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
|
||||
|
||||
#include <__config>
|
||||
#include <chrono>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
|
||||
#pragma GCC system_header
|
||||
|
@ -28,8 +30,6 @@
|
|||
#include <Windows.h>
|
||||
#include <process.h>
|
||||
#include <fibersapi.h>
|
||||
|
||||
#include <chrono>
|
||||
#endif
|
||||
|
||||
#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
|
||||
|
@ -183,6 +183,9 @@ int __libcpp_thread_detach(__libcpp_thread_t *__t);
|
|||
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||
void __libcpp_thread_yield();
|
||||
|
||||
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||
void __libcpp_thread_sleep_for(const chrono::nanoseconds& ns);
|
||||
|
||||
// Thread local storage
|
||||
_LIBCPP_THREAD_ABI_VISIBILITY
|
||||
int __libcpp_tls_create(__libcpp_tls_key* __key,
|
||||
|
@ -345,6 +348,28 @@ void __libcpp_thread_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
|
||||
int __libcpp_tls_create(__libcpp_tls_key *__key, void (*__at_exit)(void *))
|
||||
{
|
||||
|
@ -562,6 +587,14 @@ void __libcpp_thread_yield()
|
|||
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
|
||||
int __libcpp_tls_create(__libcpp_tls_key* __key,
|
||||
void(_LIBCPP_TLS_DESTRUCTOR_CC* __at_exit)(void*))
|
||||
|
|
|
@ -114,33 +114,9 @@ namespace this_thread
|
|||
void
|
||||
sleep_for(const chrono::nanoseconds& ns)
|
||||
{
|
||||
using namespace chrono;
|
||||
if (ns > nanoseconds::zero())
|
||||
if (ns > chrono::nanoseconds::zero())
|
||||
{
|
||||
#if defined(_LIBCPP_WIN32API)
|
||||
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
|
||||
__libcpp_thread_sleep_for(ns);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue