Hi,
I am attaching the code.
Thank you very much. 
Tanima.



________________________________
From: Corey J Ashford <cjash...@us.ibm.com>
To: Tanima Dey <dey_tr...@yahoo.com>
Cc: Corey Ashford <cjash...@linux.vnet.ibm.com>; Perfmon 
<perfmon2-devel@lists.sourceforge.net>
Sent: Saturday, July 18, 2009 10:26:11 PM
Subject: Re: [perfmon2] About per-thread monitoring


Can you post the code where you are doing the fork/exec of the app, and 
following ptrace call?  Maybe we can spot the problem easier that way, because 
I'm a little confused about the terminology "appThread".  If appThread is a 
pthread id, that would be the reason that ptrace is not working...  it takes 
task ids, rather than pthread ids.

- Corey

Tanima Dey <dey_tr...@yahoo.com> wrote on 07/18/2009 03:55:02 PM:

> Tanima Dey <dey_tr...@yahoo.com> 
> 07/18/2009 03:55 PM
> 
> To
> 
> Corey Ashford <cjash...@linux.vnet.ibm.com>
> 
> cc
> 
> Perfmon <perfmon2-devel@lists.sourceforge.net>
> 
> Subject
> 
> Re: [perfmon2] About per-thread monitoring
> 
> Hi,
> Yes, I have studied that example, and wrote similar code, but for 
> the appThread. But it shows me the same error message for ptrace() 
> while attaching the task. I have given the appThread ID instead of 
> the process ID, and it shows the message:
> 
> "cannot attach to threadID, operation is not permitted"
> 
> Can you help?
> Thanks
> Tanima.
> 
> From: Corey Ashford <cjash...@linux.vnet.ibm.com>
> To: Tanima Dey <dey_tr...@yahoo.com>
> Cc: Perfmon <perfmon2-devel@lists.sourceforge.net>
> Sent: Friday, July 17, 2009 6:20:09 PM
> Subject: Re: [perfmon2] About per-thread monitoring
> 
> On 07/16/2009 04:33 PM, Tanima Dey wrote:
> >
> > Hi,
> >
> > Thanks for the reply.
> >
> > It is mentioned in the manual that the thread to which the context is
> > attached is the monitored thread, in my case then it is the application
> > thread to which the context should be loaded, right? If it is so, I am
> > initializing and loading the context in the appThread, and trying to
> > read the counters value in the monitor thread. So I have used ptrace()
> > to stop the appThread in the monitor thread and trying to read the
> > counters, but it is showing the error message: Cannot attach: Operation
> > not permitted. Also I tried to read by saving the file descriptor
> > variable, it is also not working.
> >
> > Must the per-thread monitoring always be self-monitoring? Otherwise, I
> > think it will always be the case that the monitoring thread wont have
> > any access to PMU state initialized by the appThread.
> >
> > What wrong I am doing here?Do you have any examples for perthread
> > monitoring using threads?
> >
> 
> You can monitor from the same thread or from another thread, or from 
> another thread in a different process.
> 
> Have you looked at libpfm/examples_v2.x/task_attach.c ?
> 
> It is an example of monitoring events in another task (i.e. process or 
> thread).
> 
> - Corey
> ------------------------------------------------------------------------------
> Enter the BlackBerry Developer Challenge  
> This is your chance to win up to $100,000 in prizes! For a limited time, 
> vendors submitting new applications to BlackBerry App World(TM) will have
> the opportunity to enter the BlackBerry Developer Challenge. See full prize  
> details at: http://p.sf.net/sfu/Challenge
> _______________________________________________
> perfmon2-devel mailing list
> perfmon2-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/perfmon2-devel



      
/*
 *
 * self_smpl_multi.c - multi-thread self-sampling program
 
Original:
 *  Create a new thread, launch perfmon overflow counters in both
 *  threads, print the number of interrupts per thread and per second,
 *  and look for anomalous interrupts.  Look for mismatched thread
 *  ids, bad message type, or failed pfm_restart().

Mine:
 * One Application Thread, One performance monitoring thread, NON-self Monitoring
 * pinning done in core 0, reads the counters every 2 seconds
 * start, print and stop in the while(1) loop
 */

