17 #ifdef THREAD_POSIX_IMPL
28 static JavaVM *java_vm =
nullptr;
31 pthread_key_t ThreadPosixImpl::_pt_ptr_index = 0;
32 bool ThreadPosixImpl::_got_pt_ptr_index =
false;
39 if (thread_cat->is_debug()) {
41 <<
"Deleting thread " << _parent_obj->get_name() <<
"\n";
47 pthread_detach(_thread);
58 void ThreadPosixImpl::
61 _thread = pthread_self();
67 bool ThreadPosixImpl::
68 start(ThreadPriority priority,
bool joinable) {
70 if (thread_cat->is_debug()) {
71 thread_cat.debug() <<
"Starting " << *_parent_obj <<
"\n";
74 nassertd(_status == S_new) {
80 _status = S_start_called;
83 if (!_got_pt_ptr_index) {
88 pthread_attr_init(&attr);
91 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
95 int result = pthread_attr_setstacksize(&attr, thread_stack_size);
98 <<
"Unable to set stack size.\n";
103 result = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
105 thread_cat->warning()
106 <<
"Unable to set system scope.\n";
109 struct sched_param param;
110 int current_policy = SCHED_OTHER;
111 result = pthread_attr_setschedpolicy(&attr, current_policy);
113 thread_cat->warning()
114 <<
"Unable to set scheduling policy.\n";
121 param.sched_priority = sched_get_priority_min(current_policy);
122 result = pthread_attr_setschedparam(&attr, ¶m);
127 param.sched_priority = sched_get_priority_max(current_policy);
128 result = pthread_attr_setschedparam(&attr, ¶m);
137 thread_cat->warning()
138 <<
"Unable to specify thread priority.\n";
144 result = pthread_create(&_thread, &attr, &root_func, (
void *)
this);
146 pthread_attr_destroy(&attr);
165 void ThreadPosixImpl::
171 pthread_join(_thread, &return_val);
181 std::string ThreadPosixImpl::
182 get_unique_id()
const {
183 std::ostringstream strm;
184 strm << getpid() <<
"." << (uintptr_t)_thread;
194 bool ThreadPosixImpl::
197 std::string thread_name = _parent_obj->get_name();
198 JavaVMAttachArgs args;
199 args.version = JNI_VERSION_1_2;
200 args.name = thread_name.c_str();
201 args.group =
nullptr;
202 if (java_vm->AttachCurrentThread(&env, &args) != 0) {
204 <<
"Failed to attach Java VM to thread "
205 << _parent_obj->get_name() <<
"!\n";
217 void ThreadPosixImpl::
220 nassertv(thread !=
nullptr);
225 if (java_vm->GetEnv((
void **)&env, JNI_VERSION_1_4) == JNI_OK) {
226 nassertv(thread->_impl._jni_env ==
nullptr || thread->_impl._jni_env == env);
227 thread->_impl._jni_env = env;
230 <<
"Called bind_java_thread() on thread "
231 << *thread <<
", which is not attached to Java VM!\n";
239 void *ThreadPosixImpl::
240 root_func(
void *data) {
241 TAU_REGISTER_THREAD();
245 ThreadPosixImpl *
self = (ThreadPosixImpl *)data;
246 int result = pthread_setspecific(_pt_ptr_index, self->_parent_obj);
247 nassertr(result == 0,
nullptr);
251 nassertd(self->_status == S_start_called) {
252 self->_mutex.unlock();
256 self->_status = S_running;
257 self->_mutex.unlock();
262 self->attach_java_vm();
265 self->_parent_obj->thread_main();
267 if (thread_cat->is_debug()) {
269 <<
"Terminating thread " <<
self->_parent_obj->get_name()
270 <<
", count = " <<
self->_parent_obj->get_ref_count() <<
"\n";
275 nassertd(self->_status == S_running) {
276 self->_mutex.unlock();
279 self->_status = S_finished;
280 self->_mutex.unlock();
285 if (self->_jni_env !=
nullptr) {
286 java_vm->DetachCurrentThread();
287 self->_jni_env =
nullptr;
304 void ThreadPosixImpl::
305 init_pt_ptr_index() {
306 nassertv(!_got_pt_ptr_index);
308 int result = pthread_key_create(&_pt_ptr_index,
nullptr);
311 <<
"Unable to associate Thread pointers with threads.\n";
315 _got_pt_ptr_index =
true;
320 result = pthread_setspecific(_pt_ptr_index, main_thread_obj);
321 nassertv(result == 0);
328 jint JNI_OnLoad(JavaVM *jvm,
void *reserved) {
332 ThreadPosixImpl::bind_java_thread();
333 return JNI_VERSION_1_4;
337 #endif // THREAD_POSIX_IMPL