void ThreadPool::shutDown() { Lock(poolLock); ThreadInfo *p; // note: do not terminate thread 0 (main thread) in this loop for (unsigned i = 1; i < nThreads; i++) { p = data[i]; // All threads should be idle when this function is called. if (p->state == ThreadInfo::Idle) { // Set the thread to the terminating state that will force thread // procedure exit p->state = ThreadInfo::Terminating; // unblock the thread p->signal(); } // wait for the thread to terminate #ifdef _WIN32 WaitForSingleObject(p->thread_id,INFINITE); #else void *value_ptr; pthread_join(p->thread_id,&value_ptr); #endif // Free thread data delete p; } // now free main thread data delete data[0]->work; delete data[0]; // main thread structure Unlock(poolLock); }
static void * Thread_Worker (void *data) /* IN */ { ThreadInfo *info = data; sigset_t set; void *ret; ASSERT (info); ASSERT (info->func); sigfillset (&set); pthread_sigmask (SIG_BLOCK, &set, NULL); #if defined(HAVE_PTHREAD_SETNAME_NP) if (info->name) { #if defined(PLATFORM_APPLE) pthread_setname_np (info->name); #elif defined(PLATFORM_LINUX) pthread_setname_np (pthread_self (), info->name); #endif } #endif ret = info->func (info->data); free (info->name); free (info); return ret; }
static void ThreadCallbackWrapper(void *context) { ThreadInfo *threadInfo = (ThreadInfo*)context; if (threadInfo) threadInfo->Runnable(threadInfo, threadInfo->Context); vTaskDelete(NULL); }
void __end_ctrace__ (CTraceStruct *c, const char *name) { if (file_to_write == 0) return; ThreadInfo *tinfo = GetThreadInfo (); tinfo->stack_end_--; if (tinfo->stack_end_ < ThreadInfo::max_stack) { if (c->start_time_ != invalid_time) { if (tinfo->stack_end_ == 0) { tinfo->UpdateCurrentTime (); c->min_end_time_ = tinfo->current_time_ + ticks; } // we should record this RecordThis (c, tinfo); if (tinfo->stack_end_ != 0) { // propagate the back's mini end time tinfo->stack_[tinfo->stack_end_ - 1]->min_end_time_ = c->min_end_time_ + ticks; tinfo->stack_[tinfo->stack_end_ - 1]->min_end_time_thread_ = c->min_end_time_thread_ + ticks; tinfo->current_time_ += ticks; tinfo->current_time_thread_ += ticks; } } } }
GeckoSampler::~GeckoSampler() { if (IsActive()) Stop(); SetActiveSampler(nullptr); // Destroy ThreadProfile for all threads { ::MutexAutoLock lock(*sRegisteredThreadsMutex); for (uint32_t i = 0; i < sRegisteredThreads->size(); i++) { ThreadInfo* info = sRegisteredThreads->at(i); ThreadProfile* profile = info->Profile(); if (profile) { delete profile; info->SetProfile(nullptr); } // We've stopped profiling. We no longer need to retain // information for an old thread. if (info->IsPendingDelete()) { delete info; sRegisteredThreads->erase(sRegisteredThreads->begin() + i); i--; } } } #if defined(XP_WIN) delete mIntelPowerGadget; #endif }
void GeckoSampler::StreamTaskTracer(SpliceableJSONWriter& aWriter) { #ifdef MOZ_TASK_TRACER aWriter.StartArrayProperty("data"); nsAutoPtr<nsTArray<nsCString>> data(mozilla::tasktracer::GetLoggedData(sStartTime)); for (uint32_t i = 0; i < data->Length(); ++i) { aWriter.StringElement((data->ElementAt(i)).get()); } aWriter.EndArray(); aWriter.StartArrayProperty("threads"); ::MutexAutoLock lock(*sRegisteredThreadsMutex); for (size_t i = 0; i < sRegisteredThreads->size(); i++) { // Thread meta data ThreadInfo* info = sRegisteredThreads->at(i); aWriter.StartObjectElement(); if (XRE_GetProcessType() == GeckoProcessType_Plugin) { // TODO Add the proper plugin name aWriter.StringProperty("name", "Plugin"); } else { aWriter.StringProperty("name", info->Name()); } aWriter.IntProperty("tid", static_cast<int>(info->ThreadId())); aWriter.EndObject(); } aWriter.EndArray(); aWriter.DoubleProperty("start", static_cast<double>(mozilla::tasktracer::GetStartTime())); #endif }
static DWORD WINAPI entry_point(void *parameter) { ThreadInfo *ti = static_cast<ThreadInfo *>(parameter); ti->entry(ti->param); delete ti; return 0; }
// AddCLVItems() // void AddCLVItems(ColumnListView* MyColumnListView) { extern int32 getShares(void *); ThreadInfo *info = new ThreadInfo(); info->SetColumnListView(MyColumnListView); info->SetHostAddress(address); thread_id shareThread = spawn_thread(getShares, "Get Shares", B_NORMAL_PRIORITY, info); resume_thread(shareThread); }
/// This is the function that happens on each thread if it is a sustained /// thread, using barriers to synchronize. void* barrierLoop( void* info ) { ThreadInfo* t = reinterpret_cast< ThreadInfo* >( info ); for ( int i = 0; i < t->numJoins(); ++i ) { barrier->wait(); busyFunc( t ); } pthread_exit( NULL ); }
static DWORD CALLBACK StarterFunc(void *ptr) { ThreadInfo *inf = (ThreadInfo*)ptr; ALint ret; ret = inf->func(inf->ptr); ExitThread((DWORD)ret); return (DWORD)ret; }
// Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, int aInterval, const char** aFeatures, uint32_t aFeatureCount) { if (!stack_key_initialized) profiler_init(); /* If the sampling interval was set using env vars, use that in preference to anything else. */ if (sUnwindInterval > 0) aInterval = sUnwindInterval; PseudoStack *stack = tlsPseudoStack.get(); if (!stack) { ASSERT(false); return; } // Reset the current state if the profiler is running profiler_stop(); TableTicker* t; if (sps_version2()) { t = new BreakpadSampler(aInterval ? aInterval : PROFILE_DEFAULT_INTERVAL, aProfileEntries ? aProfileEntries : PROFILE_DEFAULT_ENTRY, aFeatures, aFeatureCount); } else { t = new TableTicker(aInterval ? aInterval : PROFILE_DEFAULT_INTERVAL, aProfileEntries ? aProfileEntries : PROFILE_DEFAULT_ENTRY, aFeatures, aFeatureCount); } tlsTicker.set(t); t->Start(); if (t->ProfileJS()) { mozilla::MutexAutoLock lock(*Sampler::sRegisteredThreadsMutex); std::vector<ThreadInfo*> threads = t->GetRegisteredThreads(); for (uint32_t i = 0; i < threads.size(); i++) { ThreadInfo* info = threads[i]; ThreadProfile* thread_profile = info->Profile(); if (!thread_profile) { continue; } thread_profile->GetPseudoStack()->enableJSSampling(); } } sIsProfiling = true; nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(nullptr, "profiler-started", nullptr); }
// Stops a thread at the scheduler by means of @ref ThreadInfo object void Scheduler::stopThreadByInfo(const ThreadInfo& info) { if (info.getThread() == NULL) { return; } if (info.getThread()->isStopped()) return; // has been stopped info.getThread()->stop(); // join info.join(); }
void N::insertGrow(curN *n, uint64_t v, N *parentNode, uint64_t parentVersion, uint8_t keyParent, uint8_t key, N *val, bool &needRestart, ThreadInfo &threadInfo) { if (!n->isFull()) { if (parentNode != nullptr) { parentNode->readUnlockOrRestart(parentVersion, needRestart); if (needRestart) return; } n->upgradeToWriteLockOrRestart(v, needRestart); if (needRestart) return; n->insert(key, val); n->writeUnlock(); return; } parentNode->upgradeToWriteLockOrRestart(parentVersion, needRestart); if (needRestart) return; n->upgradeToWriteLockOrRestart(v, needRestart); if (needRestart) { parentNode->writeUnlock(); return; } auto nBig = new biggerN(n->getPrefix(), n->getPrefixLength()); n->copyTo(nBig); nBig->insert(key, val); N::change(parentNode, keyParent, nBig); n->writeUnlockObsolete(); threadInfo.getEpoche().markNodeForDeletion(n, threadInfo); parentNode->writeUnlock(); }
void N::removeAndShrink(curN *n, uint64_t v, N *parentNode, uint64_t parentVersion, uint8_t keyParent, uint8_t key, bool &needRestart, ThreadInfo &threadInfo) { if (!n->isUnderfull() || parentNode == nullptr) { if (parentNode != nullptr) { parentNode->readUnlockOrRestart(parentVersion, needRestart); if (needRestart) return; } n->upgradeToWriteLockOrRestart(v, needRestart); if (needRestart) return; n->remove(key); n->writeUnlock(); return; } parentNode->upgradeToWriteLockOrRestart(parentVersion, needRestart); if (needRestart) return; n->upgradeToWriteLockOrRestart(v, needRestart); if (needRestart) { parentNode->writeUnlock(); return; } auto nSmall = new smallerN(n->getPrefix(), n->getPrefixLength()); n->copyTo(nSmall); nSmall->remove(key); N::change(parentNode, keyParent, nSmall); n->writeUnlockObsolete(); threadInfo.getEpoche().markNodeForDeletion(n, threadInfo); parentNode->writeUnlock(); }
DWORD WINAPI UpdateCountdown(LPVOID _lpParamter) { ThreadInfo* Info = (ThreadInfo*)_lpParamter; LARGE_INTEGER pcFreq, currentTick; if(!QueryPerformanceFrequency(&pcFreq)) { //Todo: Insert Error Code } if(!QueryPerformanceCounter(¤tTick)) { //Todo: Insert Error Code } double startTime = double(currentTick.QuadPart) / double(pcFreq.QuadPart); //convert to milliseconds double countdown = Info->time / 1000.0; double lastTime = 0; //loop forever // or until the time is 0 or below 0 while(true) { QueryPerformanceCounter(¤tTick); double currTime = (double(currentTick.QuadPart) / double(pcFreq.QuadPart)) - startTime; countdown -= (currTime - lastTime); lastTime = currTime; //Are we ready to break? if(countdown <= 0.0) break; } //Call the function Info->function(); //Delete the memory we allocated delete Info; return 0; }
void __start_ctrace__ (void *c, const char *name) { if (file_to_write == 0) return; CTraceStruct *cs = new (c) CTraceStruct (name); ThreadInfo *tinfo = GetThreadInfo (); if (tinfo->stack_end_ == 0) { // always update the time in the first entry. // Or if it sleep too long, will make this entry looks // very time consuming. tinfo->UpdateCurrentTime (); } if (tinfo->stack_end_ < ThreadInfo::max_stack) { tinfo->stack_[tinfo->stack_end_] = cs; } tinfo->stack_end_++; }
status_t LocalDebuggerInterface::GetThreadInfo(thread_id thread, ThreadInfo& info) { thread_info threadInfo; status_t error = get_thread_info(thread, &threadInfo); if (error != B_OK) return error; info.SetTo(threadInfo.team, threadInfo.thread, threadInfo.name); return B_OK; }
status_t Team::AddThread(const ThreadInfo& threadInfo, Thread** _thread) { Thread* thread = new(std::nothrow) Thread(this, threadInfo.ThreadID()); if (thread == NULL) return B_NO_MEMORY; status_t error = thread->Init(); if (error != B_OK) { delete thread; return error; } thread->SetName(threadInfo.Name()); AddThread(thread); if (_thread != NULL) *_thread = thread; return B_OK; }
void ThreadPool::resize(unsigned n, SearchController *controller) { if (n >= 1 && n < Constants::MaxCPUs && n != nThreads) { lock(); #ifdef NUMA topo.recalc(); #endif if (n>nThreads) { // growing while (n > nThreads) { data[nThreads] = new ThreadInfo(this,nThreads); nThreads++; } } else { // shrinking while (n < nThreads) { ThreadInfo *p = data[nThreads-1]; p->state = ThreadInfo::Terminating; if (p->state == ThreadInfo::Idle) { p->signal(); // unblock thread & exit thread proc // wait for thread exit #ifdef _WIN32 WaitForSingleObject(p->thread_id,INFINITE); #else void *value_ptr; pthread_join(p->thread_id,&value_ptr); #endif } delete p; data[nThreads] = NULL; --nThreads; } } unlock(); } ASSERT(nThreads == n); availableMask = (n == 64) ? 0xffffffffffffffffULL : (1ULL << n)-1; }
void TableTicker::StreamTaskTracer(JSStreamWriter& b) { b.BeginObject(); #ifdef MOZ_TASK_TRACER b.Name("data"); b.BeginArray(); nsAutoPtr<nsTArray<nsCString>> data( mozilla::tasktracer::GetLoggedData(sStartTime)); for (uint32_t i = 0; i < data->Length(); ++i) { b.Value((data->ElementAt(i)).get()); } b.EndArray(); b.Name("threads"); b.BeginArray(); mozilla::MutexAutoLock lock(*sRegisteredThreadsMutex); for (size_t i = 0; i < sRegisteredThreads->size(); i++) { // Thread meta data ThreadInfo* info = sRegisteredThreads->at(i); b.BeginObject(); if (XRE_GetProcessType() == GeckoProcessType_Plugin) { // TODO Add the proper plugin name b.NameValue("name", "Plugin"); } else { b.NameValue("name", info->Name()); } b.NameValue("tid", static_cast<int>(info->ThreadId())); b.EndObject(); } b.EndArray(); b.NameValue("start", static_cast<double>(mozilla::tasktracer::GetStartTime())); #endif b.EndObject(); }
bool DumpWriter::WriteThread(const ThreadInfo& thread, int fatal_signal) { prstatus_t pr; memset(&pr, 0, sizeof(pr)); pr.pr_info.si_signo = fatal_signal; pr.pr_cursig = fatal_signal; pr.pr_pid = thread.Tid(); pr.pr_ppid = thread.Ppid(); pr.pr_pgrp = thread.Tgid(); memcpy(&pr.pr_reg, thread.GPRegisters(), sizeof(user_regs_struct)); Nhdr nhdr; memset(&nhdr, 0, sizeof(nhdr)); // Name size is CORE plus the NULL terminator // The format requires 4 byte alignment so the // value written in 8 bytes. Stuff the last 3 // bytes with the type of NT_PRSTATUS so it is // easier to debug in a hex editor. nhdr.n_namesz = 5; nhdr.n_descsz = sizeof(prstatus_t); nhdr.n_type = NT_PRSTATUS; if (!WriteData(&nhdr, sizeof(nhdr)) || !WriteData("CORE\0THR", 8) || !WriteData(&pr, sizeof(prstatus_t))) { return false; } #if defined(__i386__) || defined(__x86_64__) nhdr.n_descsz = sizeof(user_fpregs_struct); nhdr.n_type = NT_FPREGSET; if (!WriteData(&nhdr, sizeof(nhdr)) || !WriteData("CORE\0FLT", 8) || !WriteData(thread.FPRegisters(), sizeof(user_fpregs_struct))) { return false; } #endif #if defined(__i386__) nhdr.n_descsz = sizeof(user_fpxregs_struct); nhdr.n_type = NT_PRXFPREG; if (!WriteData(&nhdr, sizeof(nhdr)) || !WriteData("LINUX\0\0\0", 8) || !WriteData(&thread.FPXRegisters(), sizeof(user_fpxregs_struct))) { return false; } #endif return true; }
EpocheGuard(ThreadInfo<Key, Data> &threadEpocheInfo) : threadEpocheInfo(threadEpocheInfo) { threadEpocheInfo.getEpoche().enterEpoche(threadEpocheInfo); }
static void *StarterFunc(void *ptr) { ThreadInfo *inf = (ThreadInfo*)ptr; void *ret = (void*)(inf->func(inf->ptr)); return ret; }
static void *ExecuteOnThread_Dispatch(void *Arg) { ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg); TI->UserFn(TI->UserData); return 0; }
void ThreadPool::checkIn(ThreadInfo *ti) { #ifdef _THREAD_TRACE { std::ostringstream s; s << "checkIn: " << ti->index << " master=" << ti->work->split->master->index << '\0'; log(s.str()); } #endif Lock(poolLock); SplitPoint *split = ti->work->split; ThreadInfo *parent = split->master; Search *parentSearch = parent->work; // lock parent's stack Lock(parentSearch->splitLock); split->lock(); // dissociate the thread from the parent ArasanSet<ThreadInfo *,Constants::MaxCPUs> &slaves = split->slaves; // remove ti from the list of slave threads in the parent #ifdef _THREAD_TRACE { std::ostringstream s; s << "removing slave thread " << ti->index << " from master " << split->master->index << '\0'; log(s.str()); } #endif #ifdef _DEBUG ASSERT(slaves.remove(ti)); #else slaves.remove(ti); #endif const int remaining = slaves.size(); const bool top = split - parentSearch->splitStack + 1 == parentSearch->activeSplitPoints; #ifdef _THREAD_TRACE { std::ostringstream s; s << "after checkIn: " << ti->index << " remaining: " << remaining << " top=" << top << '\0'; log(s.str()); } #endif if (!remaining && top) { // all slave threads are completed, so signal parent that it // can exit its wait state and pop the split stack. ASSERT(parent); // Set parent state to Working before it even wakes up. This // ensures it will not be allocated to another split point. parent->state = ThreadInfo::Working; activeMask |= (1ULL << parent->index); #ifdef _THREAD_TRACE std::ostringstream s; s << "thread " << ti->index << " signaling parent (" << parent->index << ")" << " parent state=" << parent->state << '\0'; log(s.str()); #endif ASSERT(parent->index != ti->index); #ifdef _THREAD_TRACE log("signal",parent->index); #endif parent->signal(); } // ensure we we will wait when back in the idle loop ti->reset(); split->unlock(); Unlock(parentSearch->splitLock); Unlock(poolLock); }
struct NameDescPred { bool operator () (const ThreadInfo &a, const ThreadInfo &b) { return a.getName() > b.getName(); } };
struct IdAscPred { bool operator () (const ThreadInfo &a, const ThreadInfo &b) { return a.getID() < b.getID(); } };
// Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, double aInterval, const char** aFeatures, uint32_t aFeatureCount, const char** aThreadNameFilters, uint32_t aFilterCount) { LOG("BEGIN mozilla_sampler_start"); if (!stack_key_initialized) profiler_init(nullptr); /* If the sampling interval was set using env vars, use that in preference to anything else. */ if (sUnwindInterval > 0) aInterval = sUnwindInterval; /* If the entry count was set using env vars, use that, too: */ if (sProfileEntries > 0) aProfileEntries = sProfileEntries; // Reset the current state if the profiler is running profiler_stop(); TableTicker* t; t = new TableTicker(aInterval ? aInterval : PROFILE_DEFAULT_INTERVAL, aProfileEntries ? aProfileEntries : PROFILE_DEFAULT_ENTRY, aFeatures, aFeatureCount, aThreadNameFilters, aFilterCount); if (t->HasUnwinderThread()) { // Create the unwinder thread. ATM there is only one. uwt__init(); } tlsTicker.set(t); t->Start(); if (t->ProfileJS() || t->InPrivacyMode()) { mozilla::MutexAutoLock lock(*Sampler::sRegisteredThreadsMutex); std::vector<ThreadInfo*> threads = t->GetRegisteredThreads(); for (uint32_t i = 0; i < threads.size(); i++) { ThreadInfo* info = threads[i]; if (info->IsPendingDelete()) { continue; } ThreadProfile* thread_profile = info->Profile(); if (!thread_profile) { continue; } thread_profile->GetPseudoStack()->reinitializeOnResume(); if (t->ProfileJS()) { thread_profile->GetPseudoStack()->enableJSSampling(); } if (t->InPrivacyMode()) { thread_profile->GetPseudoStack()->mPrivacyMode = true; } } } #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) if (t->ProfileJava()) { int javaInterval = aInterval; // Java sampling doesn't accuratly keep up with 1ms sampling if (javaInterval < 10) { aInterval = 10; } mozilla::widget::android::GeckoJavaSampler::StartJavaProfiling(javaInterval, 1000); } #endif if (t->AddMainThreadIO()) { if (!sInterposeObserver) { // Lazily create IO interposer observer sInterposeObserver = new mozilla::ProfilerIOInterposeObserver(); } mozilla::IOInterposer::Register(mozilla::IOInterposeObserver::OpAll, sInterposeObserver); } sIsProfiling = true; sIsGPUProfiling = t->ProfileGPU(); if (Sampler::CanNotifyObservers()) { nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(nullptr, "profiler-started", nullptr); } LOG("END mozilla_sampler_start"); }
// Values are only honored on the first start void mozilla_sampler_start(int aProfileEntries, double aInterval, const char** aFeatures, uint32_t aFeatureCount, const char** aThreadNameFilters, uint32_t aFilterCount) { LOG("BEGIN mozilla_sampler_start"); if (!stack_key_initialized) profiler_init(nullptr); /* If the sampling interval was set using env vars, use that in preference to anything else. */ if (sUnwindInterval > 0) aInterval = sUnwindInterval; /* If the entry count was set using env vars, use that, too: */ if (sProfileEntries > 0) aProfileEntries = sProfileEntries; // Reset the current state if the profiler is running profiler_stop(); GeckoSampler* t; t = new GeckoSampler(aInterval ? aInterval : PROFILE_DEFAULT_INTERVAL, aProfileEntries ? aProfileEntries : PROFILE_DEFAULT_ENTRY, aFeatures, aFeatureCount, aThreadNameFilters, aFilterCount); tlsTicker.set(t); t->Start(); if (t->ProfileJS() || t->InPrivacyMode()) { ::MutexAutoLock lock(*Sampler::sRegisteredThreadsMutex); std::vector<ThreadInfo*> threads = t->GetRegisteredThreads(); for (uint32_t i = 0; i < threads.size(); i++) { ThreadInfo* info = threads[i]; if (info->IsPendingDelete()) { continue; } ThreadProfile* thread_profile = info->Profile(); if (!thread_profile) { continue; } thread_profile->GetPseudoStack()->reinitializeOnResume(); #ifndef SPS_STANDALONE if (t->ProfileJS()) { thread_profile->GetPseudoStack()->enableJSSampling(); } if (t->InPrivacyMode()) { thread_profile->GetPseudoStack()->mPrivacyMode = true; } #endif } } #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK) if (t->ProfileJava()) { int javaInterval = aInterval; // Java sampling doesn't accuratly keep up with 1ms sampling if (javaInterval < 10) { aInterval = 10; } mozilla::widget::GeckoJavaSampler::StartJavaProfiling(javaInterval, 1000); } #endif #ifndef SPS_STANDALONE if (t->AddMainThreadIO()) { if (!sInterposeObserver) { // Lazily create IO interposer observer sInterposeObserver = new mozilla::ProfilerIOInterposeObserver(); } mozilla::IOInterposer::Register(mozilla::IOInterposeObserver::OpAll, sInterposeObserver); } #endif sIsProfiling = true; #ifndef SPS_STANDALONE sIsGPUProfiling = t->ProfileGPU(); sIsLayersDump = t->LayersDump(); sIsDisplayListDump = t->DisplayListDump(); sIsRestyleProfiling = t->ProfileRestyle(); if (Sampler::CanNotifyObservers()) { nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) { nsTArray<nsCString> featuresArray; nsTArray<nsCString> threadNameFiltersArray; for (size_t i = 0; i < aFeatureCount; ++i) { featuresArray.AppendElement(aFeatures[i]); } for (size_t i = 0; i < aFilterCount; ++i) { threadNameFiltersArray.AppendElement(aThreadNameFilters[i]); } nsCOMPtr<nsIProfilerStartParams> params = new nsProfilerStartParams(aProfileEntries, aInterval, featuresArray, threadNameFiltersArray); os->NotifyObservers(params, "profiler-started", nullptr); } } #endif LOG("END mozilla_sampler_start"); }
struct LocationDescPred { bool operator () (const ThreadInfo &a, const ThreadInfo &b) { return a.getLocation() > b.getLocation(); } };