コード例 #1
0
bool PerfSource::prepare() {
	DynBuf printb;
	DynBuf b1;
	long long schedSwitchId;
	long long cpuIdleId;

	const uint64_t currTime = getTime();

	// Reread cpuinfo since cores may have changed since startup
	gSessionData->readCpuInfo();

	if (0
			|| !mMonitor.init()
			|| !mUEvent.init()
			|| !mMonitor.add(mUEvent.getFd())

			|| (schedSwitchId = PerfDriver::getTracepointId(SCHED_SWITCH, &printb)) < 0
			|| !sendTracepointFormat(currTime, &mBuffer, SCHED_SWITCH, &printb, &b1)

			|| (cpuIdleId = PerfDriver::getTracepointId(CPU_IDLE, &printb)) < 0
			|| !sendTracepointFormat(currTime, &mBuffer, CPU_IDLE, &printb, &b1)

			// Only want RAW but not IP on sched_switch and don't want TID on SAMPLE_ID
			|| !mCountersGroup.add(currTime, &mBuffer, 100/**/, PERF_TYPE_TRACEPOINT, schedSwitchId, 1, PERF_SAMPLE_RAW, PERF_GROUP_MMAP | PERF_GROUP_COMM | PERF_GROUP_TASK | PERF_GROUP_SAMPLE_ID_ALL | PERF_GROUP_PER_CPU)
			|| !mIdleGroup.add(currTime, &mBuffer, 101/**/, PERF_TYPE_TRACEPOINT, cpuIdleId, 1, PERF_SAMPLE_RAW, PERF_GROUP_PER_CPU)

			// Only want TID and IP but not RAW on timer
			|| (gSessionData->mSampleRate > 0 && !gSessionData->mIsEBS && !mCountersGroup.add(currTime, &mBuffer, 102/**/, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, 1000000000UL / gSessionData->mSampleRate, PERF_SAMPLE_TID | PERF_SAMPLE_IP, PERF_GROUP_PER_CPU))

			|| !gSessionData->perf.enable(currTime, &mCountersGroup, &mBuffer)
			|| 0) {
		logg->logMessage("%s(%s:%i): perf setup failed, are you running Linux 3.4 or later?", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}

	for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
		const int result = mCountersGroup.prepareCPU(cpu, &mMonitor);
		if ((result != PG_SUCCESS) && (result != PG_CPU_OFFLINE)) {
			logg->logError(__FILE__, __LINE__, "PerfGroup::prepareCPU on mCountersGroup failed");
			handleException();
		}
	}
	for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
		const int result = mIdleGroup.prepareCPU(cpu, &mMonitor);
		if ((result != PG_SUCCESS) && (result != PG_CPU_OFFLINE)) {
			logg->logError(__FILE__, __LINE__, "PerfGroup::prepareCPU on mIdleGroup failed");
			handleException();
		}
	}

	int numEvents = 0;
	for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
		numEvents += mCountersGroup.onlineCPU(currTime, cpu, false, &mBuffer);
	}
	for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
		numEvents += mIdleGroup.onlineCPU(currTime, cpu, false, &mBuffer);
	}
	if (numEvents <= 0) {
		logg->logMessage("%s(%s:%i): PerfGroup::onlineCPU failed on all cores", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}

	// Send the summary right before the start so that the monotonic delta is close to the start time
	if (!gSessionData->perf.summary(&mSummary)) {
	  logg->logError(__FILE__, __LINE__, "PerfDriver::summary failed", __FUNCTION__, __FILE__, __LINE__);
	  handleException();
	}

	// Start the timer thread to used to sync perf and monotonic raw times
	pthread_t syncThread;
	if (pthread_create(&syncThread, NULL, syncFunc, NULL)) {
	  logg->logError(__FILE__, __LINE__, "pthread_create failed", __FUNCTION__, __FILE__, __LINE__);
	  handleException();
	}
	struct sched_param param;
	param.sched_priority = sched_get_priority_max(SCHED_FIFO);
	if (pthread_setschedparam(syncThread, SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
	  logg->logError(__FILE__, __LINE__, "pthread_setschedparam failed");
	  handleException();
	}

	mBuffer.commit(currTime);

	return true;
}
コード例 #2
0
ファイル: PerfSource.cpp プロジェクト: mreyna1216/gator
bool PerfSource::prepare() {
	DynBuf printb;
	DynBuf b1;
	DynBuf b2;
	DynBuf b3;
	long long schedSwitchId;

	// Reread cpuinfo since cores may have changed since startup
	gSessionData->readCpuInfo();

	if (0
			|| !mMonitor.init()
			|| !mUEvent.init()
			|| !mMonitor.add(mUEvent.getFd())

			|| (schedSwitchId = PerfDriver::getTracepointId(SCHED_SWITCH, &printb)) < 0
			|| !sendTracepointFormat(&mBuffer, SCHED_SWITCH, &printb, &b1)

			// Only want RAW but not IP on sched_switch and don't want TID on SAMPLE_ID
			|| !mCountersGroup.add(&mBuffer, 100/**/, PERF_TYPE_TRACEPOINT, schedSwitchId, 1, PERF_SAMPLE_RAW, PERF_GROUP_MMAP | PERF_GROUP_COMM | PERF_GROUP_TASK | PERF_GROUP_SAMPLE_ID_ALL | PERF_GROUP_PER_CPU)

			// Only want TID and IP but not RAW on timer
			|| (gSessionData->mSampleRate > 0 && !gSessionData->mIsEBS && !mCountersGroup.add(&mBuffer, 99/**/, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK, 1000000000UL / gSessionData->mSampleRate, PERF_SAMPLE_TID | PERF_SAMPLE_IP, PERF_GROUP_PER_CPU))

			|| !gSessionData->perf.enable(&mCountersGroup, &mBuffer)
			|| 0) {
		logg->logMessage("%s(%s:%i): perf setup failed, are you running Linux 3.4 or later?", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}

	if (!gSessionData->perf.summary(&mSummary)) {
		logg->logMessage("%s(%s:%i): PerfDriver::summary failed", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}

	{
		// Run prepareCPU in parallel as perf_event_open can take more than 1 sec in some cases
		pthread_t threads[NR_CPUS];
		PrepareParallelArgs args[NR_CPUS];
		for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
			args[cpu].pg = &mCountersGroup;
			args[cpu].cpu = cpu;
			if (pthread_create(&threads[cpu], NULL, prepareParallel, &args[cpu]) != 0) {
				logg->logMessage("%s(%s:%i): pthread_create failed", __FUNCTION__, __FILE__, __LINE__);
				return false;
			}
		}
		for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
			if (pthread_join(threads[cpu], NULL) != 0) {
				logg->logMessage("%s(%s:%i): pthread_join failed", __FUNCTION__, __FILE__, __LINE__);
				return false;
			}
		}
	}

	int numEvents = 0;
	for (int cpu = 0; cpu < gSessionData->mCores; ++cpu) {
		numEvents += mCountersGroup.onlineCPU(cpu, false, &mBuffer, &mMonitor);
	}
	if (numEvents <= 0) {
		logg->logMessage("%s(%s:%i): PerfGroup::onlineCPU failed on all cores", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}

	// Start events before reading proc to avoid race conditions
	if (!mCountersGroup.start()) {
		logg->logMessage("%s(%s:%i): PerfGroup::start failed", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}

	if (!readProc(&mBuffer, true, &printb, &b1, &b2, &b3)) {
		logg->logMessage("%s(%s:%i): readProc failed", __FUNCTION__, __FILE__, __LINE__);
		return false;
	}

	mBuffer.commit(1);

	return true;
}