Esempio n. 1
0
void clean_shutdown()
{
	close_results();
	close_display();
	clean_open_devices();
	clear_all_devices();
	clear_all_cpus();

	return;
}
Esempio n. 2
0
static int
do_measure_one_cpu(void *data)
{
	pfmon_thread_desc_t *arg = (pfmon_thread_desc_t *)data;
	pfmon_sdesc_t sdesc_var; /* local pfmon task descriptor */
	pfmon_sdesc_t *sdesc = &sdesc_var; 
	pfmon_ctxid_t ctxid = -1;
	pid_t mytid = gettid();
	unsigned int mycpu;
	int aggr, needs_order;
	int r, error;

	/*
	 * POSIX threads: 
	 * The signal state of the new thread is initialised as follows:
    	 *    - the signal mask is inherited from the creating thread.
         *    - the set of signals pending for the new thread is empty.
	 *
	 * we want to let the master handle the global signals, therefore
	 * we mask them here.
	 */
	setup_worker_signals();

	mycpu       = arg->cpu;
	aggr        = options.opt_aggr;

	/*
	 * some NPTL sanity checks
	 */
	if (mytid == master_tid) {
		warning("pfmon is not compiled/linked with the correct pthread library,"
			"the program is linked with NPTL when it should not."
			"Check Makefile."
			"[pid=%d:tid=%d]\n", getpid(), mytid);
		goto error;
	}

	/*
	 * we initialize our "simplified" sdesc
	 */
	memset(sdesc, 0, sizeof(*sdesc));
	/*
	 * just to make sure we have these fields initialized
	 */
	sdesc->type =  PFMON_SDESC_ATTACH;
	sdesc->tid  = mytid;
	sdesc->pid  = getpid();
	sdesc->cpu  = mycpu;
	sdesc->id   = arg->id; /* logical id */

	DPRINT(("CPU%u: pid=%d tid=%d\n", mycpu, sdesc->pid, sdesc->tid));

	pthread_setspecific(param_key, arg);

	if (options.online_cpus > 1) {

		r = pfmon_pin_self(mycpu);
		if (r == -1) {
			warning("[%d] cannot set affinity to CPU%u: %s\n", mytid, mycpu, strerror(errno));
			goto error;
		}
	}

	r = pfmon_sys_setup_context(sdesc, arg->cpu, arg->ctx);
	if (r)
		goto error;

	ctxid       = sdesc->ctxid;
	needs_order = aggr || sdesc->out_fp == stdout;

	DPRINT(("sdesc->id=%u needs_order=%d\n", sdesc->id, needs_order));

	/*
	 * indicate we have reach the starting point
	 */
	arg->thread_state = THREAD_RUN;

	if (session_state == SESSION_ABORTED)
		goto error;

	/*
	 * wait for the start signal
	 */
	pthread_barrier_wait(&barrier.barrier);

	DPRINT(("CPU%u after barrier state=%d\n", mycpu, session_state));

	if (session_state == SESSION_ABORTED) goto error;

	if (options.opt_dont_start == 0) {
		if (pfmon_start(ctxid, &error) == -1)
			goto error;
		vbprintf("CPU%u started monitoring\n", mycpu);
	} else {
		vbprintf("CPU%u pfmon does not start session\n", mycpu);
	}

	/*
	 * interval is not possible when sampling
	 */
	if (options.interval != PFMON_NO_TIMEOUT) {
		struct timespec tm;

		tm.tv_sec = options.interval / 1000;
		tm.tv_nsec = (options.interval % 1000) * 1000000;

		for(;session_state == SESSION_RUN; ) {

			nanosleep(&tm, NULL);

			/*
			 * we only check on stop to avoid printing too many messages
			 */
			if (pfmon_stop(ctxid, &error) == -1)
				warning("CPU%u could not stop monitoring, CPU may be offline, check results\n", mycpu);

			read_incremental_results(sdesc);
			show_incr_results(sdesc, needs_order);

			pfmon_start(ctxid, &error);
		}
		pthread_testcancel();
	} else {
		if (options.opt_use_smpl) {
			for(;session_state == SESSION_RUN;) {
				pfarg_msg_t msg;

				r = read(sdesc->ctxid, &msg, sizeof(msg));
				if (r ==-1) {
					/*
					 * we have been interrupted by signal (likely),
					 * go check session_state
					 */
					continue;
				}

				ovfl_cnts[mycpu]++;

				pthread_testcancel();

				if (aggr) pthread_mutex_lock(&pfmon_sys_aggr_lock);

				r = pfmon_process_smpl_buf(sdesc, 0);
				if (r)
					vbprintf("CPU%-4u error processing buffer\n", mycpu);

				if (aggr) pthread_mutex_unlock(&pfmon_sys_aggr_lock);

				pthread_testcancel();
			}
		} else {
			sigset_t myset;
			int sig;

        		sigemptyset(&myset);
        		sigaddset(&myset, SIGUSR1);
			for(;session_state == SESSION_RUN;) {
				sigwait(&myset, &sig);
			}
		}
	}

	if (pfmon_stop(ctxid, &error) == -1)
		warning("CPU%u could not stop monitoring, CPU may be offline, check results\n", mycpu);

	vbprintf("CPU%-4u stopped monitoring\n", mycpu);
	/*
	 * read the final counts
	 */
	if (options.opt_use_smpl == 0 || options.opt_smpl_print_counts) {
		if (read_results(sdesc) == -1) {
			warning("CPU%u read_results error\n", mycpu);
			goto error;
		}
	}
	DPRINT(("CPU%u has read PMDS\n", mycpu));

	/* 
	 * dump results 
	 */
	if (options.opt_aggr) {
		pthread_mutex_lock(&pfmon_sys_aggr_lock);

		syswide_aggregate_results(sdesc);

		if (options.opt_use_smpl)
			pfmon_process_smpl_buf(sdesc, 1);

		pthread_mutex_unlock(&pfmon_sys_aggr_lock);

	} else {
		if (options.opt_use_smpl)
			pfmon_process_smpl_buf(sdesc, 1);
			
		/*
		 * no final totals in interval printing mode
		 */
		if (options.interval == PFMON_NO_TIMEOUT)
			show_results(sdesc, needs_order);

		close_results(sdesc);
	}

	if (options.opt_use_smpl) {
		if (options.opt_aggr == 0)
			pfmon_close_sampling_output(sdesc, -1, mycpu);
		munmap(sdesc->csmpl.smpl_hdr, sdesc->csmpl.map_size);
	}
	close(sdesc->ctxid);

	arg->thread_state = THREAD_DONE;

	DPRINT(("CPU%u is done\n", mycpu));

	pthread_exit((void *)(0));
	/* NO RETURN */
error:
	if (sdesc->ctxid > -1)
		close(sdesc->ctxid);

	arg->thread_state = THREAD_ERROR;

	vbprintf("CPU%-4u session aborted\n", mycpu);

	if (options.opt_use_smpl) {
		if (options.opt_aggr == 0)
			pfmon_close_sampling_output(sdesc, -1, mycpu);
		munmap(sdesc->csmpl.smpl_hdr, sdesc->csmpl.map_size);
	}

	pthread_exit((void *)(~0UL));
	/* NO RETURN */
}