From owner-freebsd-hackers@freebsd.org Wed Dec 14 20:56:08 2016 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9ECABC77925 for ; Wed, 14 Dec 2016 20:56:08 +0000 (UTC) (envelope-from ian@freebsd.org) Received: from outbound1b.ore.mailhop.org (outbound1b.ore.mailhop.org [54.200.247.200]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 81EEB1EE5 for ; Wed, 14 Dec 2016 20:56:08 +0000 (UTC) (envelope-from ian@freebsd.org) X-MHO-User: c07e089e-c23f-11e6-9f67-d3961ed5a660 X-Report-Abuse-To: https://support.duocircle.com/support/solutions/articles/5000540958-duocircle-standard-smtp-abuse-information X-Originating-IP: 73.78.92.27 X-Mail-Handler: DuoCircle Outbound SMTP Received: from ilsoft.org (unknown [73.78.92.27]) by outbound1.ore.mailhop.org (Halon) with ESMTPSA id c07e089e-c23f-11e6-9f67-d3961ed5a660; Wed, 14 Dec 2016 20:56:15 +0000 (UTC) Received: from rev (rev [172.22.42.240]) by ilsoft.org (8.15.2/8.15.2) with ESMTP id uBEKu0Ec004438; Wed, 14 Dec 2016 13:56:00 -0700 (MST) (envelope-from ian@freebsd.org) Message-ID: <1481748960.1889.398.camel@freebsd.org> Subject: Re: How to use sem_timedwait? From: Ian Lepore To: Goran =?iso-8859-2?Q?Meki=E6?= , freebsd-hackers@freebsd.org Date: Wed, 14 Dec 2016 13:56:00 -0700 In-Reply-To: <20161214074228.zh6q5zya2gszw4g6@hal9000.meka.no-ip.org> References: <20161214074228.zh6q5zya2gszw4g6@hal9000.meka.no-ip.org> Content-Type: text/plain; charset="iso-8859-2" X-Mailer: Evolution 3.18.5.1 FreeBSD GNOME Team Port Mime-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 14 Dec 2016 20:56:08 -0000 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 > #include > #include > #include > #include > > > 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