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