Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
platform api
Browse files Browse the repository at this point in the history
  • Loading branch information
Igor Zinkovsky committed Dec 15, 2011
1 parent 12cc4f7 commit 3d189de
Show file tree
Hide file tree
Showing 14 changed files with 1,691 additions and 5 deletions.
43 changes: 43 additions & 0 deletions include/uv.h
Expand Up @@ -177,6 +177,8 @@ typedef struct uv_async_s uv_async_t;
typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
typedef struct uv_process_s uv_process_t;
typedef struct uv_counters_s uv_counters_t;
typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
/* Request types */
typedef struct uv_req_s uv_req_t;
typedef struct uv_shutdown_s uv_shutdown_t;
Expand Down Expand Up @@ -1036,7 +1038,48 @@ UV_EXTERN int uv_queue_work(uv_loop_t* loop, uv_work_t* req,
uv_work_cb work_cb, uv_after_work_cb after_work_cb);


struct uv_cpu_info_s {
char* model;
int speed;
struct uv_cpu_times_s {
uint64_t user;
uint64_t nice;
uint64_t sys;
uint64_t idle;
uint64_t irq;
} cpu_times;
};

struct uv_interface_address_s {
char* name;
int is_internal;
union {
struct sockaddr_in address4;
struct sockaddr_in6 address6;
} address;
};

UV_EXTERN char** uv_setup_args(int argc, char** argv);
UV_EXTERN uv_err_t uv_get_process_title(char* buffer, size_t size);
UV_EXTERN uv_err_t uv_set_process_title(const char* title);
UV_EXTERN uv_err_t uv_resident_set_memory(size_t* rss);
UV_EXTERN uv_err_t uv_uptime(double* uptime);

/*
* This allocates cpu_infos array, and sets count. The array
* is freed using uv_free_cpu_info().
*/
UV_EXTERN uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);

/*
* This allocates addresses array, and sets count. The array
* is freed using uv_free_interface_addresses().
*/
UV_EXTERN uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
int* count);
UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count);

/*
* File System Methods.
Expand Down
212 changes: 212 additions & 0 deletions src/unix/darwin.c
Expand Up @@ -25,6 +25,9 @@
#include <stdint.h>
#include <errno.h>

#include <ifaddrs.h>
#include <net/if.h>

#include <CoreServices/CoreServices.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
Expand All @@ -34,6 +37,9 @@
#include <unistd.h> /* sysconf */


static char *process_title;


uint64_t uv_hrtime() {
uint64_t time;
Nanoseconds enano;
Expand Down Expand Up @@ -71,6 +77,7 @@ int uv_exepath(char* buffer, size_t* size) {
return 0;
}


uint64_t uv_get_free_memory(void) {
vm_statistics_data_t info;
mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t);
Expand All @@ -83,6 +90,7 @@ uint64_t uv_get_free_memory(void) {
return (uint64_t) info.free_count * sysconf(_SC_PAGESIZE);
}


uint64_t uv_get_total_memory(void) {
uint64_t info;
int which[] = {CTL_HW, HW_MEMSIZE};
Expand All @@ -95,6 +103,7 @@ uint64_t uv_get_total_memory(void) {
return (uint64_t) info;
}


void uv_loadavg(double avg[3]) {
struct loadavg info;
size_t size = sizeof(info);
Expand All @@ -106,3 +115,206 @@ void uv_loadavg(double avg[3]) {
avg[1] = (double) info.ldavg[1] / info.fscale;
avg[2] = (double) info.ldavg[2] / info.fscale;
}


char** uv_setup_args(int argc, char** argv) {
process_title = argc ? strdup(argv[0]) : NULL;
return argv;
}


uv_err_t uv_set_process_title(const char* title) {
/* TODO implement me */
return uv__new_artificial_error(UV_ENOSYS);
}


uv_err_t uv_get_process_title(char* buffer, size_t size) {
if (process_title) {
strncpy(buffer, process_title, size);
} else {
if (size > 0) {
buffer[0] = '\0';
}
}

return uv_ok_;
}


uv_err_t uv_resident_set_memory(size_t* rss) {
struct task_basic_info t_info;
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;

int r = task_info(mach_task_self(),
TASK_BASIC_INFO,
(task_info_t)&t_info,
&t_info_count);

if (r != KERN_SUCCESS) {
return uv__new_sys_error(errno);
}

*rss = t_info.resident_size;

return uv_ok_;
}


uv_err_t uv_uptime(double* uptime) {
time_t now;
struct timeval info;
size_t size = sizeof(info);
static int which[] = {CTL_KERN, KERN_BOOTTIME};

if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
return uv__new_sys_error(errno);
}
now = time(NULL);

*uptime = (double)(now - info.tv_sec);

return uv_ok_;
}

uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK),
multiplier = ((uint64_t)1000L / ticks);
char model[512];
uint64_t cpuspeed;
size_t size;
unsigned int i;
natural_t numcpus;
mach_msg_type_number_t msg_type;
processor_cpu_load_info_data_t *info;
uv_cpu_info_t* cpu_info;

size = sizeof(model);
if (sysctlbyname("hw.model", &model, &size, NULL, 0) < 0) {
return uv__new_sys_error(errno);
}
size = sizeof(cpuspeed);
if (sysctlbyname("hw.cpufrequency", &cpuspeed, &size, NULL, 0) < 0) {
return uv__new_sys_error(errno);
}

if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus,
(processor_info_array_t*)&info,
&msg_type) != KERN_SUCCESS) {
return uv__new_sys_error(errno);
}

*cpu_infos = (uv_cpu_info_t*)malloc(numcpus * sizeof(uv_cpu_info_t));
if (!(*cpu_infos)) {
return uv__new_artificial_error(UV_ENOMEM);
}

*count = numcpus;

for (i = 0; i < numcpus; i++) {
cpu_info = &(*cpu_infos)[i];

cpu_info->cpu_times.user = (uint64_t)(info[i].cpu_ticks[0]) * multiplier;
cpu_info->cpu_times.nice = (uint64_t)(info[i].cpu_ticks[3]) * multiplier;
cpu_info->cpu_times.sys = (uint64_t)(info[i].cpu_ticks[1]) * multiplier;
cpu_info->cpu_times.idle = (uint64_t)(info[i].cpu_ticks[2]) * multiplier;
cpu_info->cpu_times.irq = 0;

cpu_info->model = strdup(model);
cpu_info->speed = cpuspeed/1000000;
}
vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type);

return uv_ok_;
}


void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
int i;

for (i = 0; i < count; i++) {
free(cpu_infos[i].model);
}

free(cpu_infos);
}


uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
int* count) {
struct ifaddrs *addrs, *ent;
char ip[INET6_ADDRSTRLEN];
uv_interface_address_t* address;

if (getifaddrs(&addrs) != 0) {
return uv__new_sys_error(errno);
}

*count = 0;

/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
(ent->ifa_addr == NULL) ||
(ent->ifa_addr->sa_family == AF_LINK)) {
continue;
}

(*count)++;
}

*addresses = (uv_interface_address_t*)
malloc(*count * sizeof(uv_interface_address_t));
if (!(*addresses)) {
return uv__new_artificial_error(UV_ENOMEM);
}

address = *addresses;

for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
bzero(&ip, sizeof (ip));
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
continue;
}

if (ent->ifa_addr == NULL) {
continue;
}

/*
* On Mac OS X getifaddrs returns information related to Mac Addresses for
* various devices, such as firewire, etc. These are not relevant here.
*/
if (ent->ifa_addr->sa_family == AF_LINK) {
continue;
}

address->name = strdup(ent->ifa_name);

if (ent->ifa_addr->sa_family == AF_INET6) {
address->address.address6 = *((struct sockaddr_in6 *)ent->ifa_addr);
} else {
address->address.address4 = *((struct sockaddr_in *)ent->ifa_addr);
}

address->is_internal = ent->ifa_flags & IFF_LOOPBACK ? 1 : 0;

address++;
}

freeifaddrs(addrs);

return uv_ok_;
}


void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
int i;

for (i = 0; i < count; i++) {
free(addresses[i].name);
}

free(addresses);
}

3 comments on commit 3d189de

@jedisct1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libuv doesn't compile any more on BSD after this patch.

@igorzi
Copy link

@igorzi igorzi commented on 3d189de Dec 15, 2011

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jedisct1 can you please provide the list of compile errors? or a patch with fixes?

@okuoku
Copy link
Contributor

@okuoku okuoku commented on 3d189de Dec 15, 2011

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed as #280.

Please sign in to comment.