Beispiel #1
0
int
erts_sys_getenv_raw(char *key, char *value, size_t *size)
{
    int res;
    erts_rwmtx_rlock(&environ_rwmtx);
    res = erts_sys_getenv__(key, value, size);
    erts_rwmtx_runlock(&environ_rwmtx);
    return res;
}
Beispiel #2
0
static ErtsMsAcc* get_msacc(void) {
    ErtsMsAcc *msacc;
    erts_rwmtx_rlock(&msacc_mutex);
    msacc = msacc_managed;
    while (!erts_equal_tids(msacc->tid,erts_thr_self())) {
        msacc = msacc->next;
        ASSERT(msacc != NULL);
    }
    erts_rwmtx_runlock(&msacc_mutex);
    return msacc;
}
Beispiel #3
0
int erts_sys_unsetenv(char *key)
{
    int res = 0;
    WCHAR *wkey = (WCHAR *) key;

    SetLastError(0);
    erts_rwmtx_rlock(&environ_rwmtx);
    GetEnvironmentVariableW(wkey,
                            NULL,
                            0);
    if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
        res = (SetEnvironmentVariableW(wkey,
                                       NULL) ? 0 : 1);
    }
    erts_rwmtx_runlock(&environ_rwmtx);
    return res;
}
Beispiel #4
0
char*
win_build_environment(char* new_env)
{
    if (new_env == NULL) {
	return NULL;
    } else {
	WCHAR *tmp, *merged, *tmp_new;

	tmp_new = (WCHAR *) new_env;
	
	erts_rwmtx_rlock(&environ_rwmtx);
	tmp = GetEnvironmentStringsW();
	merged = merge_environment(tmp, tmp_new);

	FreeEnvironmentStringsW(tmp);
	erts_rwmtx_runlock(&environ_rwmtx);
	return (char *) merged;
    }
}
Beispiel #5
0
int
erts_sys_getenv(char *key, char *value, size_t *size)
{
    size_t req_size = 0;
    int res = 0;
    DWORD new_size;
    WCHAR *wkey = (WCHAR *) key;
    WCHAR *wvalue = (WCHAR *) value;
    DWORD wsize = *size / (sizeof(WCHAR) / sizeof(char));

    SetLastError(0);
    erts_rwmtx_rlock(&environ_rwmtx);
    new_size = GetEnvironmentVariableW(wkey,
				       wvalue,
				      (DWORD) wsize);
    res = !new_size && GetLastError() == ERROR_ENVVAR_NOT_FOUND ? -1 : 0;
    erts_rwmtx_runlock(&environ_rwmtx);
    if (res < 0)
	return res;
    res = new_size > wsize ? 1 : 0;
    *size = new_size * (sizeof(WCHAR) / sizeof(char));
    return res;
}
Beispiel #6
0
void fini_getenv_state(GETENV_STATE *state)
{
    FreeEnvironmentStringsW(state->environment_strings);
    state->environment_strings = state->next_string = NULL;
    erts_rwmtx_runlock(&environ_rwmtx);
}
Beispiel #7
0
/*
 * This function is responsible for enabling, disabling, resetting and
 * gathering data related to microstate accounting.
 *
 * Managed threads and unmanaged threads are handled differently.
 *   - managed threads get a misc_aux job telling them to switch on msacc
 *   - unmanaged have some fields protected by a mutex that has to be taken
 *     before any values can be updated
 *
 * For performance reasons there is also a global value erts_msacc_enabled
 * that controls the state of all threads. Statistics gathering is only on
 * if erts_msacc_enabled && msacc is true.
 */
