2

I'm very new in C language and linux and English is not my mother language. Sorry for those in advance.

I'm working on school project which is to implement a round robin scheduler on linux and I have some problems on implementing scheduler and thread_self.

Scheduler checks if ready queue is empty first, if yes set time slice and alarm(timeslice). Otherwise, look up a new thread from ready list, dispatch TCB of new thread, set timeslice, context switch to new thread and set alarm(timeslice). But I keep getting error at some point and I couldn't find where to fix.

Another thing is about thread_cancel. int thread_cancel(thread_t tid) function removes target tcb and I need to find the tcb using tid. I tried like

Thread* temp = getpid();
kill(pid, SIGKILL);

but I couldn't figure out how to remove tcb from queue. Please give me some better idea!

Thread.h

typedef struct _Thread{
    ThreadStatus status;
    pid_t pid;
    Thread* pPrev;
    Thread* pNext;
}Thread;
Thread* ReadyQHead;
Thread* ReadyQTail;

-Queue

typedef struct _queue{
    Thread* head;
    Thread* tail;
    unsigned int num;
} queue;

queue* runList;
queue* readyList;
queue* waitList; 

-Queue.c

void enqueue(queue * q, Thread* tcb)
{
    if(q->num == 0) {
        q->head = tcb;
        q->tail = tcb;
    } else {
        q->tail->pNext = tcb;
        q->tail = tcb;
    }
    q->num ++;
}

Thread * dequeue(queue * q)
{
    Thread * tmp;
    if(q->num == 0) return NULL;
    else if(q->num == 1) {
        tmp = q->head;
        q->head = NULL;
        q->tail = NULL;
    } else {
        tmp = q->head;
        q->head = q->head->pNext;
    }
    q->num --;
    return tmp;
}

-Scheduler

void alarmHandler(int signal)
{
    printf("Scheduler awake!!");
    /*Do schedule*/
}

int RunScheduler( void )
{
    //check if ready queue is empty
    if(is_empty(readyList) != 0)
    {
        printf("this is weird");
        signal(SIGALRM, alarmHandler);
    }
    else {
        /*Look up a new thread from ready list*/
        Thread* tmp = ReadyQHead;

        /*send sigcont*/
        kill(tmp->pid, SIGCONT);

        //dispatch TCB of new thread
        if(is_empty(runList) != 0 && runList->head->status == 0)
            enqueue(readyList, tmp);

        //pick thread at head of ready list as first thread to dispatch
        tmp->status = 0; // tmp == runningTcb
        printf("alive tcb : %d\n", tmp->pid);

        ReadyQHead = dequeue(readyList);
        //set timeslice
        signal(SIGALRM, alarmHandler);
        //context switch to new thread
        _ContextSwitch(tmp->pid, ReadyQHead->pid);

    }

    while(1){
        alarm(TIMESLICE);
    }

    return 0;
}


void _ContextSwitch(int curpid, int tpid)
{
    kill(curpid, SIGSTOP);
    kill(tpid, SIGCONT);
}
user19283043
  • 327
  • 6
  • 17
  • Can you post complete program, because i need to check definition of enqueue and dequeue. – Sumit Gemini Nov 29 '16 at 12:10
  • @SumitGemini I edited! – user19283043 Nov 29 '16 at 12:18
  • Please note that calling `printf` in a signal handler is evil since `printf` is not async-signal safe. – MirkoBanchi Nov 29 '16 at 20:45
  • regarding this code: `Thread* temp = getpid(); kill(pid, SIGKILL);` a `Thread` is an instance of a struct that contains 4 fields. The function: `getpid() returns a value that has type: `pid_t` Which, is NOT a pointer and certainly not a pointer to a type: `Thread` – user3629249 Dec 01 '16 at 17:08
  • When performing a context switch, the state of the current process, IF still running, needs to be saved. then the state of the new/next process needs to be restored. Amongst other things, this means saving/restoring the current execution point, which may or may not be the entry point of the process, the system status register, and ALL the other general purpose registers. Your code is not doing that. – user3629249 Dec 01 '16 at 17:12
  • The posted code is not showing how to move a process from a waiting for I'O to a 'ready queue. The posted code is not showing how to detect when a process is 're-scheduled to run again, but the process has not yet completed the prior run – user3629249 Dec 01 '16 at 17:14
  • the posted code seems to be confused between the activities of the `scheduler` and the `dispatcher` – user3629249 Dec 01 '16 at 17:17
  • @user3629249 you pointed out exactly what I'm confused. I'm confused between the activities of the scheduler and the dispatcher. – user19283043 Dec 03 '16 at 10:55
  • The scheduler says: `process X needs to run` The dispatcher actually runs the process. – user3629249 Dec 04 '16 at 07:02

1 Answers1

0

here is an simple example of round robin

while(1)
{
    process1();
    process2();
    process3();
    process4();
    ....
    processN();
}

anything more complex, such as context switching while a process is 'sleeping' or context switching while waiting for I/O or context switching because a process needs to be run on a timed basis or due to an interrupt event adds massive complexity.

So exactly what is your goal/objective?

user3629249
  • 16,402
  • 1
  • 16
  • 17