How to use sem_timedwait?
Ian Lepore
ian at freebsd.org
Wed Dec 14 20:56:08 UTC 2016
On Wed, 2016-12-14 at 08:42 +0100, Goran Mekić wrote:
> Hello,
>
> I'm trying to understand how sem_timedwait() works. For that I
> assambled a little program:
>
> #include <stdio.h>
> #include <sys/types.h>
> #include <semaphore.h>
> #include <errno.h>
> #include <time.h>
>
>
> int main() {
> sem_t semaphore;
> struct timespec ts;
> clock_gettime(CLOCK_REALTIME, &ts);
> ts.tv_sec += 3;
>
> sem_init(&semaphore, 0, 0);
> int result = sem_timedwait(&semaphore, &ts);
> int error = errno;
>
> printf("The sem_timedwait() should have ended at %lds and %ldns\n",
> ts.tv_sec, ts.tv_nsec);
> clock_gettime(CLOCK_REALTIME, &ts);
> printf("The sem_timedwait() exited at %lds and %ldns with %d
> status\n", ts.tv_sec, ts.tv_nsec, result);
>
> clock_getres(CLOCK_REALTIME, &ts);
> printf("Clock resolution is %lds and %ldns\n", ts.tv_sec,
> ts.tv_nsec);
>
> if (result == -1) {
> switch (error) {
> case EINVAL:
> printf("The semaphore does not refer to valid structure\n");
> break;
> case ETIMEDOUT:
> printf("Timeout occured\n");
> break;
> case EINTR:
> printf("Interupted\n");
> break;
> default:
> printf("Unknown error\n");
> break;
> }
> }
> }
>
>
> Running it I get the following output:
>
> The sem_timedwait() should have ended at 1481700752s and 2050646ns
> The sem_timedwait() exited at 1481700752s and 3813780ns with -1
> status
> Clock resolution is 0s and 1ns
> Timeout occured
>
>
> What I want to know is why the number of nanoseconds reported first
> and second time is not the same if the resolution reported on line 3
> is 1ns? It doesn't change much if I use CLOCK_RELATIME_PRECISE. Thank
> you!
>
> Regards,
> meka
One of the things you did with that code is measured how much time it
took to format and print the "It should have ended..." line. If you
want to capture how long you were asleep you need the clock_gettime()
to be the next thing you call after sem_timedwait(). Even the time to
access errno may be non-trivial if it's actually a thread-local
variable.
If you want to get better sleep-timing performance (at the expense of
less power-saving efficiency), try setting
sysctl kern.timecounter.alloweddeviation=0
That will prevent the aggregation of timeouts scheduled near each other
to all happen at the same time, resulting in more wakeups, each of
which is more accurate (more wakeups = more power used).
-- Ian
More information about the freebsd-hackers
mailing list