Eterm
erts_msacc_request(Process *c_p, int action, Eterm *threads)
{
#ifdef ERTS_ENABLE_MSACC
    ErtsMsAcc *msacc =  ERTS_MSACC_TSD_GET();
    ErtsSchedulerData *esdp = erts_proc_sched_data(c_p);
    Eterm ref;
    ErtsMSAccReq *msaccrp;
    Eterm *hp;


#ifdef ERTS_MSACC_ALWAYS_ON
    if (action == ERTS_MSACC_ENABLE || action == ERTS_MSACC_DISABLE)
        return THE_NON_VALUE;
#else
    /* take care of double enable, and double disable here */
    if (msacc && action == ERTS_MSACC_ENABLE) {
        return THE_NON_VALUE;
    } else if (!msacc && action == ERTS_MSACC_DISABLE) {
        return THE_NON_VALUE;
    }
#endif

    ref = erts_make_ref(c_p);

    msaccrp = erts_alloc(ERTS_ALC_T_MSACC, sizeof(ErtsMSAccReq));
    hp = &msaccrp->ref_heap[0];

    msaccrp->action = action;
    msaccrp->proc = c_p;
    msaccrp->ref = STORE_NC(&hp, NULL, ref);
    msaccrp->req_sched = esdp->no;

#ifdef ERTS_SMP
    *threads = erts_no_schedulers;
    *threads += 1; /* aux thread */
#else
    *threads = 1;
#endif

    erts_smp_atomic32_init_nob(&msaccrp->refc,(erts_aint32_t)*threads);

    erts_proc_add_refc(c_p, *threads);

    if (erts_no_schedulers > 1)
	erts_schedule_multi_misc_aux_work(1,
                                          erts_no_schedulers,
                                          reply_msacc,
                                          (void *) msaccrp);
#ifdef ERTS_SMP
    /* aux thread */
    erts_schedule_misc_aux_work(0, reply_msacc, (void *) msaccrp);
#endif

#ifdef USE_THREADS
    /* Manage unmanaged threads */
    switch (action) {
    case ERTS_MSACC_GATHER: {
        Uint unmanaged_count;
        ErtsMsAcc *msacc, **unmanaged;
        int i = 0;

        /* we copy a list of pointers here so that we do not have to have
           the msacc_mutex when sending messages */
        erts_rwmtx_rlock(&msacc_mutex);
        unmanaged_count = msacc_unmanaged_count;
        unmanaged = erts_alloc(ERTS_ALC_T_MSACC,
                               sizeof(ErtsMsAcc*)*unmanaged_count);

        for (i = 0, msacc = msacc_unmanaged;
             i < unmanaged_count;
             i++, msacc = msacc->next) {
            unmanaged[i] = msacc;
        }
        erts_rwmtx_runlock(&msacc_mutex);

        for (i = 0; i < unmanaged_count; i++) {
            erts_mtx_lock(&unmanaged[i]->mtx);
            if (unmanaged[i]->perf_counter) {
                ErtsSysPerfCounter perf_counter;
                /* if enabled update stats */
                perf_counter = erts_sys_perf_counter();
                unmanaged[i]->perf_counters[unmanaged[i]->state] +=
                    perf_counter - unmanaged[i]->perf_counter;
                unmanaged[i]->perf_counter = perf_counter;
            }
            erts_mtx_unlock(&unmanaged[i]->mtx);
            send_reply(unmanaged[i],msaccrp);
        }
        erts_free(ERTS_ALC_T_MSACC,unmanaged);
        /* We have just sent unmanaged_count messages, so bump no of threads */
        *threads += unmanaged_count;
        break;
    }
    case ERTS_MSACC_RESET: {
        ErtsMsAcc *msacc;
        erts_rwmtx_rlock(&msacc_mutex);
        for (msacc = msacc_unmanaged; msacc != NULL; msacc = msacc->next)
            erts_msacc_reset(msacc);
        erts_rwmtx_runlock(&msacc_mutex);
        break;
    }
    case ERTS_MSACC_ENABLE: {
        erts_rwmtx_rlock(&msacc_mutex);
        for (msacc = msacc_unmanaged; msacc != NULL; msacc = msacc->next) {
            erts_mtx_lock(&msacc->mtx);
            msacc->perf_counter = erts_sys_perf_counter();
            /* we assume the unmanaged thread is sleeping */
            msacc->state = ERTS_MSACC_STATE_SLEEP;
            erts_mtx_unlock(&msacc->mtx);
        }
        erts_rwmtx_runlock(&msacc_mutex);
        break;
    }
    case ERTS_MSACC_DISABLE: {
        ErtsSysPerfCounter perf_counter;
        erts_rwmtx_rlock(&msacc_mutex);
        /* make sure to update stats with latest results */
        for (msacc = msacc_unmanaged; msacc != NULL; msacc = msacc->next) {
            erts_mtx_lock(&msacc->mtx);
            perf_counter = erts_sys_perf_counter();
            msacc->perf_counters[msacc->state] += perf_counter - msacc->perf_counter;
            msacc->perf_counter = 0;
            erts_mtx_unlock(&msacc->mtx);
        }
        erts_rwmtx_runlock(&msacc_mutex);
        break;
    }
    default: { ASSERT(0); }
    }

#endif

    *threads = make_small(*threads);

    reply_msacc((void *) msaccrp);

#ifndef ERTS_MSACC_ALWAYS_ON
    /* enable/disable the global value */
    if (action == ERTS_MSACC_ENABLE) {
        erts_msacc_enabled = 1;
    } else if (action == ERTS_MSACC_DISABLE) {
        erts_msacc_enabled = 0;
    }
#endif

    return ref;
#else
    return THE_NON_VALUE;
#endif
}