Compat futex
[urcu.git] / compat_futex.c
CommitLineData
49617de1
MD
1/*
2 * compat_futex.c
3 *
4 * Userspace RCU library - sys_futex compatibility code
5 *
6 * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <stdio.h>
24#include <pthread.h>
25#include <signal.h>
26#include <assert.h>
27#include <errno.h>
28#include <poll.h>
29
30#include <urcu/arch.h>
31#include <urcu/urcu-futex.h>
32
33static pthread_mutex_t compat_futex_lock = PTHREAD_MUTEX_INITIALIZER;
34static pthread_cond_t compat_futex_cond = PTHREAD_COND_INITIALIZER;
35
36/*
37 * _NOT SIGNAL-SAFE_. pthread_cond is not signal-safe anyway. Though.
38 * For now, timeout, uaddr2 and val3 are unused.
39 * Waiter will relinquish the CPU until woken up.
40 */
41
42int compat_futex_noasync(int *uaddr, int op, int val,
43 const struct timespec *timeout, int *uaddr2, int val3)
44{
45 int ret, i, gret = 0;
46
47 /*
48 * Check if NULL. Don't let users expect that they are taken into
49 * account.
50 */
51 assert(!timeout);
52 assert(!uaddr2);
53 assert(!val3);
54
55 /*
56 * memory barriers to serialize with the previous uaddr modification.
57 */
58 smp_mb();
59
60 ret = pthread_mutex_lock(&compat_futex_lock);
61 assert(!ret);
62 switch (op) {
63 case FUTEX_WAIT:
64 if (*uaddr != val)
65 goto end;
66 pthread_cond_wait(&compat_futex_cond, &compat_futex_lock);
67 break;
68 case FUTEX_WAKE:
69 for (i = 0; i < val; i++)
70 pthread_cond_signal(&compat_futex_cond);
71 break;
72 default:
73 gret = -EINVAL;
74 }
75end:
76 ret = pthread_mutex_unlock(&compat_futex_lock);
77 assert(!ret);
78 return gret;
79}
80
81/*
82 * _ASYNC SIGNAL-SAFE_.
83 * For now, timeout, uaddr2 and val3 are unused.
84 * Waiter will busy-loop trying to read the condition.
85 */
86
87int compat_futex_async(int *uaddr, int op, int val,
88 const struct timespec *timeout, int *uaddr2, int val3)
89{
90 int ret, i;
91
92 /*
93 * Check if NULL. Don't let users expect that they are taken into
94 * account.
95 */
96 assert(!timeout);
97 assert(!uaddr2);
98 assert(!val3);
99
100 /*
101 * Ensure previous memory operations on uaddr have completed.
102 */
103 smp_mb();
104
105 switch (op) {
106 case FUTEX_WAIT:
107 while (*uaddr == val)
108 poll(NULL, 0, 10);
109 break;
110 case FUTEX_WAKE:
111 break;
112 default:
113 return -EINVAL;
114 }
115}
This page took 0.035769 seconds and 4 git commands to generate.