15 #include "selectThreadImpl.h"
17 #ifdef THREAD_SIMPLE_IMPL
19 #include "threadSimpleImpl.h"
20 #include "threadSimpleManager.h"
23 ThreadSimpleImpl *
volatile ThreadSimpleImpl::_st_this;
25 int ThreadSimpleImpl::_next_unique_id = 1;
33 ThreadSimpleImpl(
Thread *parent_obj) :
34 _parent_obj(parent_obj)
36 _unique_id = _next_unique_id;
41 _priority = TP_normal;
42 _priority_weight = 1.0;
48 _context = alloc_thread_context();
53 _manager = ThreadSimpleManager::get_global_ptr();
55 #ifdef HAVE_POSIX_THREADS
56 _posix_system_thread_id = (pthread_t)-1;
59 _win32_system_thread_id = 0;
70 if (thread_cat->is_debug()) {
72 <<
"Deleting thread " << _parent_obj->get_name() <<
"\n";
74 nassertv(_status != TS_running);
76 free_thread_context(_context);
78 if (_stack != (
void *)NULL) {
79 memory_hook->
mmap_free(_stack, _stack_size);
81 _manager->remove_thread(
this);
91 void ThreadSimpleImpl::
94 _priority = TP_normal;
95 _priority_weight = _manager->_simple_thread_normal_weight;
97 #ifdef HAVE_POSIX_THREADS
98 _posix_system_thread_id = pthread_self();
101 _win32_system_thread_id = GetCurrentThreadId();
104 _manager->set_current_thread(
this);
112 bool ThreadSimpleImpl::
113 start(ThreadPriority priority,
bool joinable) {
114 if (thread_cat->is_debug()) {
115 thread_cat.debug() <<
"Starting " << *_parent_obj <<
"\n";
118 nassertr(_status == TS_new,
false);
120 nassertr(_stack == NULL,
false);
122 if (needs_stack_prealloc) {
123 _stack = (
unsigned char *)memory_hook->
mmap_alloc(_stack_size,
true);
126 _joinable = joinable;
127 _status = TS_running;
128 _priority = priority;
132 _priority_weight = _manager->_simple_thread_low_weight;
136 _priority_weight = _manager->_simple_thread_normal_weight;
140 _priority_weight = _manager->_simple_thread_high_weight;
144 _priority_weight = _manager->_simple_thread_urgent_weight;
154 _python_state = PyThreadState_Swap(NULL);
155 PyThreadState_Swap(_python_state);
156 #endif // HAVE_PYTHON
158 init_thread_context(_context, _stack, _stack_size, st_begin_thread,
this);
160 _manager->enqueue_ready(
this,
false);
171 void ThreadSimpleImpl::
174 if (_status == TS_running) {
175 ThreadSimpleImpl *thread = _manager->get_current_thread();
176 if (thread !=
this) {
177 _joining_threads.push_back(thread);
178 _manager->next_context();
188 void ThreadSimpleImpl::
190 _manager->preempt(
this);
198 string ThreadSimpleImpl::
199 get_unique_id()
const {
202 strm << GetCurrentProcessId();
206 strm <<
"." << _unique_id;
217 void ThreadSimpleImpl::
219 ThreadSimpleManager *manager = ThreadSimpleManager::get_global_ptr();
220 manager->prepare_for_exit();
228 void ThreadSimpleImpl::
229 sleep_this(
double seconds) {
230 _manager->enqueue_sleep(
this, seconds);
231 _manager->next_context();
239 void ThreadSimpleImpl::
240 yield_this(
bool volunteer) {
241 if (thread_cat->is_debug() && volunteer) {
243 <<
"Force-yielding " << _parent_obj->get_name() <<
"\n";
245 _manager->enqueue_ready(
this,
true);
246 _manager->next_context();
255 void ThreadSimpleImpl::
256 st_begin_thread(
void *data) {
257 ThreadSimpleImpl *
self = (ThreadSimpleImpl *)data;
258 self->begin_thread();
267 void ThreadSimpleImpl::
270 PyThreadState_Swap(_python_state);
271 #endif // HAVE_PYTHON
273 #ifdef HAVE_POSIX_THREADS
274 _posix_system_thread_id = pthread_self();
277 _win32_system_thread_id = GetCurrentThreadId();
282 _parent_obj->thread_main();
285 _status = TS_finished;
288 JoiningThreads::iterator jti;
289 for (jti = _joining_threads.begin(); jti != _joining_threads.end(); ++jti) {
290 _manager->enqueue_ready(*jti,
false);
292 _joining_threads.clear();
294 _manager->enqueue_finished(
this);
295 _manager->next_context();
302 #endif // THREAD_SIMPLE_IMPL
size_t round_up_to_page_size(size_t size) const
Rounds the indicated size request up to the next larger multiple of page_size, to qualify it for a ca...
virtual void mmap_free(void *ptr, size_t size)
Frees a block of memory previously allocated via mmap_alloc().
A thread; that is, a lightweight process.
virtual void * mmap_alloc(size_t size, bool allow_exec)
Allocates a raw page or pages of memory directly from the OS.