Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I retrieve the following processor stats?

How can I retrieve:

i) Number of total processes ii) Number of total threads

Note by "total" I mean the total number in use not the total supported by the system.

I am specifically asking for an Objective-C/C solution on OSX.

like image 962
fdh Avatar asked Aug 14 '12 23:08

fdh


People also ask

How do I find my processor details?

If the Windows key is not available on your keyboard, using your mouse, go to the Windows icon located on the bottom-left corner of your screen, right-click, and choose System. Look up the processor's name and number in the Processor information.

How can I see my processor in CMD?

Method 1: Use the set command To use the set command to determine the processor type, follow these steps: Click Start, click Run, type cmd in the Open box, and then press ENTER. At the command prompt, type set, and then press ENTER. Note the string that is displayed next to PROCESSOR_IDENTIFIER.

How many Ghz is my processor?

If you're wondering how to check your clock speed, click the Start menu (or click the Windows* key) and type “System Information.” Your CPU's model name and clock speed will be listed under “Processor”.


2 Answers

You can use top and scrape what you're looking for, but I was curious so I dug a bit deeper and found /usr/include/libproc.h, and wrote some code:

#import <libproc.h>
#import <stdlib.h>
#import <stdio.h>

int main( int argc, const char * argv[])
{
    pid_t * pids = calloc(0x1000, 1);
    int count = proc_listallpids(pids, 0x1000);

    printf("count=%u\n", count) ;

    for( int index=0; index < count; ++index)
    {
        pid_t pid = pids[ index ] ;

        struct proc_taskinfo taskInfo ;
        /*int result*/ proc_pidinfo( pid, PROC_PIDTASKINFO, 0,  & taskInfo, sizeof( taskInfo ) ) ;

        // fields of taskInfo:
//          uint64_t        pti_virtual_size;   /* virtual memory size (bytes) */
//          uint64_t        pti_resident_size;  /* resident memory size (bytes) */
//          uint64_t        pti_total_user;     /* total time */
//          uint64_t        pti_total_system;
//          uint64_t        pti_threads_user;   /* existing threads only */
//          uint64_t        pti_threads_system;
//          int32_t         pti_policy;     /* default policy for new threads */
//          int32_t         pti_faults;     /* number of page faults */
//          int32_t         pti_pageins;        /* number of actual pageins */
//          int32_t         pti_cow_faults;     /* number of copy-on-write faults */
//          int32_t         pti_messages_sent;  /* number of messages sent */
//          int32_t         pti_messages_received;  /* number of messages received */
//          int32_t         pti_syscalls_mach;  /* number of mach system calls */
//          int32_t         pti_syscalls_unix;  /* number of unix system calls */
//          int32_t         pti_csw;            /* number of context switches */
//          int32_t         pti_threadnum;      /* number of threads in the task */
//          int32_t         pti_numrunning;     /* number of running threads */
//          int32_t         pti_priority;       /* task priority*/

        printf("PID %u:\n", pid);
        printf("\t%20s\t%u\n", "number of threads", taskInfo.pti_threadnum) ;
        printf("\t%20s\t%u\n", "number running threads", taskInfo.pti_numrunning) ;

        printf("\n") ;
    }

    return EXIT_SUCCESS ;
}
like image 134
nielsbot Avatar answered Oct 24 '22 17:10

nielsbot


Following, roughly, the source code for top(1), this works when run as root:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <mach/mach_vm.h>
#include <mach/task.h>

kern_return_t get_process_thread_count(long *process_count, long *thread_count) {
    kern_return_t   kr;
    processor_set_name_array_t psets;
    processor_set_t pset;
    task_array_t tasks;
    mach_msg_type_number_t  i, j, k, iCount, jCount, kCount;
    long process_accumulator = 0, thread_accumulator = 0;
    mach_port_t host_self = mach_host_self();
    mach_port_t task_self = mach_task_self();
    thread_act_array_t threads;
    int pid;

    if ((kr = host_processor_sets(host_self, &psets, &iCount))) return kr;
    for (i = 0; i < iCount; ++i) {
        if ((kr = host_processor_set_priv(host_self, psets[i], &pset))) return kr;
        if ((kr = processor_set_tasks(pset, &tasks, &jCount))) return kr;
        for (j = 0; j < jCount; ++j) {
            if ((kr = pid_for_task(tasks[j], &pid))) return kr;
            if (pid != 0) {
                /* then the Mach task maps to a BSD process, so */ 
                ++process_accumulator;
                if ((kr = task_threads(tasks[j], &threads, &kCount))) return kr;
                thread_accumulator += kCount;
                for (k = 0; k < kCount; ++k) {
                    if ((kr = mach_port_deallocate(task_self, threads[k]))) return kr;
                }
                if ((kr = mach_vm_deallocate(task_self,
                                             (mach_vm_address_t)(uintptr_t)threads,
                                             kCount * sizeof(*threads)))) return kr;
            }
            if ((kr = mach_port_deallocate(task_self, tasks[j]))) return kr;
        }
        if ((kr = mach_vm_deallocate(task_self,
                                     (mach_vm_address_t)(uintptr_t)tasks,
                                     kCount * sizeof(*tasks)))) return kr;
        if ((kr = mach_port_deallocate(task_self, psets[j]))) return kr;
    }
    if ((kr = mach_vm_deallocate(task_self,
                                 (vm_address_t)psets,
                                 iCount * sizeof(*psets)))) return kr;
    *process_count = process_accumulator;
    *thread_count = thread_accumulator;
    return KERN_SUCCESS;
}

int main(int argc, char* argv[]) {
    long process_count, thread_count;
    kern_return_t r;
    if ((r = get_process_thread_count(&process_count, &thread_count))) {
        mach_error("get_process_thread_count error: ", r);
        return 1;
    };
    printf("%ld processes, %ld threads\n", process_count, thread_count);
    return 0;
}

Obtaining information about all processes on the system requires elevated privileges, so if you need to do this as an unprivileged user, calling top or ps via NSTask is probably a better option, as they're already setuid root.

Final note: as (lazily) written, this code leaks both memory and Mach ports on failure.

like image 41
Jason T. Miller Avatar answered Oct 24 '22 18:10

Jason T. Miller