You will have to write several different programs using the C programming language and targeted for the Linux environment. These programs must perform the experiments described below. Of course, I expect you to reuse as much software as possible but I do expect four different executables. One each for measuring the overhead associated with performing a system call, creating a process, performing context switches and detecting memory cache boundaries (L1 and L2). For each of the three required programs, I provide an example command line (shown using the -h or help option) and summarize the required processing steps below:
Example output: wuperf> Linux/mem -h Usage: Linux/mem [-s max_stride] [-m max_mem] [-h]
Example output:
wuperf> Linux/sys -h
Linux/sys -n nsamples -s [read|write|gettime|getpid|noop] -v
## Read system call
wuperf> Linux/sys -n 1000 -s read
Measurement Results for 1000 samples, units are nsec:
Sample Mean = 756.99, Measurement Overhead = 240
Max Value = 67858, Max sample number = 103,
Min Value = 485, Min sample number = 10,
Standard Deviation = 3527.09,
Standard Error = 111.54,
StdDev as a percent of Mean (StdDev/Mean * 100) = 465.93%
## gettime
wuperf> Linux/sys -n 1000 -s gettime
Measurement Results for 1000 samples, units are nsec:
Sample Mean = 241.24, Measurement Overhead = 241
Max Value = 242, Max sample number = 4,
Min Value = 241, Min sample number = 0,
Standard Deviation = 0.43,
Standard Error = 0.01,
StdDev as a percent of Mean (StdDev/Mean * 100) = 0.18%
## getpid system call
wuperf> Linux/sys -n 1000 -s getpid
Measurement Results for 1000 samples, units are nsec:
Sample Mean = 344.58, Measurement Overhead = 241
Max Value = 353, Max sample number = 0,
Min Value = 344, Min sample number = 2,
Standard Deviation = 0.56,
Standard Error = 0.02,
StdDev as a percent of Mean (StdDev/Mean * 100) = 0.16%
wuperf> Linux/create -h Linux/create -t [unbound|bound|fork|exec] -n nsamples [-v]
...
if ((pid = fork ()) < 0) {
printf("Error doing a fork!\n");
exit (0);
} else if (pid == 0) {
if (Mode == Exec) {
execl ("./simple", 0);
_exit (0); // don't flush all standard IO buffers
} else {
// read results from child over pipe
wait(0);
}
...
Example code for creating threads:
/* struct used to pass environment information to threads */
struct Env { ... };
/* Passed to pthread_create -- this is called when thread is created */
void *do_main (void *x);
void *
do_main (void *x)
{
struct Env *env = (struct Env *)x;
...
pthread_exit(0);
return 0;
}
int main (...)
{
pthread_t tid[2];
pthread_attr_t attr;
struct Env env;
...
/* attr is used to set thread specific attributes. */
pthread_attr_init(&attr);
if (Test == BoundThread)
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
else if (Test == UnBoundThread)
pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS);
else {
...
}
...
/* create threads, then the thread is created it will start
* execution at the start of the function pointer passed in as an
* aregument, do_main in this example. The function will be passed
* the argument env when it is invoked
*/
if (pthread_create(&tid[0], &attr, do_main, &env) != 0) {
printf("Error creating thread 0 ... exiting\n");
exit(1);
}
...
}
ebony:wuperf> Linux/ctx -h
Linux/ctx [-s style] [-t tes] [-n nsamples] [-v] [-l loops]
-h : print this help message
-t test: select one of {unbound, bound, process}
unbound - context switch between user space threads (same process)
bound - context switch between threads bound to kernel threads (same process)
process - context switch time between two different processes
-n n: the number of samples to collect
-l n: the number of tests that comprise one sample
-v: turn on verbose mode
-s style: select one of {sema, pipe}
sema - use semaphores. For process place in shared memory segment
pipe - use UNIX domain pipes.
-w w - Window size used for calculating the histogram data
Include a command line option to specify the number of samples.
You are to force a context switch by sending a byte (or word) between two threads/processing using a UNIX pipe(2). If you prefer you can use two semaphore(3T)s. To use a pipe, first create the pipe using the pipe(2) system call, then use read(2) and write(2).
When submitting your assignment include documentation describing your benchmarks, behavior you expected, behavior you observed (or measured) and a description of the experiment goals (why you chose the particular mechanisms you used). When you turn in your assignment it should include: