1*4882a593SmuzhiyunFrom 5d561e1e2dcde3c9fca4d925f12447009d0d4a4c Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= <remi@remlab.net>
3*4882a593SmuzhiyunDate: Wed, 18 Apr 2018 17:23:57 +0300
4*4882a593SmuzhiyunSubject: [PATCH] posix: remove ancient run-time fallback to real-time clock
5*4882a593SmuzhiyunMIME-Version: 1.0
6*4882a593SmuzhiyunContent-Type: text/plain; charset=UTF-8
7*4882a593SmuzhiyunContent-Transfer-Encoding: 8bit
8*4882a593Smuzhiyun
9*4882a593Smuzhiyunposix: remove ancient run-time fallback to real-time clock
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunFor hysterical raisins, GNU/Linux and possibly some other OSes still
12*4882a593Smuzhiyunreport that monotonic clock must be checked at run-time, although I
13*4882a593Smuzhiyundoubt that VLC or even current glibc would run on such old kernel.
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunDrop that to simplify and avoid the systematic one-time init check.
16*4882a593Smuzhiyun
17*4882a593SmuzhiyunDownloaded from upstream commit to fix build error on m68k:
18*4882a593Smuzhiyun
19*4882a593Smuzhiyunposix/thread.c:79:5: warning: #warning Monotonic clock not available. Expect timing issues. [-Wcpp]
20*4882a593Smuzhiyun #   warning Monotonic clock not available. Expect timing issues.
21*4882a593Smuzhiyun     ^~~~~~~
22*4882a593Smuzhiyunposix/thread.c: In function ‘vlc_clock_setup_once’:
23*4882a593Smuzhiyunposix/thread.c:88:18: error: lvalue required as left operand of assignment
24*4882a593Smuzhiyun     vlc_clock_id = (val < 0) ? CLOCK_REALTIME : CLOCK_MONOTONIC;
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunSigned-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
27*4882a593Smuzhiyun---
28*4882a593Smuzhiyun src/posix/thread.c | 96 +++++++-----------------------------------------------
29*4882a593Smuzhiyun 1 file changed, 11 insertions(+), 85 deletions(-)
30*4882a593Smuzhiyun
31*4882a593Smuzhiyundiff --git a/src/posix/thread.c b/src/posix/thread.c
32*4882a593Smuzhiyunindex dab8b71f97..8878941913 100644
33*4882a593Smuzhiyun--- a/src/posix/thread.c
34*4882a593Smuzhiyun+++ b/src/posix/thread.c
35*4882a593Smuzhiyun@@ -51,62 +51,16 @@
36*4882a593Smuzhiyun # include <sys/pset.h>
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun-#if !defined (_POSIX_TIMERS)
40*4882a593Smuzhiyun-# define _POSIX_TIMERS (-1)
41*4882a593Smuzhiyun-#endif
42*4882a593Smuzhiyun-#if !defined (_POSIX_CLOCK_SELECTION)
43*4882a593Smuzhiyun-/* Clock selection was defined in 2001 and became mandatory in 2008. */
44*4882a593Smuzhiyun-# define _POSIX_CLOCK_SELECTION (-1)
45*4882a593Smuzhiyun-#endif
46*4882a593Smuzhiyun-#if !defined (_POSIX_MONOTONIC_CLOCK)
47*4882a593Smuzhiyun-# define _POSIX_MONOTONIC_CLOCK (-1)
48*4882a593Smuzhiyun-#endif
49*4882a593Smuzhiyun-
50*4882a593Smuzhiyun-#if (_POSIX_TIMERS > 0)
51*4882a593Smuzhiyun static unsigned vlc_clock_prec;
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun-# if (_POSIX_MONOTONIC_CLOCK > 0) && (_POSIX_CLOCK_SELECTION > 0)
54*4882a593Smuzhiyun-/* Compile-time POSIX monotonic clock support */
55*4882a593Smuzhiyun-#  define vlc_clock_id (CLOCK_MONOTONIC)
56*4882a593Smuzhiyun-
57*4882a593Smuzhiyun-# elif (_POSIX_MONOTONIC_CLOCK == 0) && (_POSIX_CLOCK_SELECTION > 0)
58*4882a593Smuzhiyun-/* Run-time POSIX monotonic clock support (see clock_setup() below) */
59*4882a593Smuzhiyun-static clockid_t vlc_clock_id;
60*4882a593Smuzhiyun-
61*4882a593Smuzhiyun-# else
62*4882a593Smuzhiyun-/* No POSIX monotonic clock support */
63*4882a593Smuzhiyun-#   define vlc_clock_id (CLOCK_REALTIME)
64*4882a593Smuzhiyun-#   warning Monotonic clock not available. Expect timing issues.
65*4882a593Smuzhiyun-
66*4882a593Smuzhiyun-# endif /* _POSIX_MONOTONIC_CLOKC */
67*4882a593Smuzhiyun-
68*4882a593Smuzhiyun static void vlc_clock_setup_once (void)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun-# if (_POSIX_MONOTONIC_CLOCK == 0)
71*4882a593Smuzhiyun-    long val = sysconf (_SC_MONOTONIC_CLOCK);
72*4882a593Smuzhiyun-    assert (val != 0);
73*4882a593Smuzhiyun-    vlc_clock_id = (val < 0) ? CLOCK_REALTIME : CLOCK_MONOTONIC;
74*4882a593Smuzhiyun-# endif
75*4882a593Smuzhiyun-
76*4882a593Smuzhiyun     struct timespec res;
77*4882a593Smuzhiyun-    if (unlikely(clock_getres (vlc_clock_id, &res) != 0 || res.tv_sec != 0))
78*4882a593Smuzhiyun+    if (unlikely(clock_getres(CLOCK_MONOTONIC, &res) != 0 || res.tv_sec != 0))
79*4882a593Smuzhiyun         abort ();
80*4882a593Smuzhiyun     vlc_clock_prec = (res.tv_nsec + 500) / 1000;
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun-static pthread_once_t vlc_clock_once = PTHREAD_ONCE_INIT;
84*4882a593Smuzhiyun-
85*4882a593Smuzhiyun-# define vlc_clock_setup() \
86*4882a593Smuzhiyun-    pthread_once(&vlc_clock_once, vlc_clock_setup_once)
87*4882a593Smuzhiyun-
88*4882a593Smuzhiyun-#else /* _POSIX_TIMERS */
89*4882a593Smuzhiyun-
90*4882a593Smuzhiyun-# include <sys/time.h> /* gettimeofday() */
91*4882a593Smuzhiyun-
92*4882a593Smuzhiyun-# define vlc_clock_setup() (void)0
93*4882a593Smuzhiyun-# warning Monotonic clock not available. Expect timing issues.
94*4882a593Smuzhiyun-#endif /* _POSIX_TIMERS */
95*4882a593Smuzhiyun-
96*4882a593Smuzhiyun static struct timespec mtime_to_ts (mtime_t date)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun     lldiv_t d = lldiv (date, CLOCK_FREQ);
99*4882a593Smuzhiyun@@ -233,14 +187,11 @@ void vlc_cond_init (vlc_cond_t *p_condvar)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun     pthread_condattr_t attr;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun-    if (unlikely(pthread_condattr_init (&attr)))
104*4882a593Smuzhiyun-        abort ();
105*4882a593Smuzhiyun-#if (_POSIX_CLOCK_SELECTION > 0)
106*4882a593Smuzhiyun-    vlc_clock_setup ();
107*4882a593Smuzhiyun-    pthread_condattr_setclock (&attr, vlc_clock_id);
108*4882a593Smuzhiyun-#endif
109*4882a593Smuzhiyun-    if (unlikely(pthread_cond_init (p_condvar, &attr)))
110*4882a593Smuzhiyun+    if (unlikely(pthread_condattr_init (&attr))
111*4882a593Smuzhiyun+     || unlikely(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
112*4882a593Smuzhiyun+     || unlikely(pthread_cond_init (p_condvar, &attr)))
113*4882a593Smuzhiyun         abort ();
114*4882a593Smuzhiyun+
115*4882a593Smuzhiyun     pthread_condattr_destroy (&attr);
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun@@ -625,44 +576,27 @@ void vlc_control_cancel (int cmd, ...)
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun mtime_t mdate (void)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun-#if (_POSIX_TIMERS > 0)
123*4882a593Smuzhiyun     struct timespec ts;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun-    vlc_clock_setup ();
126*4882a593Smuzhiyun-    if (unlikely(clock_gettime (vlc_clock_id, &ts) != 0))
127*4882a593Smuzhiyun+    if (unlikely(clock_gettime(CLOCK_MONOTONIC, &ts) != 0))
128*4882a593Smuzhiyun         abort ();
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun     return (INT64_C(1000000) * ts.tv_sec) + (ts.tv_nsec / 1000);
131*4882a593Smuzhiyun-
132*4882a593Smuzhiyun-#else
133*4882a593Smuzhiyun-    struct timeval tv;
134*4882a593Smuzhiyun-
135*4882a593Smuzhiyun-    if (unlikely(gettimeofday (&tv, NULL) != 0))
136*4882a593Smuzhiyun-        abort ();
137*4882a593Smuzhiyun-    return (INT64_C(1000000) * tv.tv_sec) + tv.tv_usec;
138*4882a593Smuzhiyun-
139*4882a593Smuzhiyun-#endif
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun #undef mwait
143*4882a593Smuzhiyun void mwait (mtime_t deadline)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun-#if (_POSIX_CLOCK_SELECTION > 0)
146*4882a593Smuzhiyun-    vlc_clock_setup ();
147*4882a593Smuzhiyun+    static pthread_once_t vlc_clock_once = PTHREAD_ONCE_INIT;
148*4882a593Smuzhiyun+
149*4882a593Smuzhiyun     /* If the deadline is already elapsed, or within the clock precision,
150*4882a593Smuzhiyun      * do not even bother the system timer. */
151*4882a593Smuzhiyun+    pthread_once(&vlc_clock_once, vlc_clock_setup_once);
152*4882a593Smuzhiyun     deadline -= vlc_clock_prec;
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun     struct timespec ts = mtime_to_ts (deadline);
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun-    while (clock_nanosleep (vlc_clock_id, TIMER_ABSTIME, &ts, NULL) == EINTR);
157*4882a593Smuzhiyun-
158*4882a593Smuzhiyun-#else
159*4882a593Smuzhiyun-    deadline -= mdate ();
160*4882a593Smuzhiyun-    if (deadline > 0)
161*4882a593Smuzhiyun-        msleep (deadline);
162*4882a593Smuzhiyun-
163*4882a593Smuzhiyun-#endif
164*4882a593Smuzhiyun+    while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL) == EINTR);
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun #undef msleep
168*4882a593Smuzhiyun@@ -670,15 +604,7 @@ void msleep (mtime_t delay)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun     struct timespec ts = mtime_to_ts (delay);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun-#if (_POSIX_CLOCK_SELECTION > 0)
173*4882a593Smuzhiyun-    vlc_clock_setup ();
174*4882a593Smuzhiyun-    while (clock_nanosleep (vlc_clock_id, 0, &ts, &ts) == EINTR);
175*4882a593Smuzhiyun-
176*4882a593Smuzhiyun-#else
177*4882a593Smuzhiyun-    while (nanosleep (&ts, &ts) == -1)
178*4882a593Smuzhiyun-        assert (errno == EINTR);
179*4882a593Smuzhiyun-
180*4882a593Smuzhiyun-#endif
181*4882a593Smuzhiyun+    while (clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts) == EINTR);
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun unsigned vlc_GetCPUCount(void)
185*4882a593Smuzhiyun--
186*4882a593Smuzhiyun2.14.4
187*4882a593Smuzhiyun
188