Download presentation
Presentation is loading. Please wait.
Published byNancy Flowers Modified over 6 years ago
1
Copyright ©: Nahrstedt, Angrave, Abdelzaher, Caccamo
Timers and Clocks Copyright ©: Nahrstedt, Angrave, Abdelzaher, Caccamo
2
Example of race condition with signals
Copyright ©: Nahrstedt, Angrave, Abdelzaher Example of race condition with signals This example shows what can happen if a signal handler runs in the middle of modifying a variable. struct two_words { int a, b; } memory; void handler(int signum) { printf ("%d,%d\n", memory.a, memory.b); alarm (1); } int main (void) { static struct two_words zeros = { 0, 0 }, ones = { 1, 1 }; signal (SIGALRM, handler); memory = zeros; while (1) { memory = ones; memory = zeros; The signal function provides a simple interface for establishing an action for a particular signal. Use of this function is unspecified in a multi-threaded process (see man pages!) This program can print a pair of zeros or a pair of ones. But are we sure these are the only two cases that can happen?
3
Example of race condition with signals
Copyright ©: Nahrstedt, Angrave, Abdelzaher Example of race condition with signals On most machines, it takes several instructions to store a new value in memory, and the value is stored one word at a time. If the signal is delivered in between these instructions, the handler might find that memory.a is zero and memory.b is one (or vice versa). struct two_words { int a, b; } memory; void handler(int signum) { printf ("%d,%d\n", memory.a, memory.b); alarm (1); } int main (void) { static struct two_words zeros = { 0, 0 }, ones = { 1, 1 }; signal (SIGALRM, handler); memory = zeros; while (1) { memory = zeros; memory = ones; Note that calling printf in the handler is safe in this program because printf is never called outside the handler when the signal happens
4
POSIX signals and threads
Copyright ©: Nahrstedt, Angrave, Abdelzaher POSIX signals and threads In previous lectures, we studied POSIX signals. We assumed that each process had only one single thread of execution. We now need to understand how we can use properly POSIX signals in the presence of multi-threaded applications. We need to be cautious when using threads and signals together, since there are some new subtle rules to remember. We now describe the main aspects of it.
5
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Signals & Threads GLOBAL: Signal handler installed by sigaction is global for all the threads. GLOBAL: A signal is delivered only once to any thread (in the process) whose mask is not blocking that particular signal LOCAL: Signal mask is installed on a per thread basis. INHERITANCE: Child threads inherit the mask of parent thread by default. A thread inherits its parent’s mask; but you can change it by using: int pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask); Don’t use sigprocmask! That is for PROCESS
6
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Signals & Threads Problem: if a signal is sent to a process and more than one thread signalwait for this signal, only one of them get it and the order is random. SOLUTION When a thread is created, it inherits the signal mask of the thread that created it. So if we mask all the signals in main’s thread, no thread will receive any signal after it is created. Dedicate a thread to the purpose of catching signals by using sigwait. This thread will now be in charge of handling the signal. For sigwait to work reliably, we need to follow above solution. That is, the signals being waited for must be masked by all threads. If more than one thread sigwait for the same signal, the signal will be randomly delivered to one of them.
7
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Time.h #include <time.h> time_t time(time_t *tloc); The time() function shall return the value of time in seconds since the Epoch. The tloc argument points to an area where the return value is also stored. If tloc is a null pointer, no value is stored. Epoch: 00:00 (midnight), Jan 1, 1970 GMT time_t is usually a long UNIX “Y2K” Problem: If the long is 32 bits, when will time overflow? Implementations in which time_t is a 32-bit signed integer (many historical implementations) fail in the year 2038.
8
Timing a function (Example 1)
Copyright ©: Nahrstedt, Angrave, Abdelzaher Timing a function (Example 1) #include <stdio.h> #include <time.h> void function_to_time(void); int main(void) { time_t tstart; tstart = time(NULL); function_to_time(); printf(“function_to_time took %f seconds of elapsed time\n”, difftime(time(NULL), tstart)); return(0); }
9
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Time int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; struct tm *localtime(const time_t *timer); Takes time since epoch, returns date char *asctime(const struct tm *timeptr); 26 byte date string in ascii (ex. "Wed Jun 30 21:49: \n") char *ctime(const time_t *clock); Quiz: are these functions thread-safe?
10
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Time int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; struct tm *localtime(const time_t *timer); Takes time since epoch, returns date char *asctime(const struct tm *timeptr); 26 byte date string in ascii (ex. "Wed Jun 30 21:49: \n") char *ctime(const time_t *clock); Quiz: are these functions thread-safe? The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions. Hence these functions are NOT thread-safe.
11
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Gettimeofday() struct timeval time_t tv_sec; /* seconds since the Epoch*/ time_t tv_usec /* and microseconds*/ #include <sys/time.h> int gettimeofday(struct timeval *tv, struct timezone *tz); gives the number of seconds and microseconds since the Epoch Notice that, even though timeval supports microseconds, most operating systems would not support that high resolution since many machines run a Hz clock tick tz is null, historical
12
Measure running time using gettimeofday (Example 2)
Copyright ©: Nahrstedt, Angrave, Abdelzaher Measure running time using gettimeofday (Example 2) #include <stdio.h> #include <sys/time.h> #define MILLION L void function_to_time(void); int main(void) { long timedif; struct timeval tpend; struct timeval tpstart; gettimeofday(&tpstart, NULL)
13
Measure running time using gettimeofday
Copyright ©: Nahrstedt, Angrave, Abdelzaher Measure running time using gettimeofday function_to_time(); /* timed code goes here */ gettimeofday(&tpend, NULL) timedif = MILLION*(tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec – tpstart.tv_usec; printf(“The function_to_time took %ld microseconds\n”, timedif); return 0; }
14
Gettimeofday limitations
Copyright ©: Nahrstedt, Angrave, Abdelzaher Gettimeofday limitations Expect a resolution on the order of the clock tick of your operating system (1-10 msec) Quiz: What does happen if you have consecutive calls of gettimeofday (within few microseconds)?
15
Gettimeofday limitations
Copyright ©: Nahrstedt, Angrave, Abdelzaher Gettimeofday limitations Expect a resolution on the order of the clock tick of your operating system (1-10 msec) Quiz: What does happen if you have consecutive calls of gettimeofday (within few microseconds)? It will return the same value!
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.