add macOS ProcessData
This commit is contained in:
parent
56f3a9b9bf
commit
637aa01364
|
@ -15,6 +15,7 @@ set(SOURCES
|
|||
src/string.c
|
||||
src/vector.c
|
||||
src/utility.c
|
||||
src/macos.c
|
||||
)
|
||||
|
||||
add_library(flint ${SOURCES})
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
# macOS
|
||||
|
||||
Platform-specific code for macOS. Everything in this library, including the headers, is wrapped in the following
|
||||
preprocessor macro
|
||||
|
||||
```c
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
/*
|
||||
... code ...
|
||||
*/
|
||||
#endif /* defined(__APPLE__) || defined(__MACH__) */
|
||||
```
|
||||
|
||||
## Structs
|
||||
|
||||
### ProcessData
|
||||
|
||||
ProcessData is a struct that tracks cpu and memory usage of a process. It needs to be regularly updated with calls to
|
||||
`update_process()` in order to provide accurate information
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
double total_user_time;
|
||||
double total_kernel_time;
|
||||
double last_total_consumed;
|
||||
double percent_cpu;
|
||||
|
||||
uint64_t virtual_memory;
|
||||
uint64_t resident_memory;
|
||||
|
||||
time_t timestamp;
|
||||
time_t last_timestamp;
|
||||
} ProcessData;
|
||||
```
|
||||
|
||||
## Functions
|
||||
|
||||
## new_ProcessData
|
||||
|
||||
Returns a pointer to a `ProcessData` struct.
|
||||
|
||||
```c
|
||||
ProcessData *new_ProcessData();
|
||||
```
|
||||
|
||||
## update_process
|
||||
|
||||
Updates a `ProcessData` struct. This should be called in a loop or at specific intervals to measure proper usage
|
||||
data. An example is below
|
||||
|
||||
```c
|
||||
int update_process(pid_t pid, ProcessData *proc);
|
||||
|
||||
/* Example */
|
||||
pid_t pid = getpid();
|
||||
ProcessData *pd = new_ProcessData();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
update_process(pid, pd);
|
||||
printf("CPU: %.2f\n", pd->percent_cpu);
|
||||
sleep(1);
|
||||
}
|
||||
free(pd);
|
||||
```
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef LIBFLINT_MACOS_H
|
||||
#define LIBFLINT_MACOS_H
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
|
||||
typedef struct {
|
||||
double total_user_time;
|
||||
double total_kernel_time;
|
||||
double last_total_consumed;
|
||||
double percent_cpu;
|
||||
|
||||
uint64_t virtual_memory;
|
||||
uint64_t resident_memory;
|
||||
|
||||
time_t timestamp;
|
||||
time_t last_timestamp;
|
||||
} ProcessData;
|
||||
|
||||
ProcessData *new_ProcessData();
|
||||
int update_process(pid_t pid, ProcessData *proc);
|
||||
|
||||
#endif /* defined(__APPLE__) || defined(__MACH__) */
|
||||
#endif /* LIBFLINT_MACOS_H */
|
|
@ -0,0 +1,43 @@
|
|||
#include <libproc.h>
|
||||
#include <time.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "lfmacos.h"
|
||||
|
||||
ProcessData *new_ProcessData() {
|
||||
ProcessData *pd = malloc(sizeof(ProcessData));
|
||||
pd->last_total_consumed = -1.0;
|
||||
return pd;
|
||||
}
|
||||
|
||||
int update_process(pid_t pid, ProcessData *proc) {
|
||||
struct proc_taskinfo taskinfo;
|
||||
const int r = proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &taskinfo, PROC_PIDTASKINFO_SIZE);
|
||||
if (r != PROC_PIDTASKINFO_SIZE) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
mach_timebase_info_data_t info;
|
||||
mach_timebase_info(&info);
|
||||
const double ns_per_tick = (double)info.numer / (double)info.denom;
|
||||
|
||||
time(&(proc->timestamp));
|
||||
proc->total_kernel_time = (taskinfo.pti_total_system * ns_per_tick) / 1000000000.0;
|
||||
proc->total_user_time = (taskinfo.pti_total_user * ns_per_tick) / 1000000000.0;
|
||||
proc->virtual_memory = taskinfo.pti_virtual_size;
|
||||
proc->resident_memory = taskinfo.pti_resident_size;
|
||||
|
||||
if (proc->last_total_consumed > -1.0) {
|
||||
proc->percent_cpu = fabs(100.0 *
|
||||
(proc->total_user_time + proc->total_kernel_time - proc->last_total_consumed) /
|
||||
(proc->last_timestamp - proc->timestamp));
|
||||
} else {
|
||||
proc->percent_cpu = 0.0;
|
||||
}
|
||||
proc->last_timestamp = proc->timestamp;
|
||||
proc->last_total_consumed = proc->total_kernel_time + proc->total_user_time;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lflinkedlist.h"
|
||||
#include "lfset.h"
|
||||
|
@ -10,6 +11,10 @@
|
|||
#include "lfmath.h"
|
||||
#include "lfstring.h"
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
#include "lfmacos.h"
|
||||
#endif /* defined(__APPLE__) || defined(__MACH__) */
|
||||
|
||||
void print_ll(List *list) {
|
||||
LL_ITER(list) {
|
||||
printf(" %d", *((int *) node->data));
|
||||
|
@ -299,6 +304,19 @@ void test_string() {
|
|||
printf("Passes all string tests\n");
|
||||
}
|
||||
|
||||
void test_macos() {
|
||||
printf("\n--- macOS TEST ---\n");
|
||||
|
||||
pid_t pid = getpid();
|
||||
ProcessData *pd = new_ProcessData();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
update_process(pid, pd);
|
||||
printf("CPU: %.2f\n", pd->percent_cpu);
|
||||
sleep(1);
|
||||
}
|
||||
free(pd);
|
||||
}
|
||||
|
||||
int main() {
|
||||
test_ll();
|
||||
test_set();
|
||||
|
@ -307,5 +325,10 @@ int main() {
|
|||
test_math();
|
||||
test_vector();
|
||||
test_string();
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
test_macos();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue