C Program to measure the cost of a system call and context switch. In this first
ID: 3880339 • Letter: C
Question
C Program to measure the cost of a system call and context switch.
In this first project, you’ll measure the costs of a
- system call
and the cost of a
- context switch
Code in C that implements the 2 objectives of this project:
system_call.c
– measures the time it takes to do a system call.
context_switch.c
– measures the time it takes to do a context switch.
A makefile for easy compilation
Hints
Measuring the cost of a system call is relatively easy. For example, you could repeatedly
call a simple system call (e.g., performing a 0byte read), and time how long it takes;
dividing the time by the number of iterations gives you an estimate of the cost of a system call.
One thing you’ll have to take into account is the precision and accuracy of your timer. A
typical timer that you can use isgettimeofday()
; read the man page for details.
What you’ll see there is that gettimeofday() returns the time in microseconds since
1970; however, this does not mean that the timer is precise to the microsecond. Measure
back-to-back calls togettimeofday() to learn something about how precise the
timer really is; this will tell you how many iterations of your null system-call test you’ll
have to run in order to get a good measurement result. If gettimeofday()
is not precise enough for you, you might look into using the rdtsc
instruction available on x86 machines.
Measuring the cost of a context switch is a little trickier. The lmbenchbenchmark does
so by running two processes on a single CPU, and setting up two UNIX pipes between
them; a pipe is just one of many ways processes in a UNIX system can communicate with
one another. The first process then issues a write to the first pipe, and waits for a read on the second; upon seeing the first process waiting
for something to read from the second
pipe, the OS puts the first process in the blocked state, and switches to the other process,
which reads from the first pipe and then writes to the second. When the second processtries to read from the first pipe again,
it blocks, and thus the back-and-forth cycle of
communication continues. By measuring the cost of communicating like this repeatedly,lmbench
can make a good estimate of the cost of a context switch. You can try to re-create something similar here, using pipes, or perhaps some other communication
mechanism such as UNIX sockets.One difficulty in measuring context
-switch cost arises in systems with more than oneCPU. (Un?)Fortunately, the C4 lab machines are multi-processor:
run lscpuand nproc on one of the machines to see this. What you need to do on such a system is
ensure that your context-switching processes are located on the same processor.
Fortunately, most operating systems have calls to bind a process to a particular processor;
on Linux, for example, the sched_setaffinity() call is what you’re looking for.
By ensuring both processes are on the same processor, you are making sure to measure the cost of the OS stopping one
process and restoring another on the same CPU.
Explanation / Answer
uint32_t COUNTER; pthread_mutex_t LOCK; pthread_mutex_t START; pthread_cond_t CONDITION; void * threads (void * unused) { pthread_mutex_lock(&START); pthread_mutex_unlock(&START); pthread_mutex_lock(&LOCK); if (COUNTER > 0) { pthread_cond_signal(&CONDITION); } for (;;) { COUNTER++; pthread_cond_wait(&CONDITION, &LOCK); pthread_cond_signal(&CONDITION); } pthread_mutex_unlock(&LOCK); } pthread_mutex_lock(&START); COUNTER = 0; pthread_create(&t1, NULL, threads, NULL); pthread_create(&t2, NULL, threads, NULL); pthread_detach(t1); pthread_detach(t2); myTime = tTimer(); pthread_mutex_unlock(&START); sleep(1); // Lock both simulaneous threads pthread_mutex_lock(&LOCK); //Normalize the result in second precision myTime = tTimer() - myTime / 1000;
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.