Wednesday, 10 October 2012

In my previous post, I was explaining about the method of creating the thread library using context switch. In this post, I am gonna give the pseudo-code and then discuss certain issues at last.

I hope this post will give you the clear picture of the thread library :) . I don't say that this is the only way, but its one of the ways of implementing it.

The code:


//create a global queue which stores all the list of created threads...

void initialize()    //called at the starting of main function...
{
//Includes all the code like initializing the timer and attaching the signal
// handler function "schedule()" to the signal SIGPROF.

}

void schedule()      //signal handler for SIGPROF
{

in the queue.and

If it was the last thread in the queue, then execute the main function
once and then again start from the first thread in the queue and continue
this until all threads have finished their execution

*/

/*when there are no more threads in the queue... just stop the
timer and execute the main function until it completes...
*/

}

{
/*Initialize the context using getcontext(), attach a function
using makecontext() and keep this in the ready_queue*/

//If this was the first thread that is created, then start the timer....

/*important: block all the signals while adding a new thread to the queue...
and after adding it, just unblock all the signals that were previously
blocked...
*/
}

{

/* when the currently executing thread has finished its execution before
the context switch, then this function should be executed...
*/

have to block all the signals and then unblock at last..) and at last it
should call the schedule function. */

}



That's it!! we are done...!!

I was saying in my pseudo-code to block all the signals before adding or removing any thread in the queue. This was the question I posed in my previous post and here is the solution to solve the issue. I said that every process has a signal mask associated with it and it includes all the list of signals that should be blocked. We are gonna change this mask to overcome this issue.

We have to use the following function to perform the operation:

int sigprocmask(int how, const sigset_t *set, sigset_t *oset)

You may not have seen this function before, but for sure you must know the type of 2nd and 3rd arguments as we have discussed in the previous post.

This function is pretty much easy to use. You specify the signal that you want to block in the set variable using the functions that i have discussed previously. Then call this function and it blocks the desired signal. I have to say something about the first argument.

It specifies what the function has to perform exactly. It has three types of values.

SIG_BLOCK makes the function to block the additional signals specified in the set variable along with the previous ones.

SIG_UNBLOCK makes the function to unblock all the signals specified in the set variable.

If the third argument is not null, it returns the previously used mask. In this case the variable old has the previous mask.

It will be clear if i take an example. Here is the sample code to give you a clear idea about the usage of the function.


sigset_t a,b;
sigemptyset(&a);
sigaddset(&a, SIGPROF);   // i want to block SIGPROF...
//*******

//perform all the operaitons related to queue here....

//*******
//at last unblock the SIGPROF signal....
//In the above function call we are simply restoring the previous contents of signal mask... hence SIGPROF gets unblocked...



I hope much of it is clear from the comments beside it. :)

Now, I have said that the function kill_thread() must be executed when a thread gets terminated before its time slot has finished. So, how do you accomplish this. Here comes the uc_pointer to rescue. We just make every threads context's uc_pointer to point to some context which executes the kill_thread in which we remove Current_thread from the queue and then executing the schedule function. This accomplishes the task without any errors.

I hope you will get the desired results without too many segmentation errors. ;).