ext/etc/etc.c in etc-1.2.0 vs ext/etc/etc.c in etc-1.3.0
- old
+ new
@@ -50,36 +50,35 @@
#ifndef _WIN32
char *getenv();
#endif
char *getlogin();
-#define RUBY_ETC_VERSION "1.2.0"
+#define RUBY_ETC_VERSION "1.3.0"
#ifdef HAVE_RB_DEPRECATE_CONSTANT
void rb_deprecate_constant(VALUE mod, const char *name);
#else
# define rb_deprecate_constant(mod,name) ((void)(mod),(void)(name))
#endif
#include "constdefs.h"
-#ifdef HAVE_RB_EXT_RACTOR_SAFE
-#include "ruby/thread_native.h"
+#ifdef HAVE_RUBY_ATOMIC_H
+# include "ruby/atomic.h"
#else
-/* Implement rb_native_mutex_x using an int */
-typedef int rb_nativethread_lock_t;
-static int rb_native_mutex_trylock(int *mutex) {
- if (*mutex) {
- return 1;
- }
- *mutex = 1;
- return 0;
+typedef int rb_atomic_t;
+# define RUBY_ATOMIC_CAS(var, oldval, newval) \
+ ((var) == (oldval) ? ((var) = (newval), (oldval)) : (var))
+# define RUBY_ATOMIC_EXCHANGE(var, newval) \
+ atomic_exchange(&var, newval)
+static inline rb_atomic_t
+atomic_exchange(volatile rb_atomic_t *var, rb_atomic_t newval)
+{
+ rb_atomic_t oldval = *var;
+ *var = newval;
+ return oldval;
}
-static void rb_native_mutex_unlock(int *mutex) {
- *mutex = 0;
-}
-#define rb_native_mutex_initialize rb_native_mutex_unlock
#endif
/* call-seq:
* getlogin -> String
*
@@ -256,16 +255,18 @@
return Qnil;
#endif
}
#ifdef HAVE_GETPWENT
-static rb_nativethread_lock_t passwd_blocking;
+static rb_atomic_t passwd_blocking;
static VALUE
passwd_ensure(VALUE _)
{
endpwent();
- rb_native_mutex_unlock(&passwd_blocking);
+ if (RUBY_ATOMIC_EXCHANGE(passwd_blocking, 0) != 1) {
+ rb_raise(rb_eRuntimeError, "unexpected passwd_blocking");
+ }
return Qnil;
}
static VALUE
passwd_iterate(VALUE _)
@@ -280,11 +281,11 @@
}
static void
each_passwd(void)
{
- if (rb_native_mutex_trylock(&passwd_blocking)) {
+ if (RUBY_ATOMIC_CAS(passwd_blocking, 0, 1)) {
rb_raise(rb_eRuntimeError, "parallel passwd iteration");
}
rb_ensure(passwd_iterate, 0, passwd_ensure, 0);
}
#endif
@@ -498,16 +499,18 @@
return Qnil;
#endif
}
#ifdef HAVE_GETGRENT
-static rb_nativethread_lock_t group_blocking;
+static rb_atomic_t group_blocking;
static VALUE
group_ensure(VALUE _)
{
endgrent();
- rb_native_mutex_unlock(&group_blocking);
+ if (RUBY_ATOMIC_EXCHANGE(group_blocking, 0) != 1) {
+ rb_raise(rb_eRuntimeError, "unexpected group_blocking");
+ }
return Qnil;
}
static VALUE
@@ -523,11 +526,11 @@
}
static void
each_group(void)
{
- if (rb_native_mutex_trylock(&group_blocking)) {
+ if (RUBY_ATOMIC_CAS(group_blocking, 0, 1)) {
rb_raise(rb_eRuntimeError, "parallel group iteration");
}
rb_ensure(group_iterate, 0, group_ensure, 0);
}
#endif
@@ -952,15 +955,17 @@
#if defined(HAVE_SCHED_GETAFFINITY) && defined(CPU_ALLOC)
static int
etc_nprocessors_affin(void)
{
- cpu_set_t *cpuset;
+ cpu_set_t *cpuset, cpuset_buff[1024 / sizeof(cpu_set_t)];
size_t size;
int ret;
int n;
+ CPU_ZERO_S(sizeof(cpuset_buff), cpuset_buff);
+
/*
* XXX:
* man page says CPU_ALLOC takes number of cpus. But it is not accurate
* explanation. sched_getaffinity() returns EINVAL if cpuset bitmap is
* smaller than kernel internal bitmap.
@@ -975,29 +980,28 @@
* So, we use hardcode number for a workaround. Current linux kernel
* (Linux 3.17) support 8192 cpus at maximum. Then 16384 must be enough.
*/
for (n=64; n <= 16384; n *= 2) {
size = CPU_ALLOC_SIZE(n);
- if (size >= 1024) {
+ if (size >= sizeof(cpuset_buff)) {
cpuset = xcalloc(1, size);
if (!cpuset)
return -1;
} else {
- cpuset = alloca(size);
- CPU_ZERO_S(size, cpuset);
+ cpuset = cpuset_buff;
}
ret = sched_getaffinity(0, size, cpuset);
if (ret == 0) {
/* On success, count number of cpus. */
ret = CPU_COUNT_S(size, cpuset);
}
- if (size >= 1024) {
+ if (size >= sizeof(cpuset_buff)) {
xfree(cpuset);
}
- if (ret > 0) {
+ if (ret > 0 || errno != EINVAL) {
return ret;
}
}
return ret;
@@ -1197,14 +1201,10 @@
#endif
rb_define_const(rb_cStruct, "Passwd", sPasswd); /* deprecated name */
rb_deprecate_constant(rb_cStruct, "Passwd");
rb_extend_object(sPasswd, rb_mEnumerable);
rb_define_singleton_method(sPasswd, "each", etc_each_passwd, 0);
-#ifdef HAVE_GETPWENT
- rb_native_mutex_initialize(&passwd_blocking);
-#endif
#ifdef HAVE_GETGRENT
- rb_native_mutex_initialize(&group_blocking);
sGroup = rb_struct_define_under(mEtc, "Group", "name",
#ifdef HAVE_STRUCT_GROUP_GR_PASSWD
"passwd",
#endif
"gid", "mem", NULL);