VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/posix/semwait.h@ 92781

Last change on this file since 92781 was 92781, checked in by vboxsync, 3 years ago

IPRT/posix/semwait.h: Build fix. bugref:10138

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.1 KB
Line 
1/* $Id: semwait.h 92781 2021-12-07 10:31:02Z vboxsync $ */
2/** @file
3 * IPRT - Common semaphore wait code.
4 */
5
6/*
7 * Copyright (C) 2021 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27#ifndef IPRT_INCLUDED_SRC_r3_posix_semwait_h
28#define IPRT_INCLUDED_SRC_r3_posix_semwait_h
29#ifndef RT_WITHOUT_PRAGMA_ONCE
30# pragma once
31#endif
32
33
34/** @def IPRT_HAVE_PTHREAD_CONDATTR_SETCLOCK
35 * Set if the platform implements pthread_condattr_setclock().
36 * Enables the use of the monotonic clock for waiting on condition variables. */
37#ifndef IPRT_HAVE_PTHREAD_CONDATTR_SETCLOCK
38/* Linux detection */
39# if defined(RT_OS_LINUX) && defined(__USE_XOPEN2K)
40# include <features.h>
41# if __GLIBC_PREREQ(2,6) /** @todo figure the exact version where this was added */
42# define IPRT_HAVE_PTHREAD_CONDATTR_SETCLOCK
43# endif
44# endif
45/** @todo check other platforms */
46#endif
47
48
49/**
50 * Converts a extended wait timeout specification to an absolute timespec and a
51 * relative nanosecond count.
52 *
53 * @note This does not check for RTSEMWAIT_FLAGS_INDEFINITE, caller should've
54 * done that already.
55 *
56 * @returns The relative wait in nanoseconds. 0 for a poll call, UINT64_MAX for
57 * an effectively indefinite wait.
58 * @param fFlags RTSEMWAIT_FLAGS_XXX.
59 * @param fMonotonicClock Whether the timeout is in monotonic (true) or real
60 * (false) time.
61 * @param uTimeout The timeout.
62 * @param pAbsDeadline Where to return the absolute deadline.
63 */
64DECLINLINE(uint64_t) rtSemPosixCalcDeadline(uint32_t fFlags, uint64_t uTimeout, bool fMonotonicClock,
65 struct timespec *pAbsDeadline)
66{
67 Assert(!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE));
68
69 /*
70 * Convert uTimeout to a relative value in nanoseconds.
71 */
72 if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
73 {
74 if (uTimeout < UINT64_MAX / RT_NS_1MS)
75 uTimeout = uTimeout * RT_NS_1MS;
76 else
77 return UINT64_MAX;
78 }
79 else if (uTimeout == UINT64_MAX) /* unofficial way of indicating an indefinite wait */
80 return UINT64_MAX;
81
82 /*
83 * Make uTimeout relative and check for polling (zero timeout) calls.
84 */
85 uint64_t uAbsTimeout = uTimeout;
86 if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
87 {
88 uint64_t const u64Now = RTTimeSystemNanoTS();
89 if (uTimeout > u64Now)
90 uTimeout -= u64Now;
91 else
92 return 0;
93 }
94 else if (uTimeout == 0)
95 return 0;
96
97 /*
98 * Calculate the deadline according to the clock we're using.
99 */
100 if (!fMonotonicClock)
101 {
102#if defined(RT_OS_DARWIN) || defined(RT_OS_HAIKU)
103 struct timeval tv = {0,0};
104 gettimeofday(&tv, NULL);
105 pAbsDeadline->tv_sec = tv.tv_sec;
106 pAbsDeadline->tv_nsec = tv.tv_usec * 1000;
107#else
108 clock_gettime(CLOCK_REALTIME, pAbsDeadline);
109#endif
110 struct timespec TsAdd;
111 TsAdd.tv_nsec = uTimeout % RT_NS_1SEC;
112 TsAdd.tv_sec = uTimeout / RT_NS_1SEC;
113
114 /* Check for 32-bit tv_sec overflows: */
115 if ( sizeof(pAbsDeadline->tv_sec) < sizeof(uint64_t)
116 && ( uTimeout >= (uint64_t)RT_NS_1SEC * UINT32_MAX
117 || (uint64_t)pAbsDeadline->tv_sec + pAbsDeadline->tv_sec >= UINT32_MAX) )
118 return UINT64_MAX;
119
120 pAbsDeadline->tv_sec += TsAdd.tv_sec;
121 pAbsDeadline->tv_nsec += TsAdd.tv_nsec;
122 if ((uint32_t)pAbsDeadline->tv_nsec >= RT_NS_1SEC)
123 {
124 pAbsDeadline->tv_nsec -= RT_NS_1SEC;
125 pAbsDeadline->tv_sec++;
126 }
127 }
128 else
129 {
130 /* ASSUMES RTTimeSystemNanoTS() == RTTimeNanoTS() == clock_gettime(CLOCK_MONOTONIC). */
131 if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
132 {
133 uint64_t const nsNow = RTTimeSystemNanoTS();
134 uAbsTimeout += nsNow;
135 if (uAbsTimeout < nsNow)
136 return UINT64_MAX;
137 }
138
139 /* Check for 32-bit tv_sec overflows: */
140 if ( sizeof(pAbsDeadline->tv_sec) < sizeof(uint64_t)
141 && uAbsTimeout >= (uint64_t)RT_NS_1SEC * UINT32_MAX)
142 return UINT64_MAX;
143
144 pAbsDeadline->tv_nsec = uAbsTimeout % RT_NS_1SEC;
145 pAbsDeadline->tv_sec = uAbsTimeout / RT_NS_1SEC;
146 }
147
148 return uTimeout;
149}
150
151#endif /* !IPRT_INCLUDED_SRC_r3_posix_semwait_h */
152
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette