void	SStopWatch::MarkInternal(Root* root)
{
	FlushICache();

	root->suspendTime = 0;

	if ((root->extensions&EXTENSION_PERFORMANCE) != 0) {
		IOSFastIoctl(CounterFD(), PERFCNT_READ_COUNTERS(NUM_COUNTERS+1),
					0, NULL, sizeof(m_node->counters), m_node->counters, &root->perfError);
	}

#if TARGET_PLATFORM == TARGET_PLATFORM_PALMSIM_WIN32
	if ((root->extensions&EXTENSION_QUANTIFY_RUNNING) != 0) {
		QuantifyStopRecordingData();
	}
	if ((root->flags&B_STOP_WATCH_QUANTIFY) != 0) {
		QuantifyStartRecordingData();
		root->extensions |= EXTENSION_QUANTIFY_RUNNING;
	}
#endif

	if ((root->flags&B_STOP_WATCH_NO_TIME) == 0) {
		m_node->time = KALGetTime(B_TIMEBASE_RUN_TIME);
	}

#if TARGET_PLATFORM == TARGET_PLATFORM_DEVICE_ARM
	if ((root->extensions&EXTENSION_PERFORMANCE_HIGH) != 0) {
		m_node->counters[0] = ReadPerformanceCounter(0);
		m_node->counters[1] = ReadPerformanceCounter(1);
		m_node->counters[2] = ReadPerformanceCounter(2);
	}
#endif
}
SPerformanceSample::SPerformanceSample()
{
	SStopWatch::FlushICache();
#if TARGET_PLATFORM == TARGET_PLATFORM_DEVICE_ARM
	m_counters[0] = ReadPerformanceCounter(0);
	m_counters[1] = ReadPerformanceCounter(1);
	m_counters[2] = ReadPerformanceCounter(2);
#endif
}
SPerformanceSample::~SPerformanceSample()
{
#if TARGET_PLATFORM == TARGET_PLATFORM_DEVICE_ARM
	uint32_t cur[3];
	cur[0] = ReadPerformanceCounter(0);
	cur[1] = ReadPerformanceCounter(1);
	cur[2] = ReadPerformanceCounter(2);
	printf("%lu %lu %lu\n", cur[0]-m_counters[0], cur[1]-m_counters[1], cur[2]-m_counters[2]);
#endif
}
void	SStopWatch::RestartInternal(Root* root)
{
	if (m_type != TYPE_CHILD) {
		if ((root->extensions&(EXTENSION_PERFORMANCE|EXTENSION_PERFORMANCE_HIGH)) != 0) {
			IOSFastIoctl(CounterFD(), PERFCNT_CONFIGURE_COUNTERS(NUM_COUNTERS),
						sizeof(root->perfCounters), root->perfCounters, 0, NULL, &root->perfError);
			//if (root->perfError != B_OK) root->extensions &= ~EXTENSION_PERFORMANCE;
		}
		if ((root->extensions&EXTENSION_PROFILING) != 0) {
			// Stopping returns an error code if already stopped, so ignore this result.
			IOSFastIoctl(ProfileFD(), profilerStopProfiling, 0, NULL, 0, NULL, &root->profError);
			root->profError = B_OK;

			if ((root->profFlags&B_PROFILE_KEEP_SAMPLES) == 0) {
				IOSFastIoctl(ProfileFD(), profilerResetSamples, 0, NULL, 0, NULL, &root->perfError);
			}
			if (root->profError == B_OK) {
				IOSFastIoctl(ProfileFD(), profilerStartProfiling, 0, NULL, 0, NULL, &root->perfError);
			}
			if (root->profError != B_OK) root->extensions &= ~EXTENSION_PROFILING;
		}

		if ((root->flags&B_STOP_WATCH_CLEAR_CACHE) != 0) {
			// A "big" size says to just blindly flush the whole cache.
			FlushICache();
		}

		// Compute overhead -- baseline
		if ((root->flags&B_STOP_WATCH_NO_TIME) == 0) {
			root->timeOverhead = KALGetTime(B_TIMEBASE_RUN_TIME);
		}
		if ((root->extensions&EXTENSION_PERFORMANCE) != 0) {
			memset(root->counterOverhead, 0, sizeof(root->counterOverhead));
			IOSFastIoctl(CounterFD(), PERFCNT_READ_COUNTERS(NUM_COUNTERS+1),
						0, NULL, sizeof(root->counterOverhead), root->counterOverhead, &root->perfError);
		}
#if TARGET_PLATFORM == TARGET_PLATFORM_DEVICE_ARM
		if ((root->extensions&EXTENSION_PERFORMANCE_HIGH) != 0) {
			root->counterOverhead[0] = ReadPerformanceCounter(0);
			root->counterOverhead[1] = ReadPerformanceCounter(1);
			root->counterOverhead[2] = ReadPerformanceCounter(2);
		}
#endif

		// Some internal stuff we always have to do
		if ((root->flags&B_STOP_WATCH_NESTING) != 0) {
			Root* foo = CurrentRoot();
		}

		// Compute overhead -- total up measurement overhead
		if ((root->flags&B_STOP_WATCH_NO_TIME) == 0) {
			root->timeOverhead = KALGetTime(B_TIMEBASE_RUN_TIME)-root->timeOverhead;
		}
		if ((root->extensions&EXTENSION_PERFORMANCE) != 0) {
			status_t err;
			IOSFastIoctl(CounterFD(), PERFCNT_READ_COUNTERS(NUM_COUNTERS+1), 0, NULL, sizeof(root->tmpPerf), root->tmpPerf, &err);
			for (int i=0; i<NUM_COUNTERS+1; i++) {
				root->counterOverhead[i] = root->tmpPerf[i] - root->counterOverhead[i];
			}
		}
#if TARGET_PLATFORM == TARGET_PLATFORM_DEVICE_ARM
		if ((root->extensions&EXTENSION_PERFORMANCE_HIGH) != 0) {
			root->tmpPerf[0] = ReadPerformanceCounter(0);
			root->tmpPerf[1] = ReadPerformanceCounter(1);
			root->tmpPerf[2] = ReadPerformanceCounter(2);
			for (int i=0; i<NUM_COUNTERS+1; i++) {
				root->counterOverhead[i] = root->tmpPerf[i] - root->counterOverhead[i];
			}
		}
#endif
	}
}
void SStopWatch::StopInternal(Root* root)
{
#if TARGET_PLATFORM == TARGET_PLATFORM_DEVICE_ARM
	if ((root->extensions&EXTENSION_PERFORMANCE_HIGH) != 0) {
		root->tmpPerf[0] = ReadPerformanceCounter(0);
		root->tmpPerf[1] = ReadPerformanceCounter(1);
		root->tmpPerf[2] = ReadPerformanceCounter(2);
	}
#endif

	Node* const node = m_node;

	if ((root->flags&B_STOP_WATCH_NO_TIME) == 0) {
		node->time = ElapsedTime();
	}

#if TARGET_PLATFORM == TARGET_PLATFORM_PALMSIM_WIN32
	if ((root->extensions&EXTENSION_QUANTIFY_RUNNING) != 0) {
		QuantifyStopRecordingData();
	}
#endif

	if ((root->extensions&EXTENSION_PERFORMANCE) != 0) {
		status_t err;
		IOSFastIoctl(CounterFD(), PERFCNT_READ_COUNTERS(NUM_COUNTERS+1),
						0, NULL, sizeof(root->tmpPerf), root->tmpPerf, &err);
	}

	if ((root->extensions&(EXTENSION_PERFORMANCE|EXTENSION_PERFORMANCE_HIGH)) != 0) {
		for (int i=0; i<NUM_COUNTERS+1; i++) {
			if (root->tmpPerf[i] <= node->counters[i])
				node->counters[i] = (root->tmpPerf[i]+0x10000)-node->counters[i];
			else
				node->counters[i] = root->tmpPerf[i]-node->counters[i];
		}
	}

	if (m_type == TYPE_CHILD) {
		root->currentNode = m_parent;
		return;
	}

	if ((root->extensions&EXTENSION_PROFILING) != 0) {
		status_t err;
		IOSFastIoctl(ProfileFD(), profilerStopProfiling, 0, NULL, 0, NULL, &err);
	}

	if ((root->flags&B_STOP_WATCH_HIGH_PRIORITY) != 0) {
		KALThreadChangePriority((KeyID)SysCurrentThread(), root->origPriority);
	}

	if ((root->flags&B_STOP_WATCH_SILENT) == 0) {
		root->PrintReport(bout);
	}

	if ((root->extensions&EXTENSION_PROFILING) != 0
			&& (root->profFlags&B_PROFILE_UPLOAD_SAMPLES) != 0) {
		status_t err;
		IOSFastIoctl(ProfileFD(), profilerSendSamplesToPOD, 0, NULL, 0, NULL, &err);
	}

	SetCurrentRoot(NULL);
	root->extensions |= EXTENSION_STOPPED;
}
Example #6
0
void RestartPerfCntrs(PerfObj *PerfCntrs)
{
  DWORD returnLength = 0;  //Lint
  DWORD returnNumCPUs;  //Lint
  DWORD i;
  
  DWORD status;
  SYSTEM_INFO SystemInfo;

  GetSystemInfo(&SystemInfo);
  
  // Move previous data from EndInfo to StartInfo.
  CopyMemory((PCHAR)&PerfCntrs->StartInfo[0],
	     (PCHAR)&PerfCntrs->EndInfo[0],
	     sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*(MAXCPUS +1));
  
  PerfCntrs->StartTime = PerfCntrs->EndTime;
  
  // get the current CPUTIME information
  if ( (status = NtQuerySystemInformation( SystemProcessorPerformanceInformation,
					   (PCHAR)&PerfCntrs->EndInfo[0], sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*MAXCPUS,
					   &returnLength )) != 0) 
    {
      fprintf(stderr, "NtQuery failed, status: %X\n", status);
      exit(1);
    }
  
  PerfCntrs->EndTime = ReadPerformanceCounter();
  
  // Validate that NtQuery returned a reasonable amount of data
  if ((returnLength % sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)) != 0)
    {
      fprintf(stderr, "NtQuery didn't return expected amount of data\n");
      fprintf(stderr, "Expected a multiple of %i, returned %i\n",
	      sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), returnLength);
      exit(1);
    }
  returnNumCPUs = returnLength / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); 
  
  if (returnNumCPUs != (int)SystemInfo.dwNumberOfProcessors)
    {
      fprintf(stderr, "NtQuery didn't return expected amount of data\n");
      fprintf(stderr, "Expected data for %i CPUs, returned %i\n",
	      (int)SystemInfo.dwNumberOfProcessors, returnNumCPUs);
      exit(1);
    }
  
  // Zero entries not returned by NtQuery
  ZeroMemory((PCHAR)&PerfCntrs->EndInfo[returnNumCPUs],
	     sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)*
	     (MAXCPUS +1 - returnNumCPUs));
  
  // Total all of the CPUs
  //      KernelTime needs to be fixed-up; it includes both idle &
  // true kernel time 
  //  Note that kernel time also includes DpcTime & InterruptTime, but
  // I like this. 
  for (i=0; i < returnNumCPUs; i++)
    {
      PerfCntrs->EndInfo[i].KernelTime.QuadPart         -= PerfCntrs->EndInfo[i].IdleTime.QuadPart;
      PerfCntrs->EndInfo[MAXCPUS].IdleTime.QuadPart     += PerfCntrs->EndInfo[i].IdleTime.QuadPart;
      PerfCntrs->EndInfo[MAXCPUS].KernelTime.QuadPart   += PerfCntrs->EndInfo[i].KernelTime.QuadPart;
      PerfCntrs->EndInfo[MAXCPUS].UserTime.QuadPart     += PerfCntrs->EndInfo[i].UserTime.QuadPart;
      PerfCntrs->EndInfo[MAXCPUS].DpcTime.QuadPart      += PerfCntrs->EndInfo[i].DpcTime.QuadPart;
      PerfCntrs->EndInfo[MAXCPUS].InterruptTime.QuadPart += PerfCntrs->EndInfo[i].InterruptTime.QuadPart;
      PerfCntrs->EndInfo[MAXCPUS].InterruptCount                += PerfCntrs->EndInfo[i].InterruptCount;
    }
  
}   /* RestartPerfCntrs */