From 31c401a5ccee4a821e4d77f5c1f1883b1aac70e3 Mon Sep 17 00:00:00 2001 From: weiyu Date: Tue, 28 May 2019 16:56:49 -0700 Subject: [PATCH] implement futex.cc --- futex.cc | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 futex.cc diff --git a/futex.cc b/futex.cc new file mode 100644 index 00000000..64ec6b4a --- /dev/null +++ b/futex.cc @@ -0,0 +1,70 @@ +// futex -*- C++ -*- + +// Copyright (C) 2015-2019 Free Software Foundation, Inc. +// +// This is a reimplementation of libstdc++-v3/src/c++11/futex.cc. + +#include +#ifdef _GLIBCXX_HAS_GTHREADS +#if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1 +#include +#include +#include +#include +#include +#include +#include + +#include "model.h" +#include "execution.h" +#include "mutex.h" +#include + +// Constants for the wait/wake futex syscall operations +const unsigned futex_wait_op = 0; +const unsigned futex_wake_op = 1; + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + bool + __atomic_futex_unsigned_base::_M_futex_wait_until(unsigned *__addr, + unsigned __val, + bool __has_timeout, chrono::seconds __s, chrono::nanoseconds __ns) + { + // do nothing if the two values are not equal + if ( *__addr != __val ) { + return true; + } + + // if a timeout is specified, return immedialy. Letting the scheduler decide how long this thread will wait. + if (__has_timeout) { + return true; + } + + ModelExecution *execution = model->get_execution(); + + cdsc::condition_variable *v = new cdsc::condition_variable(); + cdsc::mutex *m = new cdsc::mutex(); + + execution->cond_map.put( (pthread_cond_t *) __addr, v); + execution->mutex_map.put( (pthread_mutex_t *) __addr, m); + + v->wait(*m); + return true; + } + + void + __atomic_futex_unsigned_base::_M_futex_notify_all(unsigned* __addr) + { + // INT_MAX wakes all the waiters at the address __addr + ModelExecution *execution = model->get_execution(); + cdsc::condition_variable *v = execution->cond_map.get( (pthread_cond_t *) __addr); + v->notify_all(); + } + +_GLIBCXX_END_NAMESPACE_VERSION +} +#endif // defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1 +#endif // _GLIBCXX_HAS_GTHREADS -- 2.34.1