#define _GNU_SOURCE

#include <sys/time.h>
#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/ptrace.h>

#include <linux/unistd.h>
#include <perfmon/perfmon.h>
#include <perfmon/pfmlib.h>
#include "detect_pmcs.h"

#define PROGRAM_TIME  20
#define MAX_FD  20

struct over_args {
	pfmlib_event_t ev;
	pfmlib_input_param_t  inp;
	pfmlib_output_param_t outp;
	pfarg_pmc_t pc[PFMLIB_MAX_PMCS];
	pfarg_pmd_t pd[PFMLIB_MAX_PMDS];
	pfarg_ctx_t ctx;
	pfarg_load_t load_arg;
	int fd;
	pid_t tid;
	pthread_t self;
};

struct over_args fd2ov[MAX_FD];
int apptid;
struct over_args appov;

/* 
 * get the thread ID
 */

pid_t gettid(void)
{
#ifdef SYS_gettid
	return (pid_t)syscall(SYS_gettid);
#elif defined(__NR_gettid)
	return (pid_t)syscall(__NR_gettid);
#else
#error "Unable to implement gettid."
#endif
}

/*
 * pin task to CPU
 */
#ifndef __NR_sched_setaffinity
#error "you need to define __NR_sched_setaffinity"
#endif

#define MAX_CPUS	2048
#define NR_CPU_BITS	(MAX_CPUS>>3)

int pin_cpu(pid_t pid, unsigned int cpu)
{
	uint64_t my_mask[NR_CPU_BITS];

	if (cpu >= MAX_CPUS)
		printf("this program supports only up to %d CPUs\n", MAX_CPUS);

	my_mask[cpu>>6] = 1ULL << (cpu&63);

	return syscall(__NR_sched_setaffinity, pid, sizeof(my_mask), &my_mask);
}

int big[123456789];

