wierd scheduler linked-list stuff [solved]

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
GLneo

wierd scheduler linked-list stuff [solved]

Post by GLneo »

hi all!, ok, my problem is I have switched my scheduler from an array with tasks on it to a linked-list with tasks on it, this doesn't work, the first time the swither gets called and pushes all regs(the first time is switches these should be kernel regs) it stores them in the first task(kernel task)and switches, but it doesn't find the next task(select(); finds the next task with a READY state and sets it as RUNNING_PROCESS) but this fails, it looks like it got intrupted(becouse different emulators get more or less far?)even though i do CLI();? with is another ? i have: when i do get it to crash i get a error with should print the regs then stop the system, but the reg ESP moves!!!!!!!!!! the ONLY way this could happen is if it is being intrupted then crashing with a different ESP over and over so it looks like continueus movement(ESP gest smaller each time), bit i locked the system????how is that possible????
heres the code for the scheduler and process creator: "process.c":

Code: Select all

#include <los/process.h>

#include <los/memory.h>
#include <los/scheduler.h>

extern int get_pri_time(int pri);

unsigned int PID_count = 0;

struct task_data *make_task(char *name, void (*entry)(), int ring)
{
    struct task_data *new_process;
    void *stack_mem;
    struct stack_data *stack;
    new_process = (struct task_data *)malloc(sizeof(struct task_data));
    if(new_process == NULL)
        return NULL;
    new_process->PID = PID_count++;
    new_process->P_PID = NULL;
    new_process->time = get_pri_time(1);
    new_process->priority = 1;
    
    stack_mem = (unsigned int *)malloc(STACK_SIZE);
    stack_mem += STACK_SIZE - sizeof(struct stack_data);
    stack = stack_mem;
    if(ring == 0)
    {
        stack->gs = KERNEL_DATA_SEG;
        stack->fs = KERNEL_DATA_SEG;
        stack->es = KERNEL_DATA_SEG;
        stack->ds = KERNEL_DATA_SEG;
        stack->cs = KERNEL_CODE_SEG;
    }
    else
    {
        stack->gs = USER_DATA_SEG;
        stack->fs = USER_DATA_SEG;
        stack->es = USER_DATA_SEG;
        stack->ds = USER_DATA_SEG;
        stack->cs = USER_CODE_SEG;
    }    
    stack->edi = 0;
    stack->esi = 0;
    stack->esp = (unsigned int)stack;
    stack->ebp = stack->esp;
    stack->ebx = 0;
    stack->edx = 0;
    stack->ecx = 0;
    stack->eax = 0;
    stack->eip = (unsigned int)entry;
    stack->eflags = 0x00000202;
    
    strncpy(new_process->name, name, 32);
    new_process->stack = stack;
    new_process->ss = KERNEL_STACK_SEG;
    new_process->state = CREATED;
    
    return new_process;
}
"process.h":

Code: Select all

#ifndef __SCHEDULER_H
#define __SCHEDULER_H

#include <los/syslib.h>
#include <los/text.h>
#include <los/scheduler.h>
#include <los/memory.h>

#define STACK_SIZE        64*4
#define KERNEL_CODE_SEG   0x0008
#define KERNEL_STACK_SEG  0x0010
#define KERNEL_DATA_SEG   0x0010
#define USER_CODE_SEG     0x0018
#define USER_STACK_SEG    0x0020
#define USER_DATA_SEG     0x0020

#endif
the rest is too long to post so i'll attach it ;)
GLneo

Re:wierd scheduler linked-list stuff

Post by GLneo »

cant attach here it is:

Code: Select all

#include <los/scheduler.h>

#include <los/syslib.h>
#include <los/memory.h>
#include <los/clock.h>
#include <los/text.h>
#include <los/process.h>
#include <asm/main_asm.h>

extern struct task_data *make_task(char *name, void (*entry)(), int ring);

int front = 0;
int end = 0;
struct task_data * HEAD = NULL;
struct task_data * RUNNING_PROCESS = NULL;
struct tss TSS;

void task0()
{
    while(1)
    {
        delay(1000);
        puts("a");
    }
}

void task1()
{
    while(1)
    {
        delay(1000);
        puts("b");
    }
}

int is_empty()
{
    if(RUNNING_PROCESS == NULL)
        return 1;
    return 0;
}

int cur_task_time()
{
    if(is_empty())
        return 0;
    return RUNNING_PROCESS -> time;
}

int cur_task_pri()
{
    if(is_empty())
        return 0;
    return RUNNING_PROCESS -> priority;
}

void select()
{
    if(RUNNING_PROCESS->state == RUNNING)
    {
        RUNNING_PROCESS->state = READY;
        printf("Setting %s state to READY\n", RUNNING_PROCESS->name);
    }    
    while(1)
    {
        RUNNING_PROCESS = RUNNING_PROCESS->prev;
        printf("Cheaking %s state\n", RUNNING_PROCESS->name);
        if(RUNNING_PROCESS->state == READY || RUNNING_PROCESS->state == CREATED)
         break;
    }
    printf("Found %s\n", RUNNING_PROCESS->name);
    RUNNING_PROCESS->state = RUNNING;
}

void dec_cur_task_time()
{
    if(is_empty())
        return;
    RUNNING_PROCESS -> time--;
}

