ThreadSupervisor::ThreadSupervisor(int targetNumThreads): m_TargetNumThreads(targetNumThreads),m_ThreadLocalIdCounter(1) { threadSupervisor=this; //if using get specific, create the thread specific key for the thread local memory block #ifdef GETSPECIFICTHREADLOCAL //create key, abort on error if(pthread_key_create(&m_ThreadSpecificKey,NULL)) abort(); //create new thread local memory block m_LocalThreadMemory = new void*[ThreadSupervisor::s_MaxThreadLocalIdCounter]; //make really really sure it is zero memset(m_LocalThreadMemory,0,sizeof(void*)*ThreadSupervisor::s_MaxThreadLocalIdCounter); //set memory block location for main thread. Main thread doesn't do anything, so not really used. //however, there are plenty of initializations in it anyway. if(pthread_setspecific(threadSupervisor->m_ThreadSpecificKey,m_LocalThreadMemory)) abort(); #endif //if not using get specific no initialization is necessary //initialize task waiting condition if(pthread_cond_init(&m_TaskWaitingCondition,NULL)) abort(); //force everything to get done just in case there is some weird GC issue. AO_compiler_barrier(); //once everything is done initialize statics staticThreadLocalInit(); }
/* collector has been explicitly initialized. */ GC_API GC_ATTR_MALLOC void * GC_CALL GC_gcj_malloc(size_t bytes, void * ptr_to_struct_containing_descr) { if (EXPECT(GC_incremental, FALSE)) { return GC_core_gcj_malloc(bytes, ptr_to_struct_containing_descr); } else { size_t granules = ROUNDED_UP_GRANULES(bytes); void *result; void **tiny_fl = ((GC_tlfs)GC_getspecific(GC_thread_key)) -> gcj_freelists; GC_ASSERT(GC_gcj_malloc_initialized); GC_FAST_MALLOC_GRANS(result, granules, tiny_fl, DIRECT_GRANULES, GC_gcj_kind, GC_core_gcj_malloc(bytes, ptr_to_struct_containing_descr), {AO_compiler_barrier(); *(void **)result = ptr_to_struct_containing_descr;});
SupervisorThread::SupervisorThread(int localThreadId):m_KeepRunning(true),m_LocalThreadId(localThreadId) { m_ThreadLocal = new void*[ThreadSupervisor::s_MaxThreadLocalIdCounter]; AO_compiler_barrier(); }