Priya Natarajan
2008-Feb-12 20:50 UTC
[dtrace-discuss] measuring sleep time in synchronization objects
Hi, I am fairly new to DTrace, and wanted to ask something regarding synchronization objects. I have a multithreaded C++ program in which I use semaphores (POSIX version) for synchronization. I was interested in using DTrace to figure out the total time for which each thread in my application sleeps, blocked on a semaphore, i.e., as a result of sem_wait() call. In order to measure this, I wrote a script with sched:::sleep and sched:wakeup probes enabled, as shown below: sched:::sleep /execname == "myexecname"/ { ustack(); bedtime[curlwpsinfo->pr_addr,curlwpsinfo->pr_stype] = walltimestamp; } sched:::wakeup /bedtime[args[0]->pr_addr,args[0]->pr_stype]/ { @sleeptime[execname,args[0]->pr_lwpid,args[0]->pr_addr,args[0]->pr_stype] sum(walltimestamp - bedtime[args[0]->pr_addr,args[0]->pr_stype]); bedtime[args[0]->pr_addr,args[0]->pr_stype] = 0; } On running my program along with this script, I could see (because of ustack()) that the program is following the expected path to sem_wait() call and then enters cv_block:sleep. The aggregation output showed that the threads in my program are sleeping on pr_stype = 3 (translates to SOBJ_CV according to the file sobject.h). However, I was expecting to see the threads sleeping on pr_stype = 5 (SOBJ_USER) as a result of sem_wait() calls, because the description of pr_stype field in struct lwpsinfo_t says that (and I quote from chapter 25 of the DTrace guide): The pr_stype field is set when the thread is sleeping on a synchronization object. The possible values for the pr_stype field are: SOBJ_MUTEX SOBJ_RWLOCK ... SOBJ_USER : A user-level synchronization object. All blocking on user-level synchronization objects is handled with SOBJ_USER synchronization objects. User-level synchronization objects include those created with mutex_init(3), sema_init(3C), rwlock_init(3C), cond_init(3C) and their POSIX equivalents. ... SOBJ_SHUTTLE I was not surprised that the threads are sleeping on other synchronization objects as well, but no account of SOBJ_USER was a little surprising. Although I can see from ustack() that sem_wait() ultimately leads to cv_block:sleep, was I wrong in expecting to see pr_stype = SOBJ_USER in the output? Can someone please explain what is going on? In case this is not the correct forum for such questions, please direct me to a suitable forum. Thank you for your time. Regards, Priya -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.opensolaris.org/pipermail/dtrace-discuss/attachments/20080212/f08ae2e2/attachment.html>
Adam Leventhal
2008-Mar-12 07:05 UTC
[dtrace-discuss] measuring sleep time in synchronization objects
Hi Priya, Sorry for taking so long to get back to you. This appears to be a subtle difference between the documented behavior and what''s actually implemented. In most cases, user- land synchronization primitives will call lwp_block() which shows up as SOBJ_USER, but some cases call lwp_park() which calls cv_waituntil_sig() so shows up as SOBJ_CV. I''d argue that this is a bug, but libc guru Roger Faulkner may want to weigh in. Adam On Feb 12, 2008, at 12:50 PM, Priya Natarajan wrote:> Hi, > > I am fairly new to DTrace, and wanted to ask something regarding > synchronization objects. > > I have a multithreaded C++ program in which I use semaphores (POSIX > version) for synchronization. I was interested in using DTrace to > figure out the total time for which each thread in my application > sleeps, blocked on a semaphore, i.e., as a result of sem_wait() > call. In order to measure this, I wrote a script with sched:::sleep > and sched:wakeup probes enabled, as shown below: > > sched:::sleep > /execname == ?myexecname?/ > { > ustack(); > bedtime[curlwpsinfo->pr_addr,curlwpsinfo->pr_stype] = > walltimestamp; > } > > sched:::wakeup > /bedtime[args[0]->pr_addr,args[0]->pr_stype]/ > { > @sleeptime[execname,args[0]->pr_lwpid,args[0]->pr_addr,args[0]- > >pr_stype] = sum(walltimestamp - bedtime[args[0]->pr_addr,args[0]- > >pr_stype]); > bedtime[args[0]->pr_addr,args[0]->pr_stype] = 0; > } > > On running my program along with this script, I could see (because > of ustack()) that the program is following the expected path to > sem_wait() call and then enters cv_block:sleep. The aggregation > output showed that the threads in my program are sleeping on > pr_stype = 3 (translates to SOBJ_CV according to the file > sobject.h). However, I was expecting to see the threads sleeping on > pr_stype = 5 (SOBJ_USER) as a result of sem_wait() calls, because > the description of pr_stype field in struct lwpsinfo_t says that > (and I quote from chapter 25 of the DTrace guide): > > The pr_stype field is set when the thread is sleeping on a > synchronization object. > The possible values for the pr_stype field are: > SOBJ_MUTEX > SOBJ_RWLOCK > ... > SOBJ_USER : A user-level synchronization object. All blocking on > user-level > synchronization objects is handled with SOBJ_USER synchronization > objects. User-level synchronization objects include those created with > mutex_init(3), sema_init(3C), rwlock_init(3C), > cond_init(3C) and their POSIX equivalents. > ... > SOBJ_SHUTTLE > > I was not surprised that the threads are sleeping on other > synchronization objects as well, but no account of SOBJ_USER was a > little surprising. > Although I can see from ustack() that sem_wait() ultimately leads to > cv_block:sleep, was I wrong in expecting to see pr_stype = SOBJ_USER > in the output? Can someone please explain what is going on? > > In case this is not the correct forum for such questions, please > direct me to a suitable forum. Thank you for your time. > > Regards, > Priya > > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org-- Adam Leventhal, Fishworks http://blogs.sun.com/ahl