forked from OSchip/llvm-project
Threading support: externalize sleep_for() function.
Different platforms implement the wait/sleep functions in difrerent ways. It makes sense to externalize this into the threading API. Differential revision: https://reviews.llvm.org/D29630 Reviewers: EricWF, joerg llvm-svn: 294573
This commit is contained in:
parent
9987d98370
commit
54a987e1f1
|
@ -12,6 +12,8 @@
|
||||||
#define _LIBCPP_THREADING_SUPPORT
|
#define _LIBCPP_THREADING_SUPPORT
|
||||||
|
|
||||||
#include <__config>
|
#include <__config>
|
||||||
|
#include <chrono>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
|
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
|
||||||
#pragma GCC system_header
|
#pragma GCC system_header
|
||||||
|
@ -28,8 +30,6 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <fibersapi.h>
|
#include <fibersapi.h>
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
|
#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
|
||||||
|
@ -183,6 +183,9 @@ int __libcpp_thread_detach(__libcpp_thread_t *__t);
|
||||||
_LIBCPP_THREAD_ABI_VISIBILITY
|
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||||
void __libcpp_thread_yield();
|
void __libcpp_thread_yield();
|
||||||
|
|
||||||
|
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||||
|
void __libcpp_thread_sleep_for(const chrono::nanoseconds& ns);
|
||||||
|
|
||||||
// Thread local storage
|
// Thread local storage
|
||||||
_LIBCPP_THREAD_ABI_VISIBILITY
|
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||||
int __libcpp_tls_create(__libcpp_tls_key* __key,
|
int __libcpp_tls_create(__libcpp_tls_key* __key,
|
||||||
|
@ -345,6 +348,28 @@ void __libcpp_thread_yield()
|
||||||
sched_yield();
|
sched_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
|
||||||
|
{
|
||||||
|
using namespace chrono;
|
||||||
|
seconds __s = duration_cast<seconds>(__ns);
|
||||||
|
timespec __ts;
|
||||||
|
typedef decltype(__ts.tv_sec) ts_sec;
|
||||||
|
_LIBCPP_CONSTEXPR ts_sec __ts_sec_max = numeric_limits<ts_sec>::max();
|
||||||
|
|
||||||
|
if (__s.count() < __ts_sec_max)
|
||||||
|
{
|
||||||
|
__ts.tv_sec = static_cast<ts_sec>(__s.count());
|
||||||
|
__ts.tv_nsec = static_cast<decltype(__ts.tv_nsec)>((__ns - __s).count());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
__ts.tv_sec = __ts_sec_max;
|
||||||
|
__ts.tv_nsec = 999999999; // (10^9 - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
while (nanosleep(&__ts, &__ts) == -1 && errno == EINTR);
|
||||||
|
}
|
||||||
|
|
||||||
// Thread local storage
|
// Thread local storage
|
||||||
int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
|
int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
|
||||||
{
|
{
|
||||||
|
@ -562,6 +587,14 @@ void __libcpp_thread_yield()
|
||||||
SwitchToThread();
|
SwitchToThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __libcpp_thread_sleep_for(const chrono::nanoseconds& __ns)
|
||||||
|
{
|
||||||
|
using namespace chrono;
|
||||||
|
// round-up to the nearest milisecond
|
||||||
|
milliseconds __ms = duration_cast<milliseconds>(__ns + 999999);
|
||||||
|
Sleep(__ms.count());
|
||||||
|
}
|
||||||
|
|
||||||
// Thread Local Storage
|
// Thread Local Storage
|
||||||
int __libcpp_tls_create(__libcpp_tls_key* __key,
|
int __libcpp_tls_create(__libcpp_tls_key* __key,
|
||||||
void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*))
|
void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*))
|
||||||
|
|
|
@ -114,33 +114,9 @@ namespace this_thread
|
||||||
void
|
void
|
||||||
sleep_for(const chrono::nanoseconds& ns)
|
sleep_for(const chrono::nanoseconds& ns)
|
||||||
{
|
{
|
||||||
using namespace chrono;
|
if (ns > chrono::nanoseconds::zero())
|
||||||
if (ns > nanoseconds::zero())
|
|
||||||
{
|
{
|
||||||
#if defined(_LIBCPP_WIN32API)
|
__libcpp_thread_sleep_for(ns);
|
||||||
milliseconds ms = duration_cast<milliseconds>(ns);
|
|
||||||
if (ms.count() == 0 || ns > duration_cast<nanoseconds>(ms))
|
|
||||||
++ms;
|
|
||||||
Sleep(ms.count());
|
|
||||||
#else
|
|
||||||
seconds s = duration_cast<seconds>(ns);
|
|
||||||
timespec ts;
|
|
||||||
typedef decltype(ts.tv_sec) ts_sec;
|
|
||||||
_LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max();
|
|
||||||
if (s.count() < ts_sec_max)
|
|
||||||
{
|
|
||||||
ts.tv_sec = static_cast<ts_sec>(s.count());
|
|
||||||
ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((ns-s).count());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ts.tv_sec = ts_sec_max;
|
|
||||||
ts.tv_nsec = giga::num - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (nanosleep(&ts, &ts) == -1 && errno == EINTR)
|
|
||||||
;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue