HI there, I?ve discovered DTrace few days ago and I?m currently stuck on a cpu stats problem. I?m trying to poll the cpu_t.cpu_acct[] array to pull idle, system and user values. So, I made this little script: ------------------------------------------------------------------------------------------------------ #!/usr/sbin/dtrace -s #pragma D option quiet this uint64_t start; this hrtime_t timeidle; this hrtime_t timeuser; this hrtime_t timesystem; this hrtime_t timewait; this int in; dtrace:::BEGIN { this -> start = timestamp; this -> timeidle = 0; this -> timeuser = 0; this -> timesystem = 0; this -> timewait = 0; this -> in = 0; } sched:::on-cpu { this -> timeidle = curthread -> t_cpu -> cpu_acct[2]; this -> timeuser = curthread -> t_cpu -> cpu_acct[0]; this -> timesystem = curthread -> t_cpu -> cpu_acct[1]; this -> in = 1; } sched:::off-cpu /this->in/ { @user = sum(curthread->t_cpu->cpu_acct[0] - this -> timeuser); @system = sum(curthread->t_cpu->cpu_acct[1] - this -> timesystem); @idle = sum(curthread->t_cpu->cpu_acct[2] - this -> timeidle); } dtrace:::END { printf("elapsed time : %u\n",(timestamp - this -> start)); } ---------------------------------------------------------------------------------------------------------------- I?m not sure that?s the best way to get those values, but it?s the only one I found. The main problem is that the ?@idle? value is higher than the ?timestamp ? this -> start? one, meaning that the cpu has spent more time in idle state than the whole duration of the script. What did I do wrong ? Thanks for your help :) This message posted from opensolaris.org
Hi! There is a problem with your script, but I''m not sure if it''s the source of the problem you''re asking about. Clause local variables (this->) only maintain their storage allocation for the duration of the probe clauses activated for the firing of one probe. So, for example, if you had two probe clauses associated with the on-cpu probe, your clause local variables would remain active for the execution of the both clauses. However, in your case, there''s no guarantee that the values for the clause local variables that you set in the on-cpu probe clause are going to still be available when you reference them in the off-cpu probe clause. I say no guarantee, because I''ve seen cases where the values happen to still be there, because the storage locations happen to get reused in the same order, and since clause local variables are not initialized to zero automatically like other variable types, you might get away with it. I think I''d used thread local variables (self->). Just don''t forget to set them to zero at the end of the "off-cpu" probe clause, so that they don''t take over your memory. Chip LOETSCHER wrote:> HI there, > > I?ve discovered DTrace few days ago and I?m currently stuck on a cpu stats problem. I?m trying to poll the cpu_t.cpu_acct[] array to pull idle, system and user values. > So, I made this little script: > ------------------------------------------------------------------------------------------------------ > #!/usr/sbin/dtrace -s > #pragma D option quiet > > this uint64_t start; > this hrtime_t timeidle; > this hrtime_t timeuser; > this hrtime_t timesystem; > this hrtime_t timewait; > this int in; > > dtrace:::BEGIN > { > this -> start = timestamp; > this -> timeidle = 0; > this -> timeuser = 0; > this -> timesystem = 0; > this -> timewait = 0; > this -> in = 0; > } > sched:::on-cpu > { > this -> timeidle = curthread -> t_cpu -> cpu_acct[2]; > this -> timeuser = curthread -> t_cpu -> cpu_acct[0]; > this -> timesystem = curthread -> t_cpu -> cpu_acct[1]; > this -> in = 1; > } > sched:::off-cpu > /this->in/ > { > @user = sum(curthread->t_cpu->cpu_acct[0] - this -> timeuser); > @system = sum(curthread->t_cpu->cpu_acct[1] - this -> timesystem); > @idle = sum(curthread->t_cpu->cpu_acct[2] - this -> timeidle); > } > > dtrace:::END > { > printf("elapsed time : %u\n",(timestamp - this -> start)); > } > ---------------------------------------------------------------------------------------------------------------- > > I?m not sure that?s the best way to get those values, but it?s the only one I found. The main problem is that the ?@idle? value is higher than the ?timestamp ? this -> start? one, meaning that the cpu has spent more time in idle state than the whole duration of the script. > What did I do wrong ? > Thanks for your help :) > > > This message posted from opensolaris.org > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org >
Hi,> HI there, > > I???ve discovered DTrace few days ago and I???m currently stuck on a cpu stats problem. I???m trying to poll the cpu_t.cpu_acct[] array to pull idle, system and user values.While you can use DTrace for this you can also get this info from the /proc/<pid>/usage structure.> So, I made this little script: > ------------------------------------------------------------------------------------------------------ > #!/usr/sbin/dtrace -s > #pragma D option quiet > > this uint64_t start; > this hrtime_t timeidle; > this hrtime_t timeuser; > this hrtime_t timesystem; > this hrtime_t timewait; > this int in; > > dtrace:::BEGIN > { > this -> start = timestamp; > this -> timeidle = 0; > this -> timeuser = 0; > this -> timesystem = 0; > this -> timewait = 0; > this -> in = 0; > } > sched:::on-cpu > { > this -> timeidle = curthread -> t_cpu -> cpu_acct[2]; > this -> timeuser = curthread -> t_cpu -> cpu_acct[0]; > this -> timesystem = curthread -> t_cpu -> cpu_acct[1]; > this -> in = 1; > }Note that this is a close-local variable which only has meaning within a single clause. You probably want to use ''self'' instead of ''this'' or associative array keyed by a thread. Note that you can''t initialise thread-local variables in the BEGIN probe because they are thread-specific. - Alex Kolbasov.
s/this/self/ ''this'' storage goes away at the end of the probe clause. To be prudent, you may want to set self->in to 0 in off-cpu{}. -r LOETSCHER writes: > HI there, > > I???ve discovered DTrace few days ago and I???m currently stuck on a cpu stats problem. I???m trying to poll the cpu_t.cpu_acct[] array to pull idle, system and user values. > So, I made this little script: > ------------------------------------------------------------------------------------------------------ > #!/usr/sbin/dtrace -s > #pragma D option quiet > > this uint64_t start; > this hrtime_t timeidle; > this hrtime_t timeuser; > this hrtime_t timesystem; > this hrtime_t timewait; > this int in; > > dtrace:::BEGIN > { > this -> start = timestamp; > this -> timeidle = 0; > this -> timeuser = 0; > this -> timesystem = 0; > this -> timewait = 0; > this -> in = 0; > } > sched:::on-cpu > { > this -> timeidle = curthread -> t_cpu -> cpu_acct[2]; > this -> timeuser = curthread -> t_cpu -> cpu_acct[0]; > this -> timesystem = curthread -> t_cpu -> cpu_acct[1]; > this -> in = 1; > } > sched:::off-cpu > /this->in/ > { > @user = sum(curthread->t_cpu->cpu_acct[0] - this -> timeuser); > @system = sum(curthread->t_cpu->cpu_acct[1] - this -> timesystem); > @idle = sum(curthread->t_cpu->cpu_acct[2] - this -> timeidle); > } > > dtrace:::END > { > printf("elapsed time : %u\n",(timestamp - this -> start)); > } > ---------------------------------------------------------------------------------------------------------------- > > I???m not sure that???s the best way to get those values, but it???s the only one I found. The main problem is that the ???@idle??? value is higher than the ???timestamp ??? this -> start??? one, meaning that the cpu has spent more time in idle state than the whole duration of the script. > What did I do wrong ? > Thanks for your help :) > > > This message posted from opensolaris.org > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org
Hi> > Note that this is a close-local variable which only > has meaning within a > single clause. You probably want to use ''self'' > instead of ''this'' or > associative array keyed by a thread. > > Note that you can''t initialise thread-local variables > in the BEGIN probe > because they are thread-specific. > > - Alex Kolbasov. >Well, shame on me, it''s clearly written in the DTrace - Guide, page 62. Ooops... But after correcting my script, the same problem appear. I have rewritten another tiny script, to focus on the "idle" value. --------------------------------------------------------------------------------------------- #!/usr/sbin/dtrace -qs long long timestampidle; long long start; long long total; long long idle; int in; int seconds; dtrace:::BEGIN { start = timestamp; total = 0; in = 0; seconds = 3; } profile-1 /seconds != 0/ { seconds--; } profile-1 /seconds == 0/ { exit(0); } sched:::on-cpu { in = 1; timestampidle = curthread -> t_cpu -> cpu_acct[2]; } sched:::off-cpu /in/ { idle = curthread -> t_cpu -> cpu_acct[2] - timestampidle; printf("idle time : %d\n",idle); total = total + idle; } dtrace:::END { printf("end time : %d\n",timestamp - start); printf("total idle : %lld\n",total); } ------------------------------------------------------------------------------------------------- Final output : ------------------------------------------------------------------------------------------------- ...... idle time : 0 idle time : 0 idle time : 18580304 idle time : 0 idle time : 0 idle time : 0 idle time : 18465891 idle time : 0 idle time : 0 idle time : 18941504 idle time : 0 idle time : 0 idle time : 18386068 idle time : 0 end time : 3040254054 total idle : 5339226728 -------------------------------------------------------------------------------------------------- The cpu_acct array is an "hrtime_t" type = "long long" type. The description is " Time expressed as a 64-bit nanosecond counter." As you can see, the script is programmed to run 3 seconds, and I''ve got a total running time of : 3040254054 nsec ~ 3 sec. But the total of cpu idle time is : 5339226728 nsec, more than the total duration of the script ! The cpu_acct array is an "hrtime_t" type = "long long" type. The description is " Time expressed as a 64-bit nanosecond counter." How can this be possible ? Did I do another dumb mistake ? This message posted from opensolaris.org
If it''s not a single CPU system you seem to have data races on your variables. Note also that you may reduce the occurence of those races but to properly eliminate them you need to use aggregations (sum). LOETSCHER writes: > Hi > > > > > > Note that this is a close-local variable which only > > has meaning within a > > single clause. You probably want to use ''self'' > > instead of ''this'' or > > associative array keyed by a thread. > > > > Note that you can''t initialise thread-local variables > > in the BEGIN probe > > because they are thread-specific. > > > > - Alex Kolbasov. > > > > Well, shame on me, it''s clearly written in the DTrace - Guide, page 62. Ooops... > > But after correcting my script, the same problem appear. I have rewritten another tiny script, to focus on the "idle" value. > --------------------------------------------------------------------------------------------- > #!/usr/sbin/dtrace -qs > > long long timestampidle; > long long start; > long long total; > long long idle; > int in; > int seconds; > > dtrace:::BEGIN > { > start = timestamp; > total = 0; > in = 0; > seconds = 3; > } > > profile-1 > /seconds != 0/ > { > seconds--; > } > > profile-1 > /seconds == 0/ > { > exit(0); > } > > sched:::on-cpu > { > in = 1; > timestampidle = curthread -> t_cpu -> cpu_acct[2]; > } > sched:::off-cpu > /in/ > { > idle = curthread -> t_cpu -> cpu_acct[2] - timestampidle; > printf("idle time : %d\n",idle); > > total = total + idle; > } > > dtrace:::END > { > printf("end time : %d\n",timestamp - start); > printf("total idle : %lld\n",total); > } > ------------------------------------------------------------------------------------------------- > Final output : > ------------------------------------------------------------------------------------------------- > ...... > idle time : 0 > idle time : 0 > idle time : 18580304 > idle time : 0 > idle time : 0 > idle time : 0 > idle time : 18465891 > idle time : 0 > idle time : 0 > idle time : 18941504 > idle time : 0 > idle time : 0 > idle time : 18386068 > idle time : 0 > end time : 3040254054 > total idle : 5339226728 > -------------------------------------------------------------------------------------------------- > > The cpu_acct array is an "hrtime_t" type = "long long" type. The description is " Time expressed as a 64-bit nanosecond counter." > > As you can see, the script is programmed to run 3 seconds, and I''ve got a total running time of : 3040254054 nsec ~ 3 sec. > But the total of cpu idle time is : 5339226728 nsec, more than the total duration of the script ! > > The cpu_acct array is an "hrtime_t" type = "long long" type. The description is " Time expressed as a 64-bit nanosecond counter." > > How can this be possible ? > > Did I do another dumb mistake ? > > > This message posted from opensolaris.org > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org
> > > If it''s not a single CPU system you seem to have > data races > on your variables. Note also that you may > reduce the > occurence of those races but to properly eliminate > them you > need to use aggregations (sum). >No, it''s a single-cpu computer. I changed the script a little bit, and replace : --------------------------------------------------------------------------------------------- idle = curthread -> t_cpu -> cpu_acct[0] - timestampidle; printf("idle time : %d\n",idle); total = total + idle; --------------------------------------------------------------------------------------------- by : --------------------------------------------------------------------------------------------- @result[cpu] = sum (curthread -> t_cpu -> cpu_acct[2] - timestampidle); --------------------------------------------------------------------------------------------- Output : --------------------------------------------------------------------------------------------- end time : 3010064297 0 5277333961 --------------------------------------------------------------------------------------------- This message posted from opensolaris.org