]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/nptl/futex-internal.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / nptl / futex-internal.c
CommitLineData
323592fd 1/* futex helper functions for glibc-internal use.
2b778ceb 2 Copyright (C) 2020-2021 Free Software Foundation, Inc.
323592fd
LM
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19#include <errno.h>
20#include <sysdep.h>
21#include <time.h>
22#include <futex-internal.h>
23#include <kernel-features.h>
24
25#ifndef __ASSUME_TIME64_SYSCALLS
26static int
a2b9e1ec
AZ
27__futex_abstimed_wait_common32 (unsigned int* futex_word,
28 unsigned int expected, int op,
29 const struct __timespec64* abstime,
30 int private, bool cancel)
323592fd 31{
50e19ddf
AZ
32 struct timespec ts32, *pts32 = NULL;
33 if (abstime != NULL)
34 {
35 if (! in_time_t_range (abstime->tv_sec))
36 return -EOVERFLOW;
37
38 ts32 = valid_timespec64_to_timespec (*abstime);
39 pts32 = &ts32;
40 }
323592fd 41
a2b9e1ec
AZ
42 if (cancel)
43 return INTERNAL_SYSCALL_CANCEL (futex, futex_word, op, expected,
44 pts32, NULL /* Unused. */,
45 FUTEX_BITSET_MATCH_ANY);
46 else
47 return INTERNAL_SYSCALL_CALL (futex, futex_word, op, expected,
50e19ddf 48 pts32, NULL /* Unused. */,
323592fd
LM
49 FUTEX_BITSET_MATCH_ANY);
50}
9cb2c923 51#endif /* ! __ASSUME_TIME64_SYSCALLS */
323592fd 52
a2b9e1ec
AZ
53static int
54__futex_abstimed_wait_common64 (unsigned int* futex_word,
55 unsigned int expected, clockid_t clockid,
56 const struct __timespec64* abstime,
57 int private, bool cancel)
323592fd
LM
58{
59 unsigned int clockbit;
60 int err;
61
62 /* Work around the fact that the kernel rejects negative timeout values
63 despite them being valid. */
64 if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0)))
65 return ETIMEDOUT;
66
67 if (! lll_futex_supported_clockid (clockid))
68 return EINVAL;
69
70 clockbit = (clockid == CLOCK_REALTIME) ? FUTEX_CLOCK_REALTIME : 0;
71 int op = __lll_private_flag (FUTEX_WAIT_BITSET | clockbit, private);
72
a2b9e1ec
AZ
73 if (cancel)
74 err = INTERNAL_SYSCALL_CANCEL (futex_time64, futex_word, op, expected,
75 abstime, NULL /* Unused. */,
76 FUTEX_BITSET_MATCH_ANY);
77 else
78 err = INTERNAL_SYSCALL_CALL (futex_time64, futex_word, op, expected,
79 abstime, NULL /* Ununsed. */,
323592fd
LM
80 FUTEX_BITSET_MATCH_ANY);
81#ifndef __ASSUME_TIME64_SYSCALLS
c6a1a261 82 if (err == -ENOSYS)
a2b9e1ec
AZ
83 err = __futex_abstimed_wait_common32 (futex_word, expected, op, abstime,
84 private, cancel);
323592fd
LM
85#endif
86
87 switch (err)
88 {
89 case 0:
90 case -EAGAIN:
91 case -EINTR:
92 case -ETIMEDOUT:
a3e7aead 93 case -EINVAL:
323592fd
LM
94 case -EOVERFLOW: /* Passed absolute timeout uses 64 bit time_t type, but
95 underlying kernel does not support 64 bit time_t futex
96 syscalls. */
97 return -err;
98
99 case -EFAULT: /* Must have been caused by a glibc or application bug. */
323592fd
LM
100 case -ENOSYS: /* Must have been caused by a glibc bug. */
101 /* No other errors are documented at this time. */
102 default:
103 futex_fatal_error ();
104 }
105}
b2cdadde
LM
106
107int
108__futex_abstimed_wait64 (unsigned int* futex_word, unsigned int expected,
109 clockid_t clockid,
110 const struct __timespec64* abstime, int private)
111{
a2b9e1ec
AZ
112 return __futex_abstimed_wait_common64 (futex_word, expected, clockid,
113 abstime, private, false);
114}
cc5d5852 115libpthread_hidden_def (__futex_abstimed_wait64)
b2cdadde 116
a2b9e1ec
AZ
117int
118__futex_abstimed_wait_cancelable64 (unsigned int* futex_word,
119 unsigned int expected, clockid_t clockid,
120 const struct __timespec64* abstime,
121 int private)
122{
123 return __futex_abstimed_wait_common64 (futex_word, expected, clockid,
124 abstime, private, true);
b2cdadde 125}
cc5d5852 126libpthread_hidden_def (__futex_abstimed_wait_cancelable64)