What about to allow users to set what cpu they want to graph?
So I can have 2 plug-ins on panel, for 2 cores. And I can see
how they share the load ;-)
Petr
P.S.: Good work Doug.
Doug Scott napsal(a):
> James C. McPherson wrote:
>> Doug Scott wrote:
>>> The patch in xfce-goodies has now been updated. I have been running
>>> the cpugraph on my machine for a few hours now and the memory usage
>>> has not changed. Also, it "should" now support changing the number of
>>> CPU's in your machine. It should have segfaulted before if you added
>>> more physical CPU's. Sorry I can not test that on my machine :(
>>
>>
>> Hi Doug,
>> do you mind telling us what the problem was?
> My bad actually :)
>
> Previously, every time GetCPUUsage is called a malloc of the "new"
> array was never freed. It must have been late at night when I wrote the
> Solaris code (and just happy it worked). Also both the old and new
> arrays of cpu_time_t would never be increased or decreased with any
> change in the number of cpu's from the sysconf(_SC_CPUID_MAX) call.
> Therefore if you dynamically added more CPU's the code would try to
> access past the end of the array. I really think this would only be a
> problem with Sun Ray's connected to a domain capable server.
>
> Since Solaris does not seem to have anywhere that you can get a single
> average CPU usage across all online CPU's (linux you can just read
> /proc/stat I think). The code I wrote uses values (cpu ticks) from
> kstat, subtracts from the previous and computes the average within the
> code.
>
> Below is a very cutdown snip of the offending code. Below that is the
> current Solaris section of the os.c file.
>
> Doug
>
> -----------Before (cutdown)----------------------------
> typedef struct cpu_time {
> uint64_t stat[NUM_STATS];
> } cpu_time_t;
>
> static cpu_time_t *old=(cpu_time_t *)NULL;
>
> long GetCPUUsage (int *oldusage, int *oldtotal){
> cpu_time_t *new;
> .
> .
> .
> new=calloc(sizeof(cpu_time_t),ncpu); // ^---- Do not Free!!
> .
> .
> .
> }
>
> ---------- After Complete Solaris code ---------------
>
> #elif defined (sun)
> /*
> For Solaris we need to get the cpu stats from kstat for each CPU.
> We then return the average usage of all valid CPU's
> */
>
> #define NUM_STATS 4
>
> /*
> Probably should ignore cpu_ticks_wait on Solaris 10+ as it is always 0
> */
>
> char *stat_id[] = {
> "cpu_ticks_idle",
> "cpu_ticks_kernel",
> "cpu_ticks_user",
> "cpu_ticks_wait"
> };
>
> typedef struct cpu_time {
> uint64_t stat[NUM_STATS];
> } cpu_time_t;
>
> static cpu_time_t *old=(cpu_time_t *)NULL;
> static cpu_time_t *new=(cpu_time_t *)NULL;
> static kstat_ctl_t *kc=NULL;
>
> /*
>
> With Solaris cpu's can be enable and disabled at any time. Some systems
> the CPU's are hot-plugable. Therefore every time we need to check to see
> if a change has been made, and adjust the data structure accordingly.
> */
>
> static int last_ncpu=-1;
>
> long GetCPUUsage (int *oldusage, int *oldtotal)
> {
> uint64_t total;
> uint64_t busy;
> uint64_t ticks;
> uint64_t usage;
> int ncpu;
> int i;
> int j;
> int cnt=0;
> int sum=0;
>
> ncpu = (int)sysconf(_SC_CPUID_MAX);
> if (ncpu!=last_ncpu){
> if (old!=(cpu_time_t *)NULL) free(old);
> if (new!=(cpu_time_t *)NULL) free(new);
> }
>
> /*
> Initiallize old structure if first time round, or if the
> number of CPU's has changed.
> */
> if (old==(cpu_time_t *)NULL){
> old=calloc(sizeof(cpu_time_t),ncpu);
> for (i=0;i<ncpu;i++){
> for (j=0;j<NUM_STATS;j++){
> old[i].stat[j]=0;
> }
> }
> }
>
> /*
> Only allocate a new structure if this is the first time
> or the number of CPU's has changed.
> */
> if (new==(cpu_time_t *)NULL){
> new=calloc(sizeof(cpu_time_t),ncpu);
> }
>
> if (kc==(kstat_ctl_t *)NULL){
> kc = (kstat_ctl_t *)kstat_open();
> }
> for (i=0;i<ncpu;i++) {
> kstat_t *ksp;
> kstat_named_t *knp;
>
> ksp = kstat_lookup(kc, "cpu", i, "sys");
>
> /* No CPU in this slot, then look at the next one */
> if (p_online(i, P_STATUS)==-1) continue;
>
> kstat_read(kc, ksp, NULL);
> for (j=0;j<NUM_STATS;j++){
> knp = kstat_data_lookup(ksp, stat_id[j]);
> ticks = (uint64_t)knp->value.ui64;
> if (last_ncpu!=ncpu){
> old[i].stat[j]=ticks;
> new[i].stat[j]=0;
> } else {
> uint64_t store_ticks=ticks;
> ticks=ticks - old[i].stat[j];
> old[i].stat[j]=store_ticks;
> new[i].stat[j]=ticks;
> }
> }
> /* busy = kernel + user + wait */
> busy = new[i].stat[1] + new[i].stat[2] + new[i].stat[3];
> /* total = busy + idle */
> total = new[i].stat[0] + busy;
> if (total!=0){
> usage = busy*100/total;
> } else {
> usage=0;
> }
> cnt++;
> sum=sum+usage;
> }
> last_ncpu=ncpu;
> if (cnt==0){
> return(0);
> } else {
> return(sum/cnt);
> }
> }
> #else
> #error "You're OS is not supported."
> #endif
> _______________________________________________
> desktop-discuss mailing list
> desktop-discuss at opensolaris.org
>