Mercurial
comparison third_party/libuv/src/unix/netbsd.c @ 160:948de3f54cea
[ThirdParty] Added libuv
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 14 Jan 2026 19:39:52 -0800 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 159:05cf9467a1c3 | 160:948de3f54cea |
|---|---|
| 1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved. | |
| 2 * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 3 * of this software and associated documentation files (the "Software"), to | |
| 4 * deal in the Software without restriction, including without limitation the | |
| 5 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |
| 6 * sell copies of the Software, and to permit persons to whom the Software is | |
| 7 * furnished to do so, subject to the following conditions: | |
| 8 * | |
| 9 * The above copyright notice and this permission notice shall be included in | |
| 10 * all copies or substantial portions of the Software. | |
| 11 * | |
| 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
| 18 * IN THE SOFTWARE. | |
| 19 */ | |
| 20 | |
| 21 #include "uv.h" | |
| 22 #include "internal.h" | |
| 23 | |
| 24 #include <assert.h> | |
| 25 #include <string.h> | |
| 26 #include <errno.h> | |
| 27 | |
| 28 #include <kvm.h> | |
| 29 #include <paths.h> | |
| 30 #include <unistd.h> | |
| 31 #include <time.h> | |
| 32 #include <stdlib.h> | |
| 33 #include <fcntl.h> | |
| 34 | |
| 35 #include <sys/resource.h> | |
| 36 #include <sys/types.h> | |
| 37 #include <sys/sysctl.h> | |
| 38 #include <uvm/uvm_extern.h> | |
| 39 | |
| 40 #include <unistd.h> | |
| 41 #include <time.h> | |
| 42 | |
| 43 | |
| 44 int uv__platform_loop_init(uv_loop_t* loop) { | |
| 45 return uv__kqueue_init(loop); | |
| 46 } | |
| 47 | |
| 48 | |
| 49 void uv__platform_loop_delete(uv_loop_t* loop) { | |
| 50 } | |
| 51 | |
| 52 | |
| 53 void uv_loadavg(double avg[3]) { | |
| 54 struct loadavg info; | |
| 55 size_t size = sizeof(info); | |
| 56 int which[] = {CTL_VM, VM_LOADAVG}; | |
| 57 | |
| 58 if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) == -1) return; | |
| 59 | |
| 60 avg[0] = (double) info.ldavg[0] / info.fscale; | |
| 61 avg[1] = (double) info.ldavg[1] / info.fscale; | |
| 62 avg[2] = (double) info.ldavg[2] / info.fscale; | |
| 63 } | |
| 64 | |
| 65 | |
| 66 int uv_exepath(char* buffer, size_t* size) { | |
| 67 /* Intermediate buffer, retrieving partial path name does not work | |
| 68 * As of NetBSD-8(beta), vnode->path translator does not handle files | |
| 69 * with longer names than 31 characters. | |
| 70 */ | |
| 71 char int_buf[PATH_MAX]; | |
| 72 size_t int_size; | |
| 73 int mib[4]; | |
| 74 | |
| 75 if (buffer == NULL || size == NULL || *size == 0) | |
| 76 return UV_EINVAL; | |
| 77 | |
| 78 mib[0] = CTL_KERN; | |
| 79 mib[1] = KERN_PROC_ARGS; | |
| 80 mib[2] = -1; | |
| 81 mib[3] = KERN_PROC_PATHNAME; | |
| 82 int_size = ARRAY_SIZE(int_buf); | |
| 83 | |
| 84 if (sysctl(mib, 4, int_buf, &int_size, NULL, 0)) | |
| 85 return UV__ERR(errno); | |
| 86 | |
| 87 /* Copy string from the intermediate buffer to outer one with appropriate | |
| 88 * length. | |
| 89 */ | |
| 90 /* TODO(bnoordhuis) Check uv__strscpy() return value. */ | |
| 91 uv__strscpy(buffer, int_buf, *size); | |
| 92 | |
| 93 /* Set new size. */ | |
| 94 *size = strlen(buffer); | |
| 95 | |
| 96 return 0; | |
| 97 } | |
| 98 | |
| 99 | |
| 100 uint64_t uv_get_free_memory(void) { | |
| 101 struct uvmexp info; | |
| 102 size_t size = sizeof(info); | |
| 103 int which[] = {CTL_VM, VM_UVMEXP}; | |
| 104 | |
| 105 if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) | |
| 106 return 0; | |
| 107 | |
| 108 return (uint64_t) info.free * sysconf(_SC_PAGESIZE); | |
| 109 } | |
| 110 | |
| 111 | |
| 112 uint64_t uv_get_total_memory(void) { | |
| 113 #if defined(HW_PHYSMEM64) | |
| 114 uint64_t info; | |
| 115 int which[] = {CTL_HW, HW_PHYSMEM64}; | |
| 116 #else | |
| 117 unsigned int info; | |
| 118 int which[] = {CTL_HW, HW_PHYSMEM}; | |
| 119 #endif | |
| 120 size_t size = sizeof(info); | |
| 121 | |
| 122 if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) | |
| 123 return 0; | |
| 124 | |
| 125 return (uint64_t) info; | |
| 126 } | |
| 127 | |
| 128 | |
| 129 uint64_t uv_get_constrained_memory(void) { | |
| 130 return 0; /* Memory constraints are unknown. */ | |
| 131 } | |
| 132 | |
| 133 | |
| 134 uint64_t uv_get_available_memory(void) { | |
| 135 return uv_get_free_memory(); | |
| 136 } | |
| 137 | |
| 138 | |
| 139 int uv_resident_set_memory(size_t* rss) { | |
| 140 kvm_t *kd = NULL; | |
| 141 struct kinfo_proc2 *kinfo = NULL; | |
| 142 pid_t pid; | |
| 143 int nprocs; | |
| 144 int max_size = sizeof(struct kinfo_proc2); | |
| 145 int page_size; | |
| 146 | |
| 147 page_size = getpagesize(); | |
| 148 pid = getpid(); | |
| 149 | |
| 150 kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open"); | |
| 151 | |
| 152 if (kd == NULL) goto error; | |
| 153 | |
| 154 kinfo = kvm_getproc2(kd, KERN_PROC_PID, pid, max_size, &nprocs); | |
| 155 if (kinfo == NULL) goto error; | |
| 156 | |
| 157 *rss = kinfo->p_vm_rssize * page_size; | |
| 158 | |
| 159 kvm_close(kd); | |
| 160 | |
| 161 return 0; | |
| 162 | |
| 163 error: | |
| 164 if (kd) kvm_close(kd); | |
| 165 return UV_EPERM; | |
| 166 } | |
| 167 | |
| 168 | |
| 169 int uv_uptime(double* uptime) { | |
| 170 time_t now; | |
| 171 struct timeval info; | |
| 172 size_t size = sizeof(info); | |
| 173 static int which[] = {CTL_KERN, KERN_BOOTTIME}; | |
| 174 | |
| 175 if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) | |
| 176 return UV__ERR(errno); | |
| 177 | |
| 178 now = time(NULL); | |
| 179 | |
| 180 *uptime = (double)(now - info.tv_sec); | |
| 181 return 0; | |
| 182 } | |
| 183 | |
| 184 | |
| 185 int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { | |
| 186 unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK); | |
| 187 unsigned int multiplier = ((uint64_t)1000L / ticks); | |
| 188 unsigned int cur = 0; | |
| 189 uv_cpu_info_t* cpu_info; | |
| 190 u_int64_t* cp_times; | |
| 191 char model[512]; | |
| 192 u_int64_t cpuspeed; | |
| 193 int numcpus; | |
| 194 size_t size; | |
| 195 int i; | |
| 196 | |
| 197 size = sizeof(model); | |
| 198 if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) && | |
| 199 sysctlbyname("hw.model", &model, &size, NULL, 0)) { | |
| 200 return UV__ERR(errno); | |
| 201 } | |
| 202 | |
| 203 size = sizeof(numcpus); | |
| 204 if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) | |
| 205 return UV__ERR(errno); | |
| 206 *count = numcpus; | |
| 207 | |
| 208 /* Only i386 and amd64 have machdep.tsc_freq */ | |
| 209 size = sizeof(cpuspeed); | |
| 210 if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &size, NULL, 0)) | |
| 211 cpuspeed = 0; | |
| 212 | |
| 213 size = numcpus * CPUSTATES * sizeof(*cp_times); | |
| 214 cp_times = uv__malloc(size); | |
| 215 if (cp_times == NULL) | |
| 216 return UV_ENOMEM; | |
| 217 | |
| 218 if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0)) | |
| 219 return UV__ERR(errno); | |
| 220 | |
| 221 *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); | |
| 222 if (!(*cpu_infos)) { | |
| 223 uv__free(cp_times); | |
| 224 uv__free(*cpu_infos); | |
| 225 return UV_ENOMEM; | |
| 226 } | |
| 227 | |
| 228 for (i = 0; i < numcpus; i++) { | |
| 229 cpu_info = &(*cpu_infos)[i]; | |
| 230 cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier; | |
| 231 cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier; | |
| 232 cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier; | |
| 233 cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier; | |
| 234 cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier; | |
| 235 cpu_info->model = uv__strdup(model); | |
| 236 cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6); | |
| 237 cur += CPUSTATES; | |
| 238 } | |
| 239 uv__free(cp_times); | |
| 240 return 0; | |
| 241 } | |
| 242 | |
| 243 int uv__random_sysctl(void* buf, size_t len) { | |
| 244 static int name[] = {CTL_KERN, KERN_ARND}; | |
| 245 size_t count, req; | |
| 246 unsigned char* p; | |
| 247 | |
| 248 p = buf; | |
| 249 while (len) { | |
| 250 req = len < 32 ? len : 32; | |
| 251 count = req; | |
| 252 | |
| 253 if (sysctl(name, ARRAY_SIZE(name), p, &count, NULL, 0) == -1) | |
| 254 return UV__ERR(errno); | |
| 255 | |
| 256 if (count != req) | |
| 257 return UV_EIO; /* Can't happen. */ | |
| 258 | |
| 259 p += count; | |
| 260 len -= count; | |
| 261 } | |
| 262 | |
| 263 return 0; | |
| 264 } |