void* performanceMonitorThread(void *v)
{
	int i, fd, flags, ret, num_counters;
	int status;

	struct over_args ov;
	pfarg_msg_t msg;

	pin_cpu(gettid(), 1);
	fprintf(stdout, "PMThread ID %d\n", gettid());	
	fprintf(stdout, "PMThread fd %d\n",appov.fd);
	
	while(1)
	{
		memset(&ov, 0, sizeof(struct over_args));

		pfm_get_num_counters(&num_counters);

		ret = pfm_find_full_event("INSTRUCTIONS_RETIRED", &ov.inp.pfp_events[0]);
		if (ret != PFMLIB_SUCCESS)
			  printf("event %s: INSTRUCTIONS_RETIRED\n", pfm_strerror(ret));
	
  		ret = pfm_find_full_event("LAST_LEVEL_CACHE_MISSES", &ov.inp.pfp_events[1]);
		if (ret != PFMLIB_SUCCESS)
			  printf("event %s: Error\n", pfm_strerror(ret));

		ov.inp.pfp_event_count = 2;
		ov.inp.pfp_dfl_plm = PFM_PLM3;
		ov.inp.pfp_events[0] = ov.ev;
		

		fd = pfm_create_context(&ov.ctx, NULL, NULL, 0);
		if (fd < 0)
			errx(1, "pfm_create_context failed");

		fd2ov[fd] = ov;
		ov.fd = fd;
		ov.tid = apptid;
		//ov.tid = gettid();
		fprintf(stdout, "apptid %d gettid(): %d \n",apptid, gettid());
		ov.self = pthread_self();

		detect_unavail_pmcs(fd, &ov.inp.pfp_unavail_pmcs);

		if (pfm_dispatch_events(&ov.inp, NULL, &ov.outp, NULL) != PFMLIB_SUCCESS)
			errx(1, "pfm_dispatch_events failed");

		for (i = 0; i < ov.outp.pfp_pmc_count; i++) {
			ov.pc[i].reg_num =   ov.outp.pfp_pmcs[i].reg_num;
			ov.pc[i].reg_value = ov.outp.pfp_pmcs[i].reg_value;
		}

		for (i = 0; i < ov.outp.pfp_pmd_count; i++) {
			ov.pd[i].reg_num = ov.outp.pfp_pmds[i].reg_num;
		}

		ov.pd[0].reg_flags |= PFM_REGFL_OVFL_NOTIFY;
		ov.pd[0].reg_value =  0;
		ov.pd[1].reg_value = 0;
	
		if (pfm_write_pmcs(fd, ov.pc, ov.outp.pfp_pmc_count))
			errx(1, "pfm_write_pmcs failed");

		if (pfm_write_pmds(fd, ov.pd, ov.outp.pfp_pmd_count))
			errx(1, "pfm_write_pmds failed");
	
		ret = ptrace(PTRACE_ATTACH, apptid, NULL, 0);
		if (ret == -1) {
			fprintf(stderr,"cannot attach to %d: %s\n", apptid, strerror(errno));		
		}

		waitpid(apptid, &status, WUNTRACED);
		if (WIFEXITED(status)) {
			fprintf(stdout,"command process %d exited too early with status %d\n", apptid, 			WEXITSTATUS(status));
		}

		ov.load_arg.load_pid = apptid;

		//ov.load_arg.load_pid = gettid();
	
		if (pfm_load_context(fd, &ov.load_arg) != 0)
			errx(1, "pfm_load_context failed");

		pfm_self_start(fd);
		
		ptrace(PTRACE_DETACH, apptid, NULL, 0);
		
		/*ret = read(fd, &msg, sizeof(msg));
		if (ret == -1) {
			fprintf(stderr, "cannot read from descriptor: %s\n", strerror(errno));
		}

		if (msg.type != PFM_MSG_END) {
			fprintf(stderr, "unexpected msg type : %d\n", msg.type);
		}*/

		if (pfm_read_pmds(fd, ov.pd, ov.inp.pfp_event_count)){
			printf( "pfm_read_pmds error errno %d\n",errno);
			printf("Error name: %s\n", strerror(errno));
		}
	
		for (i=0; i < ov.inp.pfp_event_count; i++) {
			fprintf(stdout, "Value: %d\t",ov.pd[i].reg_value);
	    		ov.pd[i].reg_value=0;
		}
		
		fprintf(stdout,"\n");
		pfm_write_pmds(fd, ov.pd, ov.inp.pfp_event_count);
		
		pfm_self_stop(ov.fd);
		close(ov.fd);
		sleep(2);
	}
	
	return (NULL);
}

void* applicationThread(void *v)
{
	struct over_args ov;

	pin_cpu(gettid(), 1);
	apptid=gettid();
	appov=ov;
	fprintf(stdout, "AppThread ID %d %d %d\n", apptid, ov.fd, appov.fd);
	
	while(1)
  	{
		big[rand()%123456789]=rand()%123456789;
    	}
	
	
	return (NULL);
}

int main(int argc, char **argv)
{
	pthread_t thr, pmt;
	struct over_args ov;
	struct timeval start, last, now;
	int i, pmt_rt;
	
	if (pfm_initialize() != PFMLIB_SUCCESS)
		errx(1, "pfm_initialize failed");

	printf("\n");
	
	fprintf(stderr,"before APP created\n");

	if (pthread_create(&thr, NULL, applicationThread, NULL) != 0)
		errx(1, "pthread_create failed");

	sleep(1);
	pmt_rt=pthread_create(&pmt, NULL, performanceMonitorThread, NULL);
	if(pmt_rt==0)
		fprintf(stderr,"Performance Monitor is successfully created\n");

	gettimeofday(&start, NULL);
	last = start;

	do{
		gettimeofday(&now, NULL);
		last = now;	
	}while(now.tv_sec < start.tv_sec + PROGRAM_TIME);

	return (0);
}
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
perfmon2-devel mailing list
perfmon2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel

Reply via email to