@@ -85,17 +85,7 @@ static uint64_t read_cpufreq(unsigned int cpunum);
85
85
86
86
int uv__platform_loop_init (uv_loop_t * loop ) {
87
87
int fd ;
88
-
89
- /* It was reported that EPOLL_CLOEXEC is not defined on Android API < 21,
90
- * a.k.a. Lollipop. Since EPOLL_CLOEXEC is an alias for O_CLOEXEC on all
91
- * architectures, we just use that instead.
92
- */
93
- #if defined(__ANDROID_API__ ) && __ANDROID_API__ < 21
94
- fd = -1 ;
95
- errno = ENOSYS ;
96
- #else
97
88
fd = epoll_create1 (O_CLOEXEC );
98
- #endif
99
89
100
90
/* epoll_create1() can fail either because it's not implemented (old kernel)
101
91
* or because it doesn't understand the O_CLOEXEC flag.
@@ -208,8 +198,10 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
208
198
* that being the largest value I have seen in the wild (and only once.)
209
199
*/
210
200
static const int max_safe_timeout = 1789569 ;
211
- static int no_epoll_pwait ;
212
- static int no_epoll_wait ;
201
+ static int no_epoll_pwait_cached ;
202
+ static int no_epoll_wait_cached ;
203
+ int no_epoll_pwait ;
204
+ int no_epoll_wait ;
213
205
struct epoll_event events [1024 ];
214
206
struct epoll_event * pe ;
215
207
struct epoll_event e ;
@@ -281,6 +273,15 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
281
273
count = 48 ; /* Benchmarks suggest this gives the best throughput. */
282
274
real_timeout = timeout ;
283
275
276
+ /* You could argue there is a dependency between these two but
277
+ * ultimately we don't care about their ordering with respect
278
+ * to one another. Worst case, we make a few system calls that
279
+ * could have been avoided because another thread already knows
280
+ * they fail with ENOSYS. Hardly the end of the world.
281
+ */
282
+ no_epoll_pwait = uv__load_relaxed (& no_epoll_pwait_cached );
283
+ no_epoll_wait = uv__load_relaxed (& no_epoll_wait_cached );
284
+
284
285
for (;;) {
285
286
/* See the comment for max_safe_timeout for an explanation of why
286
287
* this is necessary. Executive summary: kernel bug workaround.
@@ -293,25 +294,24 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
293
294
abort ();
294
295
295
296
if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0 )) {
296
- #if defined(__ANDROID_API__ ) && __ANDROID_API__ < 21
297
- nfds = -1 ;
298
- errno = ENOSYS ;
299
- #else
300
297
nfds = epoll_pwait (loop -> backend_fd ,
301
298
events ,
302
299
ARRAY_SIZE (events ),
303
300
timeout ,
304
301
& sigset );
305
- #endif
306
- if ( nfds == -1 && errno == ENOSYS )
302
+ if ( nfds == -1 && errno == ENOSYS ) {
303
+ uv__store_relaxed ( & no_epoll_pwait_cached , 1 );
307
304
no_epoll_pwait = 1 ;
305
+ }
308
306
} else {
309
307
nfds = epoll_wait (loop -> backend_fd ,
310
308
events ,
311
309
ARRAY_SIZE (events ),
312
310
timeout );
313
- if (nfds == -1 && errno == ENOSYS )
311
+ if (nfds == -1 && errno == ENOSYS ) {
312
+ uv__store_relaxed (& no_epoll_wait_cached , 1 );
314
313
no_epoll_wait = 1 ;
314
+ }
315
315
}
316
316
317
317
if (sigmask != 0 && no_epoll_pwait != 0 )
@@ -982,43 +982,51 @@ void uv__set_process_title(const char* title) {
982
982
}
983
983
984
984
985
- static uint64_t uv__read_proc_meminfo (const char * what ) {
986
- uint64_t rc ;
985
+ static int uv__slurp (const char * filename , char * buf , size_t len ) {
987
986
ssize_t n ;
988
- char * p ;
989
987
int fd ;
990
- char buf [4096 ]; /* Large enough to hold all of /proc/meminfo. */
991
988
992
- rc = 0 ;
993
- fd = uv__open_cloexec ("/proc/meminfo" , O_RDONLY );
989
+ assert (len > 0 );
994
990
991
+ fd = uv__open_cloexec (filename , O_RDONLY );
995
992
if (fd < 0 )
996
- return 0 ;
993
+ return fd ;
994
+
995
+ do
996
+ n = read (fd , buf , len - 1 );
997
+ while (n == -1 && errno == EINTR );
997
998
998
- n = read (fd , buf , sizeof (buf ) - 1 );
999
+ if (uv__close_nocheckstdio (fd ))
1000
+ abort ();
999
1001
1000
- if (n <= 0 )
1001
- goto out ;
1002
+ if (n < 0 )
1003
+ return UV__ERR ( errno ) ;
1002
1004
1003
1005
buf [n ] = '\0' ;
1004
- p = strstr (buf , what );
1005
1006
1006
- if ( p == NULL )
1007
- goto out ;
1007
+ return 0 ;
1008
+ }
1008
1009
1009
- p += strlen (what );
1010
1010
1011
- if (1 != sscanf (p , "%" PRIu64 " kB" , & rc ))
1012
- goto out ;
1011
+ static uint64_t uv__read_proc_meminfo (const char * what ) {
1012
+ uint64_t rc ;
1013
+ char * p ;
1014
+ char buf [4096 ]; /* Large enough to hold all of /proc/meminfo. */
1013
1015
1014
- rc *= 1024 ;
1016
+ if (uv__slurp ("/proc/meminfo" , buf , sizeof (buf )))
1017
+ return 0 ;
1015
1018
1016
- out :
1019
+ p = strstr ( buf , what );
1017
1020
1018
- if (uv__close_nocheckstdio ( fd ) )
1019
- abort () ;
1021
+ if (p == NULL )
1022
+ return 0 ;
1020
1023
1021
- return rc ;
1024
+ p += strlen (what );
1025
+
1026
+ rc = 0 ;
1027
+ sscanf (p , "%" PRIu64 " kB" , & rc );
1028
+
1029
+ return rc * 1024 ;
1022
1030
}
1023
1031
1024
1032
@@ -1056,28 +1064,13 @@ uint64_t uv_get_total_memory(void) {
1056
1064
1057
1065
static uint64_t uv__read_cgroups_uint64 (const char * cgroup , const char * param ) {
1058
1066
char filename [256 ];
1059
- uint64_t rc ;
1060
- int fd ;
1061
- ssize_t n ;
1062
1067
char buf [32 ]; /* Large enough to hold an encoded uint64_t. */
1063
-
1064
- snprintf (filename , 256 , "/sys/fs/cgroup/%s/%s" , cgroup , param );
1068
+ uint64_t rc ;
1065
1069
1066
1070
rc = 0 ;
1067
- fd = uv__open_cloexec (filename , O_RDONLY );
1068
-
1069
- if (fd < 0 )
1070
- return 0 ;
1071
-
1072
- n = read (fd , buf , sizeof (buf ) - 1 );
1073
-
1074
- if (n > 0 ) {
1075
- buf [n ] = '\0' ;
1071
+ snprintf (filename , sizeof (filename ), "/sys/fs/cgroup/%s/%s" , cgroup , param );
1072
+ if (0 == uv__slurp (filename , buf , sizeof (buf )))
1076
1073
sscanf (buf , "%" PRIu64 , & rc );
1077
- }
1078
-
1079
- if (uv__close_nocheckstdio (fd ))
1080
- abort ();
1081
1074
1082
1075
return rc ;
1083
1076
}
@@ -1091,3 +1084,20 @@ uint64_t uv_get_constrained_memory(void) {
1091
1084
*/
1092
1085
return uv__read_cgroups_uint64 ("memory" , "memory.limit_in_bytes" );
1093
1086
}
1087
+
1088
+
1089
+ void uv_loadavg (double avg [3 ]) {
1090
+ struct sysinfo info ;
1091
+ char buf [128 ]; /* Large enough to hold all of /proc/loadavg. */
1092
+
1093
+ if (0 == uv__slurp ("/proc/loadavg" , buf , sizeof (buf )))
1094
+ if (3 == sscanf (buf , "%lf %lf %lf" , & avg [0 ], & avg [1 ], & avg [2 ]))
1095
+ return ;
1096
+
1097
+ if (sysinfo (& info ) < 0 )
1098
+ return ;
1099
+
1100
+ avg [0 ] = (double ) info .loads [0 ] / 65536.0 ;
1101
+ avg [1 ] = (double ) info .loads [1 ] / 65536.0 ;
1102
+ avg [2 ] = (double ) info .loads [2 ] / 65536.0 ;
1103
+ }
0 commit comments