Exemple #1
0
void cl_net_stats(void)
{
    static vector_t NS; /* Network stats */
    static time_t t_last;

    time_t t_now;

    t_now = time(NULL);
    /* Only update net stats once a second */
    if( t_now != t_last ) {
	t_last = t_now;
	NS = net_stats(server, client.netstats);
    }
    draw_netstats(NS);

}
Exemple #2
0
int main (int argc, char* argv[]) {
    
    mach_msg_type_number_t  actListCnt;
    thread_act_array_t      actList;
    double                  cpuTime;
    kern_return_t           kr;
    int                     i;
    char                    *procName;
    float                   scaledUsage;
    task_t                  task = 0;
    pid_t                   pid = -1;
    thread_basic_info_t     tbi;
    thread_basic_info_data_t tbiData;
    double                  waitSeconds = 0.0;
    struct timespec         tv;

    
    // Setup a Ctrl-C handler.
    //act.sa_handler = intHandler;
    //sigaction(SIGINT, &act, NULL);

    //
    // PARSE PARAMETERS
    //
    
    while ((i = getopt(argc, argv, "dn:p:vw:")) != -1) {
        
        switch (i) {

            case 'd':
                gFmpFormat = true;
                break;

            case 'h':
                print_usage();
                break;
            case 'n':
                procName = optarg;
                //printf ("Name: %s\n", procName);
                pid = get_pid_for_process(procName);
                break;

            case 'p':
                pid = atoi (optarg);
                break;

            case 'v':
                gVerbose = true;
                break;

            case 'w':
                //printf ("Wait: %s\n", argv[i+1]);
                waitSeconds = atof (optarg);
                
                if (waitSeconds <= 0.0)
                    waitSeconds = 0.0;
                if (waitSeconds > 0.0 && waitSeconds < 0.1)
                    waitSeconds = 0.1;
                break;

            default:
                printf ("Invalid arguments, please try again.\n");
                print_usage();
                exit(1);
                break;
        }
    }

    if (gVerbose) {
        print_verbose_info();
    }
    
    //printf ("PID: %i\n", pid);

    if (pid < 1) {
        printf ("No process found, please try again.\n");
        print_usage();
        return 1;
    }

    if (waitSeconds > 0.0) {
        /* Construct the timespec from the number of whole seconds...  */
        tv.tv_sec = (time_t) waitSeconds;
        /* ... and the remainder in nanoseconds.  */
        tv.tv_nsec = (long) ((waitSeconds - tv.tv_sec) * 1e+9);
    } else {
        // Default time if none specified.
        tv.tv_sec = (time_t) 1;
        tv.tv_nsec = 0;
    }
    
    //
    //  GET PROCESS INFO
    //
    
    task_basic_info_data_t basic_info;
    mach_msg_type_number_t count;

    // Get port for accessing system CPU stats.
	gHostPort = mach_host_self();
    
    do {

        // Need to load the task number?
        if (task == 0 && pid > 0) {
            if ((kr = task_for_pid(mach_task_self(), pid, &task)) != KERN_SUCCESS) {
                mach_error("processdetail", kr);
                perror ("Could not get Mach task for pid. Did you run with sudo?\n");
                exit (1);
            }
            
        }
        
        count = TASK_BASIC_INFO_COUNT;
        
        if ((kr = task_info(task, TASK_BASIC_INFO,
                            (task_info_t)&basic_info, &count)) != KERN_SUCCESS) {
                        
            if (gHasRunOnce && procName != NULL) {
                // We found the process originally, so we'll wait the regular interval and
                // see if the process restarts.
                gKeepRunning = nanosleep(&tv, NULL) == 0;
                if (!gKeepRunning) printf ("\n"); // Return after Ctrl-C
                
                pid = get_pid_for_process(procName);
                
                // Force the task number to be reloaded.
                task = 0;
                
                continue;
                
            } else {
                // Shouldn't happen unless process died in between getting pid and here.
                perror ("Process being monitored died!?\n");
                mach_error("processdetail", kr);
                exit(1);
            }
        }
        
        if (count != TASK_BASIC_INFO_COUNT) {
            fprintf(stderr, "size mismatch");
            exit(1);
        }
    
        // CPU STATS
        
        cpuTime = cpu_statistics();
        
        // NET STATS
        
        if (net_stats() != 0) {
            perror ("Error getting network stats");
            exit (1);
        }
        
         // There is a wait interval and this is the very first run?
        if (gHasRunOnce == false) {
            // Skip printing until we have a full interval.
            // We can then give difference between before & after.
            gHasRunOnce = true;
            
            // Update values but don't print.
            net_print_stats(false);
            
            gKeepRunning = nanosleep(&tv, NULL) == 0;
            if (!gKeepRunning) printf ("\n");
            continue;
        }

        //
        //  PRINT SYSTEM STATS
        //
        
        print_timestamp();
        
        cpu_print_statistics(cpuTime);
        
        net_print_stats(true);
        
        //
        //  PRINT PROCESS SPECIFIC STATS
        //
        
        if (gFmpFormat) {
            printf ("$pd.pid=%i;\n$pd.vmsize=%li;\n$pd.residentmemory=%li;\n", pid, basic_info.virtual_size,basic_info.resident_size);
        } else {
            printf ("%i, %li, %li, ", pid, basic_info.virtual_size,basic_info.resident_size);
            //printf("Suspend count: %d\n", basic_info.suspend_count);
        }
        
        task_events_info_data_t events_info;
        
        if ((kr = task_info(task, TASK_EVENTS_INFO,
                            (task_info_t)&events_info, &count)) != KERN_SUCCESS) {
            mach_error("processdetail", kr);
            exit(1);
        }
        if (count != TASK_EVENTS_INFO_COUNT) {
            fprintf(stderr, "size mismatch");
            exit(1);
        }
        
        if (gFmpFormat) {
            printf ("$pd.pagefaults=%d;\n$pd.pageins=%d;\n$pd.copyonwritefaults=%d;\n", events_info.faults, events_info.pageins, events_info.cow_faults);
        } else {
            //printf("Page faults: %d\n", events_info.faults);
            printf("%d, ", events_info.faults);
            //printf("Pageins: %d\n", events_info.pageins);
            printf("%d, ", events_info.pageins);
            //printf("Copy-on-write faults: %d\n", events_info.cow_faults);
            printf("%d, ", events_info.cow_faults);
            //printf("Messages sent: %d\n", events_info.messages_sent);
            //printf("Messages received: %d\n", events_info.messages_received);
            //printf("Mach system calls: %d\n", events_info.syscalls_mach);
            //printf("Unix system calls: %d\n", events_info.syscalls_unix);
            //printf("Context switches: %d\n", events_info.csw);
        }
        
        if (gFmpFormat) {
            switch (basic_info.policy) {
                case THREAD_STANDARD_POLICY:
                    printf("$pd.threadpolicy=Standard;\n");
                    break;
                case THREAD_TIME_CONSTRAINT_POLICY:
                    printf("$pd.threadpolicy=\"Time Constraint\";\n");
                    break;
                case THREAD_PRECEDENCE_POLICY:
                    printf("$pd.threadpolicy=Precendence;\n");
                    break;
                default:
                    printf("$pd.threadpolicy=Unknown;\n");
                    break;
            }
    
        } else {
            switch (basic_info.policy) {
                case THREAD_STANDARD_POLICY:
                    printf("Standard, ");
                    break;
                case THREAD_TIME_CONSTRAINT_POLICY:
                    printf("\"Time Constraint\", ");
                    break;
                case THREAD_PRECEDENCE_POLICY:
                    printf("Precendence, ");
                    break;
                default:
                    printf("Unknown, ");
                    break;
            }
        }

        kr = task_threads (task, &actList, &actListCnt);
        if (kr != KERN_SUCCESS) {
            fprintf(stderr, "task_threads failed");
            exit (1);
        }
        
        if (gFmpFormat) {
            printf ("$td.threadcount=%i;\n", actListCnt);
        } else {
            printf ("%i, ", actListCnt);
        }

        mach_msg_type_number_t threadInfoCnt;
        float cpuUsage;
        
        
        /*
        
         Never a pthread (!?) so this doesn't work.
        for (int i = 0; i < actListCnt; ++i) {
            pthread_t pt = pthread_from_mach_thread_np(actList[i]);
            if (pt) {
                name[0] = '\0';
                int rc = pthread_getname_np(pt, name, sizeof name);
                printf("mach thread %u: getname returned %d: %s\n", actList[i], rc, name);
            } else {
                printf("mach thread %u: no pthread found\n", actList[i]);
            }
        }
    */


        tbi = &tbiData;
        cpuUsage = 0.0;
        
        for (i = 0; i < actListCnt; i++) {
            threadInfoCnt = THREAD_BASIC_INFO_COUNT;
            kr = thread_info(
                             actList[i],                            //thread_act_t target_act
                             THREAD_BASIC_INFO,                     //thread_flavor_t flavor
                             (thread_info_t) tbi,                   //thread_info_t thread_info_out
                             &threadInfoCnt);                       //mach_msg_type_number_t *thread_info_outCnt

            
            cpuUsage += tbi->cpu_usage;
            //printf ("CPU Usage: %i\n", tbi->cpu_usage);
            scaledUsage = tbi->cpu_usage / (float)TH_USAGE_SCALE * 100.0;
            
            if (gFmpFormat) {
                printf ("$pd.threadcpu[%i]=%.2f;\n", i+1, scaledUsage);
            } else {
                printf ("%.2f, ", scaledUsage);
            }
        }

        if (gFmpFormat) {
            printf ("$pd.totalcpu=%.2f\n\n", cpuUsage / (float)TH_USAGE_SCALE * 100.0);
        } else {
            printf ("%.2f\n", cpuUsage / (float)TH_USAGE_SCALE * 100.0);
        }
        
        // If user is tailing the piped result we want them to see results quickly.
        fflush (stdout);
        
        // We've done the whole process at least once.
        gHasRunOnce = true;
        
        if (waitSeconds != 0.0) {
            gKeepRunning = nanosleep(&tv, NULL) == 0;
        } else {
            gKeepRunning = false;
        }
        
    } while (gKeepRunning);
    
    return 0;
    
}