From owner-freebsd-hackers@freebsd.org Wed Feb 22 15:19:22 2017 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 50A02CE9804 for ; Wed, 22 Feb 2017 15:19:22 +0000 (UTC) (envelope-from vangyzen@FreeBSD.org) Received: from smtp.vangyzen.net (hotblack.vangyzen.net [199.48.133.146]) by mx1.freebsd.org (Postfix) with ESMTP id 3C7D5D3B for ; Wed, 22 Feb 2017 15:19:21 +0000 (UTC) (envelope-from vangyzen@FreeBSD.org) Received: from ford.home.vangyzen.net (unknown [76.164.15.242]) by smtp.vangyzen.net (Postfix) with ESMTPSA id 60B6356483; Wed, 22 Feb 2017 09:19:15 -0600 (CST) Subject: Re: Absolute timeouts and clock adjustments To: Sebastian Huber , FreeBSD References: <58AD5802.30908@embedded-brains.de> From: Eric van Gyzen Message-ID: <1ff4d78a-a157-53c5-af7e-b516bc1b6187@FreeBSD.org> Date: Wed, 22 Feb 2017 09:19:12 -0600 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:45.0) Gecko/20100101 Thunderbird/45.6.0 MIME-Version: 1.0 In-Reply-To: <58AD5802.30908@embedded-brains.de> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit 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, 22 Feb 2017 15:19:22 -0000 On 02/22/2017 03:21, Sebastian Huber wrote: > Hello, > > I try to figure out how the timeout mechanisms work in current FreeBSD. My > interpretation (which could be completely wrong) of POSIX is something like this > should happen: > > now 2017-02-22 > sem_timedwait(s, 2023-12-13) > external entity adjusts time to 2050-01-01 > timeout of sem_timedwait() occurs due to the time adjustment This is correct. > Inside the kernel all absolute timeouts seem to use the uptime. The > sem_timedwait() seems to end up eventually in: > > /* > * Put thread into sleep state, before sleeping, check if > * thread was removed from umtx queue. > */ > static inline int > umtxq_sleep(struct umtx_q *uq, const char *wmesg, struct abs_timeout *abstime) > { > struct umtxq_chain *uc; > int error, timo; > > uc = umtxq_getchain(&uq->uq_key); > UMTXQ_LOCKED_ASSERT(uc); > for (;;) { > if (!(uq->uq_flags & UQF_UMTXQ)) > return (0); > if (abstime != NULL) { > timo = abs_timeout_gethz(abstime); > if (timo < 0) > return (ETIMEDOUT); > } else > timo = 0; > error = msleep(uq, &uc->uc_lock, PCATCH | PDROP, wmesg, timo); > if (error != EWOULDBLOCK) { > umtxq_lock(&uq->uq_key); > break; > } > if (abstime != NULL) > abs_timeout_update(abstime); > umtxq_lock(&uq->uq_key); > } > return (error); > } > > The abs_timeout_gethz() returns the interval length in ticks of [abstime->cur, > abstime->end]. Since the msleep() uses the uptime, does this mean that timeouts > trigger not immediately due to time adjustments in FreeBSD? This is also correct. The sleep will not be affected by the clock adjustment. This is contrary to POSIX. Note that CentOS 6 (Linux 3.10) behaves the same way. Fedora 24 (Linux 4.8) behaves according to POSIX. I don't know when this changed. I also don't know if it's configurable. By a curious coincidence, I'm working on adding a new sem_clockwait_np() function to FreeBSD. It allows the caller to specify the reference clock and choose between absolute and relative mode. In relative mode, the remaining time can be returned. https://reviews.freebsd.org/D9656 My changes will not make sem_timedwait() comply with POSIX, but they will let the caller use CLOCK_MONOTONIC and avoid the issue. Eric