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
> 


Reply via email to