xref: /netbsd/external/mit/libuv/dist/src/unix/openbsd.c (revision fbb2e0a3)
1*fbb2e0a3Schristos /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2*fbb2e0a3Schristos  * Permission is hereby granted, free of charge, to any person obtaining a copy
3*fbb2e0a3Schristos  * of this software and associated documentation files (the "Software"), to
4*fbb2e0a3Schristos  * deal in the Software without restriction, including without limitation the
5*fbb2e0a3Schristos  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6*fbb2e0a3Schristos  * sell copies of the Software, and to permit persons to whom the Software is
7*fbb2e0a3Schristos  * furnished to do so, subject to the following conditions:
8*fbb2e0a3Schristos  *
9*fbb2e0a3Schristos  * The above copyright notice and this permission notice shall be included in
10*fbb2e0a3Schristos  * all copies or substantial portions of the Software.
11*fbb2e0a3Schristos  *
12*fbb2e0a3Schristos  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13*fbb2e0a3Schristos  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14*fbb2e0a3Schristos  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15*fbb2e0a3Schristos  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16*fbb2e0a3Schristos  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17*fbb2e0a3Schristos  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18*fbb2e0a3Schristos  * IN THE SOFTWARE.
19*fbb2e0a3Schristos  */
20*fbb2e0a3Schristos 
21*fbb2e0a3Schristos #include "uv.h"
22*fbb2e0a3Schristos #include "internal.h"
23*fbb2e0a3Schristos 
24*fbb2e0a3Schristos #include <sys/types.h>
25*fbb2e0a3Schristos #include <sys/param.h>
26*fbb2e0a3Schristos #include <sys/resource.h>
27*fbb2e0a3Schristos #include <sys/sched.h>
28*fbb2e0a3Schristos #include <sys/time.h>
29*fbb2e0a3Schristos #include <sys/sysctl.h>
30*fbb2e0a3Schristos 
31*fbb2e0a3Schristos #include <errno.h>
32*fbb2e0a3Schristos #include <fcntl.h>
33*fbb2e0a3Schristos #include <paths.h>
34*fbb2e0a3Schristos #include <stdlib.h>
35*fbb2e0a3Schristos #include <string.h>
36*fbb2e0a3Schristos #include <unistd.h>
37*fbb2e0a3Schristos 
38*fbb2e0a3Schristos 
uv__platform_loop_init(uv_loop_t * loop)39*fbb2e0a3Schristos int uv__platform_loop_init(uv_loop_t* loop) {
40*fbb2e0a3Schristos   return uv__kqueue_init(loop);
41*fbb2e0a3Schristos }
42*fbb2e0a3Schristos 
43*fbb2e0a3Schristos 
uv__platform_loop_delete(uv_loop_t * loop)44*fbb2e0a3Schristos void uv__platform_loop_delete(uv_loop_t* loop) {
45*fbb2e0a3Schristos }
46*fbb2e0a3Schristos 
47*fbb2e0a3Schristos 
uv_loadavg(double avg[3])48*fbb2e0a3Schristos void uv_loadavg(double avg[3]) {
49*fbb2e0a3Schristos   struct loadavg info;
50*fbb2e0a3Schristos   size_t size = sizeof(info);
51*fbb2e0a3Schristos   int which[] = {CTL_VM, VM_LOADAVG};
52*fbb2e0a3Schristos 
53*fbb2e0a3Schristos   if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) < 0) return;
54*fbb2e0a3Schristos 
55*fbb2e0a3Schristos   avg[0] = (double) info.ldavg[0] / info.fscale;
56*fbb2e0a3Schristos   avg[1] = (double) info.ldavg[1] / info.fscale;
57*fbb2e0a3Schristos   avg[2] = (double) info.ldavg[2] / info.fscale;
58*fbb2e0a3Schristos }
59*fbb2e0a3Schristos 
60*fbb2e0a3Schristos 
uv_exepath(char * buffer,size_t * size)61*fbb2e0a3Schristos int uv_exepath(char* buffer, size_t* size) {
62*fbb2e0a3Schristos   int mib[4];
63*fbb2e0a3Schristos   char **argsbuf = NULL;
64*fbb2e0a3Schristos   size_t argsbuf_size = 100U;
65*fbb2e0a3Schristos   size_t exepath_size;
66*fbb2e0a3Schristos   pid_t mypid;
67*fbb2e0a3Schristos   int err;
68*fbb2e0a3Schristos 
69*fbb2e0a3Schristos   if (buffer == NULL || size == NULL || *size == 0)
70*fbb2e0a3Schristos     return UV_EINVAL;
71*fbb2e0a3Schristos 
72*fbb2e0a3Schristos   mypid = getpid();
73*fbb2e0a3Schristos   for (;;) {
74*fbb2e0a3Schristos     err = UV_ENOMEM;
75*fbb2e0a3Schristos     argsbuf = uv__reallocf(argsbuf, argsbuf_size);
76*fbb2e0a3Schristos     if (argsbuf == NULL)
77*fbb2e0a3Schristos       goto out;
78*fbb2e0a3Schristos     mib[0] = CTL_KERN;
79*fbb2e0a3Schristos     mib[1] = KERN_PROC_ARGS;
80*fbb2e0a3Schristos     mib[2] = mypid;
81*fbb2e0a3Schristos     mib[3] = KERN_PROC_ARGV;
82*fbb2e0a3Schristos     if (sysctl(mib, ARRAY_SIZE(mib), argsbuf, &argsbuf_size, NULL, 0) == 0) {
83*fbb2e0a3Schristos       break;
84*fbb2e0a3Schristos     }
85*fbb2e0a3Schristos     if (errno != ENOMEM) {
86*fbb2e0a3Schristos       err = UV__ERR(errno);
87*fbb2e0a3Schristos       goto out;
88*fbb2e0a3Schristos     }
89*fbb2e0a3Schristos     argsbuf_size *= 2U;
90*fbb2e0a3Schristos   }
91*fbb2e0a3Schristos 
92*fbb2e0a3Schristos   if (argsbuf[0] == NULL) {
93*fbb2e0a3Schristos     err = UV_EINVAL;  /* FIXME(bnoordhuis) More appropriate error. */
94*fbb2e0a3Schristos     goto out;
95*fbb2e0a3Schristos   }
96*fbb2e0a3Schristos 
97*fbb2e0a3Schristos   *size -= 1;
98*fbb2e0a3Schristos   exepath_size = strlen(argsbuf[0]);
99*fbb2e0a3Schristos   if (*size > exepath_size)
100*fbb2e0a3Schristos     *size = exepath_size;
101*fbb2e0a3Schristos 
102*fbb2e0a3Schristos   memcpy(buffer, argsbuf[0], *size);
103*fbb2e0a3Schristos   buffer[*size] = '\0';
104*fbb2e0a3Schristos   err = 0;
105*fbb2e0a3Schristos 
106*fbb2e0a3Schristos out:
107*fbb2e0a3Schristos   uv__free(argsbuf);
108*fbb2e0a3Schristos 
109*fbb2e0a3Schristos   return err;
110*fbb2e0a3Schristos }
111*fbb2e0a3Schristos 
112*fbb2e0a3Schristos 
uv_get_free_memory(void)113*fbb2e0a3Schristos uint64_t uv_get_free_memory(void) {
114*fbb2e0a3Schristos   struct uvmexp info;
115*fbb2e0a3Schristos   size_t size = sizeof(info);
116*fbb2e0a3Schristos   int which[] = {CTL_VM, VM_UVMEXP};
117*fbb2e0a3Schristos 
118*fbb2e0a3Schristos   if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
119*fbb2e0a3Schristos     return UV__ERR(errno);
120*fbb2e0a3Schristos 
121*fbb2e0a3Schristos   return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
122*fbb2e0a3Schristos }
123*fbb2e0a3Schristos 
124*fbb2e0a3Schristos 
uv_get_total_memory(void)125*fbb2e0a3Schristos uint64_t uv_get_total_memory(void) {
126*fbb2e0a3Schristos   uint64_t info;
127*fbb2e0a3Schristos   int which[] = {CTL_HW, HW_PHYSMEM64};
128*fbb2e0a3Schristos   size_t size = sizeof(info);
129*fbb2e0a3Schristos 
130*fbb2e0a3Schristos   if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
131*fbb2e0a3Schristos     return UV__ERR(errno);
132*fbb2e0a3Schristos 
133*fbb2e0a3Schristos   return (uint64_t) info;
134*fbb2e0a3Schristos }
135*fbb2e0a3Schristos 
136*fbb2e0a3Schristos 
uv_get_constrained_memory(void)137*fbb2e0a3Schristos uint64_t uv_get_constrained_memory(void) {
138*fbb2e0a3Schristos   return 0;  /* Memory constraints are unknown. */
139*fbb2e0a3Schristos }
140*fbb2e0a3Schristos 
141*fbb2e0a3Schristos 
uv_resident_set_memory(size_t * rss)142*fbb2e0a3Schristos int uv_resident_set_memory(size_t* rss) {
143*fbb2e0a3Schristos   struct kinfo_proc kinfo;
144*fbb2e0a3Schristos   size_t page_size = getpagesize();
145*fbb2e0a3Schristos   size_t size = sizeof(struct kinfo_proc);
146*fbb2e0a3Schristos   int mib[6];
147*fbb2e0a3Schristos 
148*fbb2e0a3Schristos   mib[0] = CTL_KERN;
149*fbb2e0a3Schristos   mib[1] = KERN_PROC;
150*fbb2e0a3Schristos   mib[2] = KERN_PROC_PID;
151*fbb2e0a3Schristos   mib[3] = getpid();
152*fbb2e0a3Schristos   mib[4] = sizeof(struct kinfo_proc);
153*fbb2e0a3Schristos   mib[5] = 1;
154*fbb2e0a3Schristos 
155*fbb2e0a3Schristos   if (sysctl(mib, ARRAY_SIZE(mib), &kinfo, &size, NULL, 0) < 0)
156*fbb2e0a3Schristos     return UV__ERR(errno);
157*fbb2e0a3Schristos 
158*fbb2e0a3Schristos   *rss = kinfo.p_vm_rssize * page_size;
159*fbb2e0a3Schristos   return 0;
160*fbb2e0a3Schristos }
161*fbb2e0a3Schristos 
162*fbb2e0a3Schristos 
uv_uptime(double * uptime)163*fbb2e0a3Schristos int uv_uptime(double* uptime) {
164*fbb2e0a3Schristos   time_t now;
165*fbb2e0a3Schristos   struct timeval info;
166*fbb2e0a3Schristos   size_t size = sizeof(info);
167*fbb2e0a3Schristos   static int which[] = {CTL_KERN, KERN_BOOTTIME};
168*fbb2e0a3Schristos 
169*fbb2e0a3Schristos   if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0))
170*fbb2e0a3Schristos     return UV__ERR(errno);
171*fbb2e0a3Schristos 
172*fbb2e0a3Schristos   now = time(NULL);
173*fbb2e0a3Schristos 
174*fbb2e0a3Schristos   *uptime = (double)(now - info.tv_sec);
175*fbb2e0a3Schristos   return 0;
176*fbb2e0a3Schristos }
177*fbb2e0a3Schristos 
178*fbb2e0a3Schristos 
uv_cpu_info(uv_cpu_info_t ** cpu_infos,int * count)179*fbb2e0a3Schristos int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
180*fbb2e0a3Schristos   unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK),
181*fbb2e0a3Schristos                multiplier = ((uint64_t)1000L / ticks), cpuspeed;
182*fbb2e0a3Schristos   uint64_t info[CPUSTATES];
183*fbb2e0a3Schristos   char model[512];
184*fbb2e0a3Schristos   int numcpus = 1;
185*fbb2e0a3Schristos   int which[] = {CTL_HW,HW_MODEL};
186*fbb2e0a3Schristos   int percpu[] = {CTL_KERN,KERN_CPTIME2,0};
187*fbb2e0a3Schristos   size_t size;
188*fbb2e0a3Schristos   int i, j;
189*fbb2e0a3Schristos   uv_cpu_info_t* cpu_info;
190*fbb2e0a3Schristos 
191*fbb2e0a3Schristos   size = sizeof(model);
192*fbb2e0a3Schristos   if (sysctl(which, ARRAY_SIZE(which), &model, &size, NULL, 0))
193*fbb2e0a3Schristos     return UV__ERR(errno);
194*fbb2e0a3Schristos 
195*fbb2e0a3Schristos   which[1] = HW_NCPUONLINE;
196*fbb2e0a3Schristos   size = sizeof(numcpus);
197*fbb2e0a3Schristos   if (sysctl(which, ARRAY_SIZE(which), &numcpus, &size, NULL, 0))
198*fbb2e0a3Schristos     return UV__ERR(errno);
199*fbb2e0a3Schristos 
200*fbb2e0a3Schristos   *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
201*fbb2e0a3Schristos   if (!(*cpu_infos))
202*fbb2e0a3Schristos     return UV_ENOMEM;
203*fbb2e0a3Schristos 
204*fbb2e0a3Schristos   i = 0;
205*fbb2e0a3Schristos   *count = numcpus;
206*fbb2e0a3Schristos 
207*fbb2e0a3Schristos   which[1] = HW_CPUSPEED;
208*fbb2e0a3Schristos   size = sizeof(cpuspeed);
209*fbb2e0a3Schristos   if (sysctl(which, ARRAY_SIZE(which), &cpuspeed, &size, NULL, 0))
210*fbb2e0a3Schristos     goto error;
211*fbb2e0a3Schristos 
212*fbb2e0a3Schristos   size = sizeof(info);
213*fbb2e0a3Schristos   for (i = 0; i < numcpus; i++) {
214*fbb2e0a3Schristos     percpu[2] = i;
215*fbb2e0a3Schristos     if (sysctl(percpu, ARRAY_SIZE(percpu), &info, &size, NULL, 0))
216*fbb2e0a3Schristos       goto error;
217*fbb2e0a3Schristos 
218*fbb2e0a3Schristos     cpu_info = &(*cpu_infos)[i];
219*fbb2e0a3Schristos 
220*fbb2e0a3Schristos     cpu_info->cpu_times.user = (uint64_t)(info[CP_USER]) * multiplier;
221*fbb2e0a3Schristos     cpu_info->cpu_times.nice = (uint64_t)(info[CP_NICE]) * multiplier;
222*fbb2e0a3Schristos     cpu_info->cpu_times.sys = (uint64_t)(info[CP_SYS]) * multiplier;
223*fbb2e0a3Schristos     cpu_info->cpu_times.idle = (uint64_t)(info[CP_IDLE]) * multiplier;
224*fbb2e0a3Schristos     cpu_info->cpu_times.irq = (uint64_t)(info[CP_INTR]) * multiplier;
225*fbb2e0a3Schristos 
226*fbb2e0a3Schristos     cpu_info->model = uv__strdup(model);
227*fbb2e0a3Schristos     cpu_info->speed = cpuspeed;
228*fbb2e0a3Schristos   }
229*fbb2e0a3Schristos 
230*fbb2e0a3Schristos   return 0;
231*fbb2e0a3Schristos 
232*fbb2e0a3Schristos error:
233*fbb2e0a3Schristos   *count = 0;
234*fbb2e0a3Schristos   for (j = 0; j < i; j++)
235*fbb2e0a3Schristos     uv__free((*cpu_infos)[j].model);
236*fbb2e0a3Schristos 
237*fbb2e0a3Schristos   uv__free(*cpu_infos);
238*fbb2e0a3Schristos   *cpu_infos = NULL;
239*fbb2e0a3Schristos   return UV__ERR(errno);
240*fbb2e0a3Schristos }
241