From a35591bbfce1c72cfc1108c35013adb55cabdbc1 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Sun, 2 Oct 2011 00:48:42 +0700 Subject: [PATCH] os: implement loadavg (not working on cygwin/win) --- include/uv.h | 3 +++ src/unix/cygwin.c | 5 +++++ src/unix/darwin.c | 14 ++++++++++++++ src/unix/freebsd.c | 12 ++++++++++++ src/unix/linux.c | 11 +++++++++++ src/unix/netbsd.c | 12 ++++++++++++ src/unix/sunos.c | 5 +++++ src/win/util.c | 5 +++++ test/test-get-loadavg.c | 36 ++++++++++++++++++++++++++++++++++++ test/test-list.h | 3 +++ uv.gyp | 1 + 11 files changed, 107 insertions(+) create mode 100644 test/test-get-loadavg.c diff --git a/include/uv.h b/include/uv.h index aad594e1..824b3c41 100644 --- a/include/uv.h +++ b/include/uv.h @@ -1044,6 +1044,9 @@ struct uv_fs_event_s { }; +/* Gets load avg */ +void uv_loadavg(double avg[3]); + /* * If filename is a directory then we will watch for all events in that * directory. If filename is a file - we will only get events from that diff --git a/src/unix/cygwin.c b/src/unix/cygwin.c index 418336d6..bafe83bf 100644 --- a/src/unix/cygwin.c +++ b/src/unix/cygwin.c @@ -36,6 +36,11 @@ uint64_t uv_hrtime() { return (ts.tv_sec * NANOSEC + ts.tv_nsec); } +void uv_loadavg(double avg[3]) { + /* Unsupported as of cygwin 1.7.7 */ + avg[0] = avg[1] = avg[2] = 0; +} + int uv_exepath(char* buffer, size_t* size) { uint32_t usize; diff --git a/src/unix/darwin.c b/src/unix/darwin.c index b912139e..26016569 100644 --- a/src/unix/darwin.c +++ b/src/unix/darwin.c @@ -30,6 +30,9 @@ #include #include /* _NSGetExecutablePath */ +#include +#include + uint64_t uv_hrtime() { uint64_t time; @@ -92,6 +95,17 @@ double uv_get_total_memory(void) { return (double) info; } +void uv_loadavg(double avg[3]) { + struct loadavg info; + size_t size = sizeof(info); + int which[] = {CTL_VM, VM_LOADAVG}; + + if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return; + + avg[0] = (double) info.ldavg[0] / info.fscale; + avg[1] = (double) info.ldavg[1] / info.fscale; + avg[2] = (double) info.ldavg[2] / info.fscale; +} int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle, diff --git a/src/unix/freebsd.c b/src/unix/freebsd.c index 9dbb2b31..e173fd83 100644 --- a/src/unix/freebsd.c +++ b/src/unix/freebsd.c @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -92,6 +93,17 @@ double uv_get_total_memory(void) { return (double) info; } +void uv_loadavg(double avg[3]) { + struct loadavg info; + size_t size = sizeof(info); + int which[] = {CTL_VM, VM_LOADAVG}; + + if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return; + + avg[0] = (double) info.ldavg[0] / info.fscale; + avg[1] = (double) info.ldavg[1] / info.fscale; + avg[2] = (double) info.ldavg[2] / info.fscale; +} int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle, diff --git a/src/unix/linux.c b/src/unix/linux.c index 0a176286..e37983d1 100644 --- a/src/unix/linux.c +++ b/src/unix/linux.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -52,6 +53,16 @@ uint64_t uv_hrtime() { return (ts.tv_sec * NANOSEC + ts.tv_nsec); } +void uv_loadavg(double avg[3]) { + struct sysinfo info; + + if (sysinfo(&info) < 0) return; + + avg[0] = (double) info.loads[0] / 65536.0; + avg[1] = (double) info.loads[1] / 65536.0; + avg[2] = (double) info.loads[2] / 65536.0; +} + int uv_exepath(char* buffer, size_t* size) { if (!buffer || !size) { diff --git a/src/unix/netbsd.c b/src/unix/netbsd.c index 5db3285c..37bb87ee 100644 --- a/src/unix/netbsd.c +++ b/src/unix/netbsd.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -40,6 +41,17 @@ uint64_t uv_hrtime(void) { return (ts.tv_sec * NANOSEC + ts.tv_nsec); } +void uv_loadavg(double avg[3]) { + struct loadavg info; + size_t size = sizeof(info); + int which[] = {CTL_VM, VM_LOADAVG}; + + if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return; + + avg[0] = (double) info.ldavg[0] / info.fscale; + avg[1] = (double) info.ldavg[1] / info.fscale; + avg[2] = (double) info.ldavg[2] / info.fscale; +} int uv_exepath(char* buffer, size_t* size) { uint32_t usize; diff --git a/src/unix/sunos.c b/src/unix/sunos.c index ecfdbf7d..554f15cd 100644 --- a/src/unix/sunos.c +++ b/src/unix/sunos.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -93,6 +94,10 @@ double uv_get_total_memory(void) { return (double) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES); } +void uv_loadavg(double avg[3]) { + (void) getloadavg(avg, 3); +} + int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle, diff --git a/src/win/util.c b/src/win/util.c index 5db0ad78..cb2d4438 100644 --- a/src/win/util.c +++ b/src/win/util.c @@ -95,6 +95,11 @@ done: return retVal; } +void uv_loadavg(double avg[3]) { + /* Can't be implemented */ + avg[0] = avg[1] = avg[2] = 0; +} + double uv_get_free_memory(void) { MEMORYSTATUSEX memory_status; memory_status.dwLength = sizeof(memory_status); diff --git a/test/test-get-loadavg.c b/test/test-get-loadavg.c new file mode 100644 index 00000000..7465e18b --- /dev/null +++ b/test/test-get-loadavg.c @@ -0,0 +1,36 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +TEST_IMPL(get_loadavg) { + + double avg[3]; + uv_loadavg(avg); + + ASSERT(avg != NULL); + ASSERT(avg[0] >= 0); + ASSERT(avg[1] >= 0); + ASSERT(avg[2] >= 0); + + return 0; +} diff --git a/test/test-list.h b/test/test-list.h index 4ff07bd4..f137493b 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -61,6 +61,7 @@ TEST_DECLARE (idle_starvation) TEST_DECLARE (loop_handles) TEST_DECLARE (ref) TEST_DECLARE (idle_ref) +TEST_DECLARE (get_loadavg) TEST_DECLARE (async_ref) TEST_DECLARE (prepare_ref) TEST_DECLARE (check_ref) @@ -188,6 +189,8 @@ TASK_LIST_START TEST_ENTRY (get_memory) + TEST_ENTRY (get_loadavg) + TEST_ENTRY (hrtime) TEST_ENTRY (getaddrinfo_basic) diff --git a/uv.gyp b/uv.gyp index 02fadbd3..5bf8c065 100644 --- a/uv.gyp +++ b/uv.gyp @@ -241,6 +241,7 @@ 'test/run-tests.c', 'test/runner.c', 'test/runner.h', + 'test/test-get-loadavg.c', 'test/task.h', 'test/test-async.c', 'test/test-callback-stack.c',