Writing a scheduler for a Userspace thread library

I am developing a userspace premptive thread library(fibre) that uses context switching as the base approach. For this I wrote a scheduler. However, its not performing as expected. Can I have any suggestions for this. The structure of the thread_t used is :

typedef struct thread_t {
    int thr_id;
    int thr_usrpri;
    int thr_cpupri;
    int thr_totalcpu;
    ucontext_t thr_context;
    void * thr_stack;
    int thr_stacksize;
    struct thread_t *thr_next;
    struct thread_t *thr_prev;
} thread_t;

The scheduling function is as follows:

void schedule(void)
{
        thread_t *t1, *t2;
    thread_t * newthr = NULL;
    int newpri = 127;
    struct itimerval tm;
    ucontext_t dummy;
    sigset_t sigt;


    t1 = ready_q;

    // Select the thread with higest priority
    while (t1 != NULL)
    {
        if (newpri > t1->thr_usrpri + t1->thr_cpupri)
        {
            newpri = t1->thr_usrpri + t1->thr_cpupri;
            newthr = t1;
        }

        t1 = t1->thr_next;
    }

    if (newthr == NULL)
    {
        if (current_thread == NULL)
        {
            // No more threads? (stop itimer)
            tm.it_interval.tv_usec = 0;
            tm.it_interval.tv_sec = 0;
            tm.it_value.tv_usec = 0; // ZERO Disable
            tm.it_value.tv_sec = 0;
            setitimer(ITIMER_PROF, &tm, NULL);
        }
        return;
    }
    else
    {
        // TO DO :: Reenabling of signals must be done.
        // Switch to new thread
        if (current_thread != NULL)
        {
            t2 = current_thread;
            current_thread = newthr;
            timeq = 0;
            sigemptyset(&sigt);
            sigaddset(&sigt, SIGPROF);
            sigprocmask(SIG_UNBLOCK, &sigt, NULL);
            swapcontext(&(t2->thr_context), &(current_thread->thr_context));
        }
        else 
        {
            // No current thread? might be terminated
            current_thread = newthr;
            timeq = 0;
            sigemptyset(&sigt);
            sigaddset(&sigt, SIGPROF);
            sigprocmask(SIG_UNBLOCK, &sigt, NULL);
            swapcontext(&(dummy), &(current_thread->thr_context));
        }
    }
}

Answers


It seems that the "ready_q" (head of the list of ready threads?) never changes, so the search of the higest priority thread always finds the first suitable element. If two threads have the same priority, only the first one has a chance to gain the CPU. There are many algorithms you can use, some are based on a dynamic change of the priority, other ones use a sort of rotation inside the ready queue. In your example you could remove the selected thread from its place in the ready queue and put in at the last place (it's a double linked list, so the operation is trivial and quite inexpensive). Also, I'd suggest you to consider the performace issues due to the linear search in ready_q, since it may be a problem when the number of threads is big. In that case it may be helpful a more sophisticated structure, with different lists of threads for different levels of priority. Bye!


Need Your Help

passing a shells output to a perl script log

perl shell logging

what this script does is pull down a list of usernames and passowrds and hashes it and then adds it to

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.