CLOCK_MONOTONIC and sem_timedwait / pthread_mutex_timedlock
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
CLOCK_MONOTONIC and sem_timedwait / pthread_mutex_timedlock
Hi!
The use of CLOCK_MONOTONIC is somewhat limited as it's not supported AFAIK for semaphores and mutexes. I know it is supported for condition variables through pthread_condattr_setclock().
The only reference I found on this subject is a question from Ulrich Drepper to the OpenGroup about the lack of:
pthread_mutexattr_getclock()
pthread_mutexattr_setclock()
pthread_rwlockattr_getclock()
pthread_rwlockattr_setclock()
sem_getclock()
sem_setclock()
posix_trace_attr_setclock()
posix_trace_attr_getclock()
The beauty part about Open Source is that, if one toolkit happens to have one or another limitation, you can usually either:
a) modify the available source to do what you want
... or (more commonly) ...
b) find an alternate toolkit that does exactly what you need/want.
Personally, I think the standard pthreads library and "gettimeofday()" probably already does everything you actually need. But there are *lots* of alternatives out there.
Hi -
Personally, I think the standard pthreads library and "gettimeofday()" probably already does everything you actually need. But there are *lots* of alternatives out there.
Thanks for your reply!
gettimeofday uses the realtime clock, not CLOCK_MONOTONIC. This is how pthread_cond_timedwait is set up to use CLOCK_MONOTONIC:
Semaphores and mutexes also has timedwait functions (sem_timedwait()/pthread_mutex_timedlock()) but these can not as of SUSv3 be configured to use clockids other then CLOCK_REALTIME.
It is possible to work around the lack of CLOCK_MONOTONIC in some cases but it requires a POSIX timer and an unused signal number. The timer can use CLOCK_REALTIME since it will be relative only, so I *think* that system clock adjustments shouldn't affect it.
Set up a stub signal handler with sigaction() and unmask the signal using pthread_sigmask(). Then use timer_create() to create a timer which will signal the thread on expiration and call timer_settime() to start it counting down. Unlike sem_wait(), the pthread_*() functions appear never to allow a signal handler interrupt them. So, if you want to use pthread_mutex_timedlock(), emulate the mutex (unlocked state) with a semaphore initialized to 1. Now when the signal fires and returns, sem_wait() will return a non-zero value and errno will be set to EINTR. To guard against external signal sources and to ensure the timer actually expired, use a loop to check it with timer_gettime().
There is a per-process limit of POSIX timers. If I remember correctly, it was 256 on FreeBSD and 1024 on Linux last I checked. If you need that many, consider timer multiplexing or rethink your design.
EDIT:
Sorry, nevermind. There is a race condition.
I apologize for my previous misleading post and for double posting. However, it really is possible to implement my_sem_timedwait() and my_mutex_timedlock() using a monotonic clock, with restrictions.
Implement each semaphore with a mutex, condition variable, and counter. Call pthread_condattr_setclock() when initializing your emulated semaphore. There are drawbacks related to signals: my_sem_post() isn't safe to call within a signal handler, nor is my_sem_wait()/my_sem_timedwait() interruptable by signals. Finally, use an emulated semaphore to implement my_mutex_timedlock() with a monotonic clock.
These emulated semaphores are also useful on Mac OS X where unnamed semaphores just aren't implemented.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.