Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Dec 2016 13:56:00 -0700
From:      Ian Lepore <ian@freebsd.org>
To:        Goran =?iso-8859-2?Q?Meki=E6?= <meka@tilda.center>, freebsd-hackers@freebsd.org
Subject:   Re: How to use sem_timedwait?
Message-ID:  <1481748960.1889.398.camel@freebsd.org>
In-Reply-To: <20161214074228.zh6q5zya2gszw4g6@hal9000.meka.no-ip.org>
References:  <20161214074228.zh6q5zya2gszw4g6@hal9000.meka.no-ip.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1481748960.1889.398.camel>