add macOS ProcessData

This commit is contained in:
Evan Burkey 2023-12-28 12:28:13 -08:00
parent 56f3a9b9bf
commit 637aa01364
5 changed files with 153 additions and 0 deletions

View File

@ -15,6 +15,7 @@ set(SOURCES
src/string.c
src/vector.c
src/utility.c
src/macos.c
)
add_library(flint ${SOURCES})

63
docs/macos.md Normal file
View File

@ -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);
```

23
include/lfmacos.h Normal file
View File

@ -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 */

43
src/macos.c Normal file
View File

@ -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;
}

View File

@ -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;
}