fix git conflict
[c11tester.git] / futex.cc
1 // futex -*- C++ -*-
2
3 // Copyright (C) 2015-2019 Free Software Foundation, Inc.
4 //
5 // This is a reimplementation of libstdc++-v3/src/c++11/futex.cc.
6
7 #include <bits/atomic_futex.h>
8 #ifdef _GLIBCXX_HAS_GTHREADS
9 #if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
10 #include <chrono>
11 #include <climits>
12 #include <syscall.h>
13 #include <unistd.h>
14 #include <sys/time.h>
15 #include <errno.h>
16 #include <debug/debug.h>
17
18 #include "model.h"
19 #include "execution.h"
20 #include "mutex.h"
21 #include <condition_variable>
22
23 // Constants for the wait/wake futex syscall operations
24 const unsigned futex_wait_op = 0;
25 const unsigned futex_wake_op = 1;
26
27 namespace std _GLIBCXX_VISIBILITY(default)
28 {
29         _GLIBCXX_BEGIN_NAMESPACE_VERSION
30
31         bool
32         __atomic_futex_unsigned_base::_M_futex_wait_until(unsigned *__addr,
33                                                                                                                                                                                                                 unsigned __val,
34                                                                                                                                                                                                                 bool __has_timeout, chrono::seconds __s, chrono::nanoseconds __ns)
35         {
36                 // do nothing if the two values are not equal
37                 if ( *__addr != __val ) {
38                         return true;
39                 }
40
41                 // if a timeout is specified, return immedialy. Letting the scheduler decide how long this thread will wait.
42                 if (__has_timeout) {
43                         return true;
44                 }
45
46                 ModelExecution *execution = model->get_execution();
47
48                 cdsc::snapcondition_variable *v = new cdsc::snapcondition_variable();
49                 cdsc::snapmutex *m = new cdsc::snapmutex();
50
51                 execution->getCondMap()->put( (pthread_cond_t *) __addr, v);
52                 execution->getMutexMap()->put( (pthread_mutex_t *) __addr, m);
53
54                 v->wait(*m);
55                 return true;
56         }
57
58         void
59         __atomic_futex_unsigned_base::_M_futex_notify_all(unsigned* __addr)
60         {
61                 // INT_MAX wakes all the waiters at the address __addr
62                 ModelExecution *execution = model->get_execution();
63                 cdsc::condition_variable *v = execution->getCondMap()->get( (pthread_cond_t *) __addr);
64                 v->notify_all();
65         }
66
67         _GLIBCXX_END_NAMESPACE_VERSION
68 }
69 #endif  // defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
70 #endif  // _GLIBCXX_HAS_GTHREADS