mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
simple_thread_yield_sleep
This commit is contained in:
parent
92ac3b6ee8
commit
5755ae390c
@ -45,6 +45,11 @@ ThreadSimpleManager() :
|
|||||||
PRC_DESC("When SIMPLE_THREADS is defined, this defines the amount of time, "
|
PRC_DESC("When SIMPLE_THREADS is defined, this defines the amount of time, "
|
||||||
"in seconds, for which a task that voluntarily yields should "
|
"in seconds, for which a task that voluntarily yields should "
|
||||||
"be delayed.")),
|
"be delayed.")),
|
||||||
|
_simple_thread_yield_sleep
|
||||||
|
("simple-thread-yield-sleep", 0.001,
|
||||||
|
PRC_DESC("When SIMPLE_THREADS is defined, this defines the amount of time, "
|
||||||
|
"in seconds, for which the process should be put to sleep when "
|
||||||
|
"yielding the timeslice to the system.")),
|
||||||
_simple_thread_window
|
_simple_thread_window
|
||||||
("simple-thread-window", 1.0,
|
("simple-thread-window", 1.0,
|
||||||
PRC_DESC("When SIMPLE_THREADS is defined, this defines the amount of time, "
|
PRC_DESC("When SIMPLE_THREADS is defined, this defines the amount of time, "
|
||||||
@ -396,13 +401,22 @@ remove_thread(ThreadSimpleImpl *thread) {
|
|||||||
void ThreadSimpleManager::
|
void ThreadSimpleManager::
|
||||||
system_sleep(double seconds) {
|
system_sleep(double seconds) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
Sleep((int)(seconds * 1000));
|
Sleep((int)(seconds * 1000 + 0.5));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
/*
|
||||||
struct timespec rqtp;
|
struct timespec rqtp;
|
||||||
rqtp.tv_sec = time_t(seconds);
|
rqtp.tv_sec = time_t(seconds);
|
||||||
rqtp.tv_nsec = long((seconds - (double)rqtp.tv_sec) * 1000000000.0);
|
rqtp.tv_nsec = long((seconds - (double)rqtp.tv_sec) * 1000000000.0 + 0.5);
|
||||||
nanosleep(&rqtp, NULL);
|
nanosleep(&rqtp, NULL);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// We use select() as the only way that seems to actually yield the
|
||||||
|
// timeslice. sleep() and nanosleep() don't appear to do the trick.
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = time_t(seconds);
|
||||||
|
tv.tv_usec = long((seconds - (double)tv.tv_sec) * 1000000.0 + 0.5);
|
||||||
|
select(0, NULL, NULL, NULL, &tv);
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,26 +482,24 @@ write_status(ostream &out) const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void ThreadSimpleManager::
|
void ThreadSimpleManager::
|
||||||
system_yield() {
|
system_yield() {
|
||||||
|
if (!_pointers_initialized) {
|
||||||
|
// Ignore this call before we construct the global ThreadSimpleManager.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (thread_cat->is_debug()) {
|
if (thread_cat->is_debug()) {
|
||||||
thread_cat.debug()
|
thread_cat.debug()
|
||||||
<< "system_yield\n";
|
<< "system_yield\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
// There seem to be some issues with modern operating systems not
|
||||||
// 1 ms is the smallest effective time we can request on Windows;
|
// wanting to actually yield the timeslice in response to sleep(0).
|
||||||
// Sleep(0) doesn't seem to actually yield? Or at least it doesn't
|
// In particular, Windows and OSX both seemed to do nothing in that
|
||||||
// yield enough.
|
// call. Whatever. We'll force the point by explicitly sleeping
|
||||||
Sleep(1);
|
// for 1 ms in both cases. This is user-configurable in case 1 ms
|
||||||
|
// is too much (though on Windows that's all the resolution you
|
||||||
#else
|
// have).
|
||||||
// We use select() as the only way that seems to actually yield the
|
system_sleep(_global_ptr->_simple_thread_yield_sleep);
|
||||||
// timeslice. sleep() and nanosleep() don't appear to do the trick.
|
|
||||||
struct timeval tv;
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 1;
|
|
||||||
select(0, NULL, NULL, NULL, &tv);
|
|
||||||
|
|
||||||
#endif // WIN32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -628,7 +640,7 @@ choose_next_context() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No threads are ready to rull, but we're not explicitly
|
// No threads are ready to run, but we're not explicitly
|
||||||
// shutting down. This is an error condition, an
|
// shutting down. This is an error condition, an
|
||||||
// unintentional deadlock.
|
// unintentional deadlock.
|
||||||
if (!_blocked.empty()) {
|
if (!_blocked.empty()) {
|
||||||
|
@ -107,6 +107,7 @@ public:
|
|||||||
// Defined within the class to avoid static-init ordering problems.
|
// Defined within the class to avoid static-init ordering problems.
|
||||||
ConfigVariableDouble _simple_thread_epoch_timeslice;
|
ConfigVariableDouble _simple_thread_epoch_timeslice;
|
||||||
ConfigVariableDouble _simple_thread_volunteer_delay;
|
ConfigVariableDouble _simple_thread_volunteer_delay;
|
||||||
|
ConfigVariableDouble _simple_thread_yield_sleep;
|
||||||
ConfigVariableDouble _simple_thread_window;
|
ConfigVariableDouble _simple_thread_window;
|
||||||
ConfigVariableDouble _simple_thread_low_weight;
|
ConfigVariableDouble _simple_thread_low_weight;
|
||||||
ConfigVariableDouble _simple_thread_normal_weight;
|
ConfigVariableDouble _simple_thread_normal_weight;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user