void cur_task_time_equ(int time)
{
    if(is_empty())
        return;
    RUNNING_PROCESS -> time = time;
}

int get_pri_time(int pri)
{
    switch(pri)
    {
        case 0:
            return 100;
            break;
        case 1:
            return 10;
            break;
        case 2:
            return 5;
            break;
        case 3:
            return 2;
            break;
        case 4:
            return 1;
            break;
        default:
            return 0;
     }
}

struct stack_data *schedule(struct stack_data *regs)
{
    cur_task_time_equ(get_pri_time(cur_task_pri()));
    RUNNING_PROCESS -> stack = regs;
    select();
    return RUNNING_PROCESS -> stack;
//    TSS.esp0 = (int);
//    (stack_data_t *)TSS.esp0;
}

struct stack_data *task_timer_c(struct stack_data *regs)
{
    clock();
//    (void)inport(0x60);
    outport(0x20, 0x20);
    if(cur_task_time() > 0)
    {
        dec_cur_task_time();
        return regs;
    }
    else
        return schedule(regs);
}

void fill_tss()
{
    TSS.ss0 = 0x10;
    TSS.bitmap = 0xFFFF;
}

void add_process(struct task_data *process)
{
    process->prev = HEAD;
    HEAD = process;
    if(RUNNING_PROCESS == NULL)
        RUNNING_PROCESS = process;
    printf("Adding new task to list %s with:\nPID: %i \nP_PID: %i\ntime: %i\npriority: %i\n state: %i\n", process->name, process->PID, process->P_PID, process->time, process->priority, process->state);
}

int remove_process(struct task_data *process)
{
    struct task_data *temp;
    if(process == NULL)
      return 1;
    if(process->PID == KERNEL_PID)
      return 1;
   if(process == HEAD)
   {
      HEAD = process->prev;
      return 0;
   }
   else
   {
      for(temp = HEAD; temp != NULL; temp = temp->prev)
      {
         if(temp->prev == process)
         {
            temp->prev = process->prev;
            return 0;
         }
      }
   }
   return 1;
}

void start_sys()
{
    add_process(make_task("NOT_DOING_NOTHIN'_TASK", task0, 0));
    add_process(make_task("task0", task0, 0));
    add_process(make_task("task1", task1, 0));
//    fill_tss(); // fill the struct
//    setup_tss(); // put pointer to GDT entery in cpu
    set_a_idt(32, (unsigned)task_timer, 0x08, 0x8E); // redirect timer
}
GLneo

Re:wierd scheduler linked-list stuff

Post by GLneo »

and the header:

Code: Select all

#ifndef __PROCESS_H
#define __PROCESS_H

#include <los/syslib.h>
#include <los/clock.h>
#include <los/text.h>

#define CREATED 0
#define READY 1
#define RUNNING 2
#define BLOCKED 3
#define TERMINATED 4
#define KERNEL_PID 0

struct stack_data
{
   unsigned int gs;
   unsigned int fs;
   unsigned int es;
   unsigned int ds;
   unsigned int edi;
   unsigned int esi;
   unsigned int ebp;
   unsigned int esp;
   unsigned int ebx;
   unsigned int edx;
   unsigned int ecx;
   unsigned int eax;
   unsigned int eip;
   unsigned int cs;
   unsigned int eflags;
};

struct tss
{
    short backlink, __blh;
    int esp0;
    short ss0, __ss0h;
    int esp1;
    short ss1, __ss1h;
    int esp2;
    short ss2, __ss2h;
    int cr3;
    int eip;
    int eflags;
    int eax, ecx, edx, ebx;
    int esp, ebp, esi, edi;
    short es, __esh;
    short cs, __csh;
    short ss, __ssh;
    short ds, __dsh;
    short fs, __fsh;
    short gs, __gsh;
    short ldt, __ldth;
    short trace, bitmap;
}__attribute__((packed));

struct task_data 
{
    char name[33];
    struct stack_data *stack;
    unsigned int ss;
    unsigned int kstack;
    unsigned int ustack;
    unsigned int PID;
    unsigned int P_PID;
    unsigned int time;
    unsigned int priority;
    unsigned int state;
    struct task_data *prev;
};

/* sched.c */
extern void tester_asm();
extern void test();
extern void start_sys();
extern int is_empty();
extern int cur_task_time();
extern int cur_task_pri();
extern void front_to_end();
extern void dec_cur_task_time();
extern void cur_task_time_equ(int time);
extern int get_pri_time(int pri);
extern struct stack_data *schedule(struct stack_data *regs);
extern struct stack_data *task_timer_c(struct stack_data *regs);
extern void task_timer();
extern int remove_process(struct task_data *process);
extern void add_process(struct task_data *process);
extern int get_pri_time(int pri);

#endif
dc0d32

Re:wierd scheduler linked-list stuff

Post by dc0d32 »

i had a similar problem

at each task switch, print SS0:ESP0 and SS:ESP of all tasks/threads. it will give u a clearer picture.
GLneo

Re:wierd scheduler linked-list stuff

Post by GLneo »

i fixed it!!!!!!!!!!!!! it wasn't the ss:esp, the tasks wern't like properaly, but thx much for reply!
Post Reply