Here is the code I have in papi to fix this:

Apologies for the line wraps...

int tune_up_fd(int
fd)                                                                             
                            
{                                                                               
                                               
  /* set close-on-exec to ensure we will be getting the PFM_END_MSG,
i.e.,                                                     
   * fd not visible to child.
*/                                                                              
                 
  ret = fcntl(ctx_fd, F_SETFD,
FD_CLOEXEC);                                                                    
                
  if (ret ==
-1)                                                                             
                                  

{                                                                               
                                           
      PAPIERROR("cannot fcntl(FD_CLOEXEC) on %d: %s",
ctx_fd,strerror(errno));                                                 

return(PAPI_ESYS);                                                              
                                         
    }                                                                           
                                               
  /* setup asynchronous notification on the file descriptor
*/                                                                 
  ret = fcntl(ctx_fd, F_SETFL, fcntl(ctx_fd, F_GETFL, 0) |
O_ASYNC);                                                           
  if (ret ==
-1)                                                                             
                                  

{                                                                               
                                           
      PAPIERROR("cannot fcntl(O_ASYNC) on %d: %s",
ctx_fd,strerror(errno));                                                    

return(PAPI_ESYS);                                                              
                                         
    }                                                                           
                                               
  /* get ownership of the descriptor
*/                                                                              
          
  ret = fcntl(ctx_fd, F_SETOWN,
mygettid());                                                                    
               
  if (ret ==
-1)                                                                             
                                  

{                                                                               
                                           
      PAPIERROR("cannot fcntl(F_SETOWN) on %d: %s",
ctx_fd,strerror(errno));                                                   

return(PAPI_ESYS);                                                              
                                         
    }                                                                           
                                               
  /*                                                                            
                                               
   * when you explicitely declare that you want a particular
signal,                                                           
   * even with you use the default signal, the kernel will send
more                                                           
   * information concerning the event to the signal
handler.                                                                   

*                                                                               
                                            
   * In particular, it will send the file descriptor from which
the                                                            
   * event is originating which can be quite useful when
monitoring                                                            
   * multiple tasks from a single
thread.                                                                         
             

*/                                                                              
                                            
  ret = fcntl(ctx_fd, F_SETSIG,
_papi_hwi_system_info.sub_info.hardware_intr_sig);                              
               
  if (ret ==
-1)                                                                             
                                  

{                                                                               
                                           
      PAPIERROR("cannot fcntl(F_SETSIG,%d) on %d: %s",
_papi_hwi_system_info.sub_info.hardware_intr_sig, ctx_fd, strerror(errn\
o));                                                                            
                                               

return(PAPI_ESYS);                                                              
                                         
    }                                                                           
                                               

return(PAPI_OK);                                                                
                                             
}               

On Thu, 2007-03-22 at 12:15 -0800, Stephane Eranian wrote:
> Richard,
> 
> On Thu, Mar 22, 2007 at 12:10:46PM -0400, Richard C Bilson wrote:
> > Hello Stephane and others,
> > 
> > As part of our work on uProfiler we are using perfmon to self-sample
> > multithreaded programs. Specifically, we have programs with multiple
> > kernel threads, each with their own perfmon context, each requesting
> > overflow interrupts through SIGIO.
> > 
> > The behavior that's troubling me right now is that there appears to be
> > no guarantee that the SIGIO is delivered to the same kernel thread that
> > caused the corresponding counter overflow. Specifically, I find our
> > SIGIO handler being activated on a particular kernel thread with
> > siginfo's si_fd member referring to the context of a different kernel
> > thread.
> > 
> You are perfectly right, POSIX does not stipulate that SIGIO goes to the
> thread that generated the event. In general asynchronous signals cannot
> be targeted to a particular thread. I ran into this myself with earlier
> version of pfmon. There is nothing I can do about it in perfmon. You'd have
> to structure your code differently or use the trick you are using, i.e.,
> based on the fd forward to the right thread. One thing is sure, is that
> the signal is not delivered to a thread that blocks the signal. So you
> could have all but one thread block the signal and then dispatch from there.
> 
> 
> > I can understand why this behavior might suit some applications, but it
> > poses real problems for us: we use overflow notifications as a cue to
> > sample a variety of bits of application state on that kernel thread, so
> > getting the notification on a different thread doesn't help us.
> > 
> > As of now, I haven't been able even to craft an effective work-around.
> > The best I can come up with is to detect a signal on the "wrong" thread
> > and respond with a pthread_kill to the right thread. But that seems
> > like it would significantly increase not only our probe effect but,
> > more importantly, the time between overflow and sample.
> > 
> > I hope someone can tell me that there's an obvious switch that I've
> > overlooked, but I appreciate any comments or ideas.
> > 
> > Thanks.
> > -- 
> > Richard C. Bilson, Research Assistant     [EMAIL PROTECTED]
> >                 http://plg.uwaterloo.ca/~rcbilson
> >  D. R. Cheriton School of Computer Science, University of Waterloo
> >    200 University Avenue West, Waterloo, Ontario, CANADA N2L 3G1
> > _______________________________________________
> > perfmon mailing list
> > [email protected]
> > http://www.hpl.hp.com/hosted/linux/mail-archives/perfmon/
> 

_______________________________________________
perfmon mailing list
[email protected]
http://www.hpl.hp.com/hosted/linux/mail-archives/perfmon/

Reply via email to