about summary refs log tree commit diff
path: root/src/rt/rust_env.cpp
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-07-27 14:34:39 -0700
committerBrian Anderson <banderson@mozilla.com>2011-07-28 12:23:01 -0700
commit4ef1ec580aaf9f95d66c1654ce942f5e454a0b4d (patch)
tree39b600f84688f7e49c734285593fbe9911214cd5 /src/rt/rust_env.cpp
parent75985ab75ed216cd8c873c9ef08cd88708f8354f (diff)
downloadrust-4ef1ec580aaf9f95d66c1654ce942f5e454a0b4d.tar.gz
rust-4ef1ec580aaf9f95d66c1654ce942f5e454a0b4d.zip
Do all runtime calls to getenv at initialization
getenv is not threadsafe and (maybe as a result) it's randomly crashing with
CFLAGS=-g and RUST_THREADS=32. Calls from rust code are still on their
own.
Diffstat (limited to 'src/rt/rust_env.cpp')
-rw-r--r--src/rt/rust_env.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/rt/rust_env.cpp b/src/rt/rust_env.cpp
new file mode 100644
index 00000000000..26fc4dab180
--- /dev/null
+++ b/src/rt/rust_env.cpp
@@ -0,0 +1,119 @@
+// The runtime wants to pull a number of variables out of the
+// environment but calling getenv is not threadsafe, so every value
+// that might come from the environment is loaded here, once, during
+// init.
+
+#include "rust_internal.h"
+
+// The environment variables that the runtime knows about
+#define RUST_THREADS "RUST_THREADS"
+#define RUST_MIN_STACK "RUST_MIN_STACK"
+#define RUST_LOG "RUST_LOG"
+#define CHECK_CLAIMS "CHECK_CLAIMS"
+#define DETAILED_LEAKS "DETAILED_LEAKS"
+#define RUST_SEED "RUST_SEED"
+
+#if defined(__WIN32__)
+static int
+get_num_cpus() {
+    SYSTEM_INFO sysinfo;
+    GetSystemInfo(&sysinfo);
+
+    return (int) sysinfo.dwNumberOfProcessors;
+}
+#elif defined(__BSD__)
+static int
+get_num_cpus() {
+    /* swiped from http://stackoverflow.com/questions/150355/
+       programmatically-find-the-number-of-cores-on-a-machine */
+
+    unsigned int numCPU;
+    int mib[4];
+    size_t len = sizeof(numCPU);
+
+    /* set the mib for hw.ncpu */
+    mib[0] = CTL_HW;
+    mib[1] = HW_AVAILCPU;  // alternatively, try HW_NCPU;
+
+    /* get the number of CPUs from the system */
+    sysctl(mib, 2, &numCPU, &len, NULL, 0);
+
+    if( numCPU < 1 ) {
+        mib[1] = HW_NCPU;
+        sysctl( mib, 2, &numCPU, &len, NULL, 0 );
+
+        if( numCPU < 1 ) {
+            numCPU = 1;
+        }
+    }
+    return numCPU;
+}
+#elif defined(__GNUC__)
+static int
+get_num_cpus() {
+    return sysconf(_SC_NPROCESSORS_ONLN);
+}
+#endif
+
+static int
+get_num_threads()
+{
+    char *env = getenv(RUST_THREADS);
+    if(env) {
+        int num = atoi(env);
+        if(num > 0)
+            return num;
+    }
+    return get_num_cpus();
+}
+
+// FIXME (issue #151): This should be 0x300; the change here is for
+// practicality's sake until stack growth is working.
+
+static size_t
+get_min_stk_size() {
+    char *stack_size = getenv(RUST_MIN_STACK);
+    if(stack_size) {
+        return strtol(stack_size, NULL, 0);
+    }
+    else {
+        return 0x300000;
+    }
+}
+
+static char*
+copyenv(const char* name) {
+    char *envvar = getenv(name);
+    if (!envvar) {
+        return NULL;
+    } else {
+        const size_t maxlen = 4096;
+        size_t strlen = strnlen(envvar, maxlen);
+        size_t buflen = strlen + 1;
+        char *var = (char*)malloc(buflen);
+        memset(var, 0, buflen);
+        strncpy(var, envvar, strlen);
+        return var;
+    }
+}
+
+rust_env*
+load_env() {
+    rust_env *env = (rust_env*)malloc(sizeof(rust_env));
+
+    env->num_sched_threads = (size_t)get_num_threads();
+    env->min_stack_size = get_min_stk_size();
+    env->logspec = copyenv(RUST_LOG);
+    env->check_claims = getenv(CHECK_CLAIMS) != NULL;
+    env->detailed_leaks = getenv(DETAILED_LEAKS) != NULL;
+    env->rust_seed = copyenv(RUST_SEED);
+
+    return env;
+}
+
+void
+free_env(rust_env *env) {
+    free(env->logspec);
+    free(env->rust_seed);
+    free(env);
+}