about summary refs log tree commit diff
path: root/src/rt/rust_env.cpp
blob: 9237e8b593c4a51109a52e7e7c675253ccd95acd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// 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_MAX_STACK "RUST_MAX_STACK"
#define RUST_LOG "RUST_LOG"
#define CHECK_CLAIMS "CHECK_CLAIMS"
#define DETAILED_LEAKS "DETAILED_LEAKS"
#define RUST_SEED "RUST_SEED"
#define RUST_POISON_ON_FREE "RUST_POISON_ON_FREE"

#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();
}

static size_t
get_min_stk_size() {
    char *minsz = getenv(RUST_MIN_STACK);
    if(minsz) {
        return strtol(minsz, NULL, 0);
    }
    else {
        return 0x300;
    }
}

static size_t
get_max_stk_size() {
    char *maxsz = getenv(RUST_MAX_STACK);
    if (maxsz) {
        return strtol(maxsz, NULL, 0);
    }
    else {
        return 1024*1024*8;
    }
}

static char*
copyenv(const char* name) {
    char *envvar = getenv(name);
    if (!envvar) {
        return NULL;
    } else {
        size_t slen = strlen(envvar);
        size_t buflen = slen + 1;
        char *var = (char*)malloc(buflen);
        memset(var, 0, buflen);
        strncpy(var, envvar, slen);
        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->max_stack_size = get_max_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);
    env->poison_on_free = getenv(RUST_POISON_ON_FREE) != NULL;

    return env;
}

void
free_env(rust_env *env) {
    free(env->logspec);
    free(env->rust_seed);
    free(env);
}