32 #import <libproc.h> |
32 #import <libproc.h> |
33 #include <sys/time.h> |
33 #include <sys/time.h> |
34 #include <sys/sysctl.h> |
34 #include <sys/sysctl.h> |
35 #include <mach/mach.h> |
35 #include <mach/mach.h> |
36 #include <mach/task_info.h> |
36 #include <mach/task_info.h> |
|
37 #include <sys/socket.h> |
|
38 #include <net/if.h> |
|
39 #include <net/if_dl.h> |
|
40 #include <net/route.h> |
37 #endif |
41 #endif |
38 |
42 |
39 static const double NANOS_PER_SEC = 1000000000.0; |
43 static const double NANOS_PER_SEC = 1000000000.0; |
40 |
44 |
41 class CPUPerformanceInterface::CPUPerformance : public CHeapObj<mtInternal> { |
45 class CPUPerformanceInterface::CPUPerformance : public CHeapObj<mtInternal> { |
401 } |
405 } |
402 |
406 |
403 cpu_info = *_cpu_info; // shallow copy assignment |
407 cpu_info = *_cpu_info; // shallow copy assignment |
404 return OS_OK; |
408 return OS_OK; |
405 } |
409 } |
|
410 |
|
411 class NetworkPerformanceInterface::NetworkPerformance : public CHeapObj<mtInternal> { |
|
412 friend class NetworkPerformanceInterface; |
|
413 private: |
|
414 NetworkPerformance(); |
|
415 NetworkPerformance(const NetworkPerformance& rhs); // no impl |
|
416 NetworkPerformance& operator=(const NetworkPerformance& rhs); // no impl |
|
417 bool initialize(); |
|
418 ~NetworkPerformance(); |
|
419 int network_utilization(NetworkInterface** network_interfaces) const; |
|
420 }; |
|
421 |
|
422 NetworkPerformanceInterface::NetworkPerformance::NetworkPerformance() { |
|
423 } |
|
424 |
|
425 bool NetworkPerformanceInterface::NetworkPerformance::initialize() { |
|
426 return true; |
|
427 } |
|
428 |
|
429 NetworkPerformanceInterface::NetworkPerformance::~NetworkPerformance() { |
|
430 } |
|
431 |
|
432 int NetworkPerformanceInterface::NetworkPerformance::network_utilization(NetworkInterface** network_interfaces) const { |
|
433 size_t len; |
|
434 int mib[] = {CTL_NET, PF_ROUTE, /* protocol number */ 0, /* address family */ 0, NET_RT_IFLIST2, /* NET_RT_FLAGS mask*/ 0}; |
|
435 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &len, NULL, 0) != 0) { |
|
436 return OS_ERR; |
|
437 } |
|
438 uint8_t* buf = NEW_RESOURCE_ARRAY(uint8_t, len); |
|
439 if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &len, NULL, 0) != 0) { |
|
440 return OS_ERR; |
|
441 } |
|
442 |
|
443 size_t index = 0; |
|
444 NetworkInterface* ret = NULL; |
|
445 while (index < len) { |
|
446 if_msghdr* msghdr = reinterpret_cast<if_msghdr*>(buf + index); |
|
447 index += msghdr->ifm_msglen; |
|
448 |
|
449 if (msghdr->ifm_type != RTM_IFINFO2) { |
|
450 continue; |
|
451 } |
|
452 |
|
453 if_msghdr2* msghdr2 = reinterpret_cast<if_msghdr2*>(msghdr); |
|
454 sockaddr_dl* sockaddr = reinterpret_cast<sockaddr_dl*>(msghdr2 + 1); |
|
455 |
|
456 // The interface name is not necessarily NUL-terminated |
|
457 char name_buf[128]; |
|
458 size_t name_len = MIN2(sizeof(name_buf) - 1, static_cast<size_t>(sockaddr->sdl_nlen)); |
|
459 strncpy(name_buf, sockaddr->sdl_data, name_len); |
|
460 name_buf[name_len] = '\0'; |
|
461 |
|
462 uint64_t bytes_in = msghdr2->ifm_data.ifi_ibytes; |
|
463 uint64_t bytes_out = msghdr2->ifm_data.ifi_obytes; |
|
464 |
|
465 NetworkInterface* cur = new NetworkInterface(name_buf, bytes_in, bytes_out, ret); |
|
466 ret = cur; |
|
467 } |
|
468 |
|
469 *network_interfaces = ret; |
|
470 |
|
471 return OS_OK; |
|
472 } |
|
473 |
|
474 NetworkPerformanceInterface::NetworkPerformanceInterface() { |
|
475 _impl = NULL; |
|
476 } |
|
477 |
|
478 NetworkPerformanceInterface::~NetworkPerformanceInterface() { |
|
479 if (_impl != NULL) { |
|
480 delete _impl; |
|
481 } |
|
482 } |
|
483 |
|
484 bool NetworkPerformanceInterface::initialize() { |
|
485 _impl = new NetworkPerformanceInterface::NetworkPerformance(); |
|
486 return _impl != NULL && _impl->initialize(); |
|
487 } |
|
488 |
|
489 int NetworkPerformanceInterface::network_utilization(NetworkInterface** network_interfaces) const { |
|
490 return _impl->network_utilization(network_interfaces); |
|
491 } |