????

??? DTrace ???????????????????????????????????DTrace ?????????????????????????????????????????????????? ????????????????????DTrace ?????????????????????????????????????????????????? ?

plockstat ?????????

??????? plockstat ???? ????????? DTrace ?????????????OpenSolaris.org ??? plockstat ????? ?????? ???????1000 ?????????? 300 ???? DTrace ???????????????????????????????? plockstat ??????????? DTrace ?????? plockstat ???????????????????????????????????????????

mutex ??????????? DTrace ?????

plockstat ????????????? mutex ?????????????????????????????????????????????????p lockstat$target::: ?????????????????plockstat ??????????????? DTrace ? plockstat ?????????????????plockstat ?????? mutex ???? reader/writer ?????????? DTrace ?????????plockstat ????? plockstat ??????????????????????plockstat ????? plockstat ????????????????????????????????????????????plocks tat$target:::mutex-block ?????? mutex ????????????????????????????? plockstat$target:::mutex-blocked ?????????????????????????mutex-block ? mutex-blocked ? timestamp ??????? mutex ??????????????????????????????plockstat$target:::m utex-blocked ? arg1 ? 0 ???????????? mutex ?????????????????????????????????????????????

#!/usr/sbin/dtrace -s plockstat$target:::mutex-block { self->mtxblock[arg0] = timestamp; } plockstat$target:::mutex-blocked /self->mtxblock[arg0] && arg1 != 0/ /* arg1 is not 0 => lock is acquired */ { @mtx_block[arg0, ustack(5)] = sum(timestamp - self->mtxblock[arg0]); @mtx_block_count[arg0, ustack(5)] = count(); self->mtxblock[arg0] = 0; mtx_block_found = 1; } plockstat$target:::mutex-blocked /self->mtxblock[arg0]/ /* arg1 is 0 => error */ { self->mtxblock[arg0] = 0; } END /mtx_block_found/ { trace("Mutex block"); printa(@mtx_block, @mtx_block_count); } ?????????

??????????? plockstat ??? ??????????????????????????????????????"134614312" ? plockstat ????? "Lock" ????????? mutex ???????????????????? "Caller" ?????????????????"30002403544" ? mutex ?????????????????????? "3" ? plockstat ????? "Count" ?????????????????????????????????????????????????? ??????? plockstat ????? "nsec" ?????????? (30002403544 nsec / 3 Count = 10000801181 nsec)????? plockstat ??????????????????????????

# ./plockstat_mb.d -c ./mutex_test /ppre #!/usr/sbin/dtrace -qs int ntick; BEGIN { ntick = 0; } plockstat$target:::mutex-block { self-mtxblock = timestamp; } plockstat$target:::mutex-blocked /self-mtxblock && arg1 != 0/ /* arg1 is not 0 => lock is acquired */ { @mtx_block[tid]= sum(timestamp - self->mtxblock); @mtx_block_count[tid] = count(); self->mtxblock = 0; } plockstat$target:::mutex-blocked /self->mtxblock/ /* arg1 is 0 => error */ { self->mtxblock = 0; } tick-1sec { ntick += 1; } tick-1sec /ntick == 10/ { trace("Count"); printa(@mtx_block_count); trace("nsec"); printa(@mtx_block); exit(0); } DTrace ??????????

??????????? plockstat ???????????? general.c ????????Count ???????????????????nsec ???????????????????????????? 10 ?????????Count ???????????????? ID???????????????????????? ID ? 8 ??????? 10 ???? 15197 ??????????????????nsec ?????????????? ID ???????????????????????????????????????????? ID 5 ??????? 10 ????? 5.8 ?????????????????????

# ./plockstat_mbt.d -c ./general Count 8 15197 2 15395 3 15397 7 15418 6 15480 4 15604 9 15633 5 16011 nsec 5 5849251426 6 5891593031 9 5904264724 4 5912264400 3 5953877535 2 5983468423 7 6004800234 8 6067032588 plockstat ?????????????????????

plockstat ???????????? mutex ???? reader/writer ?????????????????????????????????????????????????? ?????????????????????????mutex ???? reader/writer ??????????????????

?????????????

???????????????????? main() ????? res ???????????????????????????

/* * cv_test.c : a test program for cv tracing. * compile : cc cv_test.c -o cv_test */ #include #include #include #include void *func(); volatile uint_t res = 0; pthread_mutex_t mp; pthread_cond_t cv; int main() { pthread_t tid1, tid2; pthread_mutex_init(&mp, NULL); pthread_cond_init(&cv, NULL); pthread_create(&tid1, NULL, func, NULL); pthread_create(&tid2, NULL, func, NULL); sleep(10); atomic_inc_uint(&res); pthread_mutex_lock(&mp); pthread_cond_broadcast(&cv); pthread_mutex_unlock(&mp); pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_mutex_destroy(&mp); pthread_cond_destroy(&cv); exit(0); } void *func() { pthread_mutex_lock(&mp); while(res == 0) { pthread_cond_wait(&cv, &mp); } puts("done"); pthread_mutex_unlock(&mp); pthread_exit(0); } ?????

???????????? cv_test.c ??????????????????????????

# gcc cv_test.c -o cv_test prstat ?????

prstat ?????? LWPID 1 ?????????? ("SLP") ??LWPID 2 ? 3 ??????????? ("LCK") ????????????

# ./cv_test&; prstat -mL -p $! PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID 10189 root 0.0 0.0 0.0 0.0 0.0 100 0.0 0.0 0 0 0 0 cv_test/3 10189 root 0.0 0.0 0.0 0.0 0.0 100 0.0 0.0 0 0 0 0 cv_test/2 10189 root 0.0 0.0 0.0 0.0 0.0 0.0 100 0.0 0 0 0 0 cv_test/1 plockstat ?????

cv_test ?????? plockstat ???????????????????prstat ????????????????????????????????plockstat ????????????????????????????????

# plockstat -Cv ./cv_test plockstat: tracing enabled for pid 19839 done done plockstat: pid 19839 has exited ????????? DTrace ?????

plockstat ?????????????? DTrace ????????????????????????????DTrace ? pid ?????????? pthread_cond_wait() ?????????????????? pthread_cond_timedwait() ? pthread_cond_reltimedwait_np() ?????????????????????????????????????

#!/usr/sbin/dtrace -s pid$target::pthread_cond_wait:entry { self->start = timestamp; self->addr = arg0; } pid$target::pthread_cond_wait:return /self->start/ { @time[tid,self->addr] = sum(timestamp - self->start); @cnt[tid,self->addr] = count(); self->start = 0; } END { printf("叩"); printf("叩"); printf("tid另cv address另time(nsec)叩"); printa("%d另%p另另%@u叩", @time); printf("叩"); printf("tid另cv address另count叩"); printa("%d另%p另另%@u叩", @cnt); } DTrace ??????????

???????? cv.d ???????????????????????????????????????tid 2 ?????? time(nsec) ? 10000060220 (=> 10 sec)?tid 3 ?????? time(nsec) ? 10000693754 (=> 10 sec) ?????????????? 10 ??????????????????????tid 2, tid 3 ?????? count ? 1 ??????????? 1 ??? pthread_cond_wait() ????????????????

# chmod +x ./cv.d # ./cv.d -c ./cv_test