Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
static void ThreadCallbackWrapper(void *context)
{
    ThreadInfo *threadInfo = (ThreadInfo*)context;
    if (threadInfo)
    threadInfo->Runnable(threadInfo, threadInfo->Context);
    vTaskDelete(NULL);
}
Пример #4
0
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;
            }
        }
    }
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
static DWORD WINAPI entry_point(void *parameter)
{
	ThreadInfo *ti = static_cast<ThreadInfo *>(parameter);
	ti->entry(ti->param);
	delete ti;
	return 0;
}
Пример #8
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);
		}
Пример #9
0
/// 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 );
}
Пример #10
0
static DWORD CALLBACK StarterFunc(void *ptr)
{
    ThreadInfo *inf = (ThreadInfo*)ptr;
    ALint ret;

    ret = inf->func(inf->ptr);
    ExitThread((DWORD)ret);

    return (DWORD)ret;
}
Пример #11
0
// 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);
}
Пример #12
0
// 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();
}
Пример #13
0
    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();
    }
Пример #14
0
    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();
    }
Пример #15
0
DWORD WINAPI UpdateCountdown(LPVOID _lpParamter)
{
	ThreadInfo* Info = (ThreadInfo*)_lpParamter;
	LARGE_INTEGER pcFreq, currentTick;

	if(!QueryPerformanceFrequency(&pcFreq))
	{	
		//Todo: Insert Error Code
	}

	if(!QueryPerformanceCounter(&currentTick))
	{	
		//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(&currentTick);
		
		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;
}
Пример #16
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_++;
}
Пример #17
0
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;
}
Пример #18
0
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;
}
Пример #19
0
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;
}
Пример #20
0
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();
}
Пример #21
0
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;
}
Пример #22
0
 EpocheGuard(ThreadInfo<Key, Data> &threadEpocheInfo) : threadEpocheInfo(threadEpocheInfo) {
     threadEpocheInfo.getEpoche().enterEpoche(threadEpocheInfo);
 }
Пример #23
0
static void *StarterFunc(void *ptr)
{
    ThreadInfo *inf = (ThreadInfo*)ptr;
    void *ret = (void*)(inf->func(inf->ptr));
    return ret;
}
Пример #24
0
static void *ExecuteOnThread_Dispatch(void *Arg) {
  ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg);
  TI->UserFn(TI->UserData);
  return 0;
}
Пример #25
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);
}
Пример #26
0
struct NameDescPred { bool operator () (const ThreadInfo &a, const ThreadInfo &b) {
	return a.getName() > b.getName();
} };
Пример #27
0
struct IdAscPred { bool operator () (const ThreadInfo &a, const ThreadInfo &b) {
	return a.getID() < b.getID();
} };
Пример #28
0
// 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");
}
Пример #29
0
// 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");
}
Пример #30
0
struct LocationDescPred { bool operator () (const ThreadInfo &a, const ThreadInfo &b) {
	return a.getLocation() > b.getLocation();
} };