Pth internals

The goal of this practical is to give you hand’s-on experience modifying the Pth library internals. You will need this knowledge for assignment 1. You should not attempt this prac until you have completed the previous prac, Intro to Pth.

Contents


Useful source files

  • pth_tcb.c - definition of struct pth_st
  • pth_lib.c - home of pth_spawn(), which is called to create a new thread
  • pth_sched.c - Pth scheduler, the “heart” of Pth
  • pth_pqueue.c - priority queue implementation, used by the scheduler for its thread queues

struct pth_st

The pth_st structure stores all of the information on threads. Each thread has exactly one such structure assigned to it. After building the source, you will see the structure in pth_p.h. Add an integer member to the structure (such as int foo;) and perform the following steps:

  1. make clean
  2. make

Now have a look back in pth_p.h. Where did foo go? The problem here is that the Pth source auto-generates the header file off another file - pth_tcb.c. If you wish to modify the structure, you must make the changes in the thread control block file. Try adding the foo variable into the .c file specified and rebuild the source. You should now see that it is always populated in the header file.

Question: Where can you initialise members of the thread control block structure? Initialise your integer value to 5.


Making debugging calls

Recall from the previous prac that building the Pth library with debugging enabled produces a fair amount of output on what the library is doing, and its internal state. This is very useful during development and you too can output messages of your own. To write debugging output to the screen, there are a number of printf()-style functions to help you, named pth_debug1() through to pth_debug6(). You can use them as follows:

  • pth_debug1(string) - simple string with no formatting
  • pth_debug2(format, arg1) - format string with one argument
  • pth_debug3(format, arg1, arg2) - format string with two argument
  • etc.

For instance, to print out a single argument you would use:

char *str = "hello";
    pth_debug2("Value is: %s", str);

Let's say we wanted to print out some information when a thread is created. Find the pth_spawn() function and just before it returns, print (using debugging) the following members of the thread's control block:

  • Its name
  • Its priority
  • The value of the foo member you added

Question: Which pth_debug function do you need to use for the above?

Rebuild the source and use a test program to create a new thread. You should be able to see the output of your debugging print when the program is run (hint: try grepping the output for it).


The Pth scheduler

The scheduler is responsible for coordinating and controlling which threads run next, and for dispatching signals and events to waiting threads. Threads will run for 100 ms at which time they will be preempted if they haven't already yielded.

Pth's scheduler is mostly implemented in the pth_sched.c file. By looking through this file you should see that it is responsible for picking new threads to run, and performing general housekeeping (such as moving threads between priority queues, dispatching any signals, checking for stack overflows, etc.).

Create some simple threads that loop forever and others than yield after doing some work. Examine the behaviour of the scheduler and determine what type of scheduling algorithm it implements. Does it pick threads fairly?