Example #1
0
void random_thread_deallocate( void )
{
	if( !get_thread_state() )
		return;

	mutex_lock( _random_mutex );
	array_push( _random_available_state, get_thread_state() );
	mutex_unlock( _random_mutex );

	set_thread_state( 0 );
}
Example #2
0
static inline void
trace_state_change_with_func (const char *transition, MonoThreadInfo *info, int cur_raw_state, int next_state, int suspend_count_delta, const char *func)
{
	check_thread_state (info);
	THREADS_STATE_MACHINE_DEBUG ("[%s][%p] %s -> %s (%d -> %d) %s\n",
		transition,
		mono_thread_info_get_tid (info),
		state_name (get_thread_state (cur_raw_state)),
		state_name (next_state),
		get_thread_suspend_count (cur_raw_state),
		get_thread_suspend_count (cur_raw_state) + suspend_count_delta,
		func);

	CHECKED_BUILD_THREAD_TRANSITION (transition, info, get_thread_state (cur_raw_state), get_thread_suspend_count (cur_raw_state), next_state, suspend_count_delta);
}
Example #3
0
static PyObject*
faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = {"file", "all_threads", NULL};
    PyObject *file = NULL;
    int all_threads = 1;
    int fd;
    PyThreadState *tstate;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
        "|Oi:enable", kwlist, &file, &all_threads))
        return NULL;

    fd = faulthandler_get_fileno(&file);
    if (fd < 0)
        return NULL;

    tstate = get_thread_state();
    if (tstate == NULL)
        return NULL;

    Py_XINCREF(file);
    Py_XSETREF(fatal_error.file, file);
    fatal_error.fd = fd;
    fatal_error.all_threads = all_threads;
    fatal_error.interp = tstate->interp;

    if (faulthandler_enable() < 0) {
        return NULL;
    }

    Py_RETURN_NONE;
}
Example #4
0
static PyObject*
faulthandler_register_py(PyObject *self,
                         PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = {"signum", "file", "all_threads", "chain", NULL};
    int signum;
    PyObject *file = NULL;
    int all_threads = 1;
    int chain = 0;
    int fd;
    user_signal_t *user;
    _Py_sighandler_t previous;
    PyThreadState *tstate;
    int err;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
        "i|Oii:register", kwlist,
        &signum, &file, &all_threads, &chain))
        return NULL;

    if (!check_signum(signum))
        return NULL;

    tstate = get_thread_state();
    if (tstate == NULL)
        return NULL;

    file = faulthandler_get_fileno(file, &fd);
    if (file == NULL)
        return NULL;

    if (user_signals == NULL) {
        user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t));
        if (user_signals == NULL)
            return PyErr_NoMemory();
        memset(user_signals, 0, NSIG * sizeof(user_signal_t));
    }
    user = &user_signals[signum];

    if (!user->enabled) {
        err = faulthandler_register(signum, chain, &previous);
        if (err) {
            PyErr_SetFromErrno(PyExc_OSError);
            return NULL;
        }

        user->previous = previous;
    }

    Py_XDECREF(user->file);
    Py_INCREF(file);
    user->file = file;
    user->fd = fd;
    user->all_threads = all_threads;
    user->chain = chain;
    user->interp = tstate->interp;
    user->enabled = 1;

    Py_RETURN_NONE;
}
Example #5
0
static PyObject*
faulthandler_dump_traceback_later(PyObject *self,
                                  PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
    int timeout;
    PyOS_sighandler_t previous;
    int repeat = 0;
    PyObject *file = NULL;
    int exit = 0;
    PyThreadState *tstate;
    int fd;
    char *header;
    size_t header_len;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
        "i|iOi:dump_traceback_later", kwlist,
        &timeout, &repeat, &file, &exit))
        return NULL;
    if (timeout <= 0) {
        PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
        return NULL;
    }

    tstate = get_thread_state();
    if (tstate == NULL)
        return NULL;

    fd = faulthandler_get_fileno(&file);
    if (fd < 0)
        return NULL;

    /* format the timeout */
    header = format_timeout(timeout);
    if (header == NULL)
        return PyErr_NoMemory();
    header_len = strlen(header);

    previous = signal(SIGALRM, faulthandler_alarm);
    if (previous == SIG_ERR) {
        PyErr_SetString(PyExc_RuntimeError, "unable to set SIGALRM handler");
        free(header);
        return NULL;
    }

    Py_XDECREF(fault_alarm.file);
    Py_XINCREF(file);
    fault_alarm.file = file;
    fault_alarm.fd = fd;
    fault_alarm.timeout = timeout;
    fault_alarm.repeat = repeat;
    fault_alarm.interp = tstate->interp;
    fault_alarm.exit = exit;
    fault_alarm.header = header;
    fault_alarm.header_len = header_len;

    alarm(timeout);

    Py_RETURN_NONE;
}
/**
 * set thread_state
 * @brief Set the thread state
 *
 * Set the given thread to the desired state.  This just writes "1" or "0"
 * to /sys/devices/system/cpu/cpu[id]/online.
 *
 * @param thread
 * @param state
 * @returns 0 on success, !0 otherwise
 */
int
set_thread_state(struct thread *thread, int state)
{
	char path[DR_PATH_MAX];
	FILE *file;
	int rc = 0;

	say(DEBUG, "%slining thread id %d\n",
	    ((state == ONLINE) ? "On" : "Off"), thread->id);
	sprintf(path, DR_THREAD_ONLINE_PATH, thread->id);
	file = fopen(path, "w");
	if (file == NULL) {
		say(ERROR, "Could not open %s, unable to set thread state "
		    "to %d\n", path);
		return -1;
	}

	fprintf(file, "%d", state);
	fclose(file);

	/* fprintf apparently does not return negative number
	 * if the write() gets an -EBUSY, so explicitly check the
	 * thread state.
	 */
	if (state != get_thread_state(thread)) {
		say(ERROR, "Failure setting thread state for %s\n", path);
		rc = -1;
	}

	return rc;
}
/**
 * online_first_dead_cpu
 * @brief Find the first cpu with attributes online and physical_id both
 *        set to 0 and online it.
 *
 * @param nthreads
 * @returns 0 on success, !0 otherwise
 */
int
online_first_dead_cpu(int nthreads, struct dr_info *dr_info)
{
	struct thread *thread;
	int rc = 1;

	for (thread = dr_info->all_threads; thread; thread = thread->next) {
		if (OFFLINE == get_thread_state(thread)
		    && ((thread->phys_id == 0xffffffff)
			|| (thread->phys_id == 0))) {
			    
			/* just assume that there will be nthreads to online. */
			while (nthreads--) {
				set_thread_state(thread, ONLINE);
				thread = thread->next;
			}

			rc = 0;
			break;
		}
	}

	if (rc)
		say(ERROR, "Could not find any threads to online\n");

	return rc;
}
/**
 * online cpu
 *
 * @param cpu
 * @param dr_info
 * @returns 0 on success, !0 otherwise
 */
int
online_cpu(struct dr_node *cpu, struct dr_info *dr_info) 
{
	int rc = 0;
	struct thread *thread = NULL;
	int found = 0;

	say(DEBUG, "Onlining cpu %s (%d threads)\n", cpu->name,
	    cpu->cpu_nthreads);

	/* Hack to work around kernel brain damage (LTC 7692) */
	for (thread = dr_info->all_threads; thread; thread = thread->next) {
		if (thread->cpu == cpu) {
			found = 1;
			break;
		}
	}
	
	if (!found) {
		/* There are no threads which match this cpu because
		 * the physical_id attribute is not updated until the
		 * cpu is onlined -- this case is for cpus which are
		 * not present at boot but are added afterwards.
		 */
		return online_first_dead_cpu(cpu->cpu_nthreads, dr_info);
	}

	for (thread = cpu->cpu_threads; thread; thread = thread->sibling) {
		if (get_thread_state(thread) != ONLINE)
			rc |= set_thread_state(thread, ONLINE);
	}

	return rc;
}
Example #9
0
thread_callback_t XPLCALL thread_callback(void *param) {
    assert(param);
    
    xpl_thread_id tid = *(xpl_thread_id *)param;
    
    int state = get_thread_state(tid);
    while (state != ts_terminate_request) {
        callback_handle_status(tid, state);
        state = get_thread_state(tid);
    }
    
#ifdef XPL_PLATFORM_WINDOWS
    _endthreadex(0);
#endif
    
    return 0;
}
Example #10
0
/**
 * Return TRUE is the thread is in an usable (suspendable) state
 */
gboolean
mono_thread_info_is_live (MonoThreadInfo *info)
{
	switch (get_thread_state (info->thread_state)) {
	case STATE_STARTING:
	case STATE_DETACHED:
		return FALSE;
	}
	return TRUE;
}
static inline void
trace_state_change (const char *transition, MonoThreadInfo *info, int cur_raw_state, int next_state, int suspend_count_delta)
{
	check_thread_state (info);
	THREADS_STATE_MACHINE_DEBUG ("[%s][%p] %s -> %s (%d -> %d)\n",
		transition,
		mono_thread_info_get_tid (info),
		state_name (get_thread_state (cur_raw_state)),
		state_name (next_state),
		get_thread_suspend_count (cur_raw_state),
		get_thread_suspend_count (cur_raw_state) + suspend_count_delta);
}
Example #12
0
/**
 * Return TRUE is the thread is in a runnable state.
*/
gboolean
mono_thread_info_is_running (MonoThreadInfo *info)
{
	switch (get_thread_state (info->thread_state)) {
	case STATE_RUNNING:
	case STATE_ASYNC_SUSPEND_REQUESTED:
	case STATE_BLOCKING_SUSPEND_REQUESTED:
	case STATE_BLOCKING:
		return TRUE;
	}
	return FALSE;
}
/**
 * cpu_diable_smt
 * @brief Disable all but one of a cpu's threads
 *
 * @param cpu cpu to disable smt on
 * @returns 0 on success, !0 otherwise
 */
int
cpu_disable_smt(struct dr_node *cpu)
{
	int rc = 0;
	struct thread *t;
	int survivor_found = 0;

	/* Ensure that the first thread of the processor is the thread that is left online
	 * when disabling SMT.
	 */
	t = cpu->cpu_threads;
	if (get_thread_state(t) == OFFLINE)
		rc |= set_thread_state(t, ONLINE);

	for (t = cpu->cpu_threads; t != NULL; t = t->sibling) {
		if (ONLINE == get_thread_state(t)) {
			if (survivor_found)
				rc |= set_thread_state(t, OFFLINE);
			survivor_found = 1;
		}
	}

	return rc;
}
/**
 * offline_cpu
 * @brief Mark the specified cpu as offline
 *
 * @param cpu
 * @param dr_info
 * @returns 0 on success, !0 otherwise
 */
int
offline_cpu(struct dr_node *cpu)
{
	int rc = 0;
	struct thread *thread;

	say(DEBUG, "Offlining cpu %s (%d threads)\n", cpu->name,
	    cpu->cpu_nthreads);

	for (thread = cpu->cpu_threads; thread; thread = thread->sibling) {
		if (get_thread_state(thread) != OFFLINE)
			rc |= set_thread_state(thread, OFFLINE);
	}

	return rc;
}
static const char*
state_name (int state)
{
	static const char *state_names [] = {
		"STARTING",
		"RUNNING",
		"DETACHED",
		"ASYNC_SUSPENDED",
		"SELF_SUSPENDED",
		"ASYNC_SUSPEND_REQUESTED",
		"SELF_SUSPEND_REQUESTED",
		"STATE_BLOCKING",
		"STATE_BLOCKING_AND_SUSPENDED",
	};
	return state_names [get_thread_state (state)];
}
Example #16
0
static PyObject*
faulthandler_dump_traceback_py(PyObject *self,
                               PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = {"file", "all_threads", NULL};
    PyObject *file = NULL;
    int all_threads = 1;
    PyThreadState *tstate;
    const char *errmsg;
    int fd;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
        "|Oi:dump_traceback", kwlist,
        &file, &all_threads))
        return NULL;

    fd = faulthandler_get_fileno(&file);
    if (fd < 0)
        return NULL;

    tstate = get_thread_state();
    if (tstate == NULL)
        return NULL;

    if (all_threads) {
        errmsg = _Py_DumpTracebackThreads(fd, NULL, tstate);
        if (errmsg != NULL) {
            PyErr_SetString(PyExc_RuntimeError, errmsg);
            return NULL;
        }
    }
    else {
        _Py_DumpTraceback(fd, tstate);
    }

    if (PyErr_CheckSignals())
        return NULL;

    Py_RETURN_NONE;
}
Example #17
0
static PyObject*
faulthandler_dump_tracebacks_later(PyObject *self,
                                   PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
    double timeout;
    PY_TIMEOUT_T timeout_us;
    int repeat = 0;
    PyObject *file = NULL;
    int fd;
    int exit = 0;
    PyThreadState *tstate;
    char *header;
    size_t header_len;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
        "d|iOi:dump_tracebacks_later", kwlist,
        &timeout, &repeat, &file, &exit))
        return NULL;
    if ((timeout * 1e6) >= (double) PY_TIMEOUT_MAX) {
        PyErr_SetString(PyExc_OverflowError,  "timeout value is too large");
        return NULL;
    }
    timeout_us = (PY_TIMEOUT_T)(timeout * 1e6);
    if (timeout_us <= 0) {
        PyErr_SetString(PyExc_ValueError, "timeout must be greater than 0");
        return NULL;
    }

    tstate = get_thread_state();
    if (tstate == NULL)
        return NULL;

    file = faulthandler_get_fileno(file, &fd);
    if (file == NULL)
        return NULL;

    /* format the timeout */
    header = format_timeout(timeout);
    if (header == NULL)
        return PyErr_NoMemory();
    header_len = strlen(header);

    /* Cancel previous thread, if running */
    cancel_dump_tracebacks_later();

    Py_XDECREF(thread.file);
    Py_INCREF(file);
    thread.file = file;
    thread.fd = fd;
    thread.timeout_us = timeout_us;
    thread.repeat = repeat;
    thread.interp = tstate->interp;
    thread.exit = exit;
    thread.header = header;
    thread.header_len = header_len;

    /* Arm these locks to serve as events when released */
    PyThread_acquire_lock(thread.running, 1);

    if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
        PyThread_release_lock(thread.running);
        Py_CLEAR(thread.file);
        free(header);
        thread.header = NULL;
        PyErr_SetString(PyExc_RuntimeError,
                        "unable to start watchdog thread");
        return NULL;
    }

    Py_RETURN_NONE;
}
Example #18
0
static PyObject*
faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
{
    static char *kwlist[] = {"file", "all_threads", NULL};
    PyObject *file = NULL;
    int all_threads = 1;
    unsigned int i;
    fault_handler_t *handler;
#ifdef HAVE_SIGACTION
    struct sigaction action;
#endif
    int err;
    int fd;
    PyThreadState *tstate;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
        "|Oi:enable", kwlist, &file, &all_threads))
        return NULL;

    file = faulthandler_get_fileno(file, &fd);
    if (file == NULL)
        return NULL;

    tstate = get_thread_state();
    if (tstate == NULL)
        return NULL;

    Py_XDECREF(fatal_error.file);
    Py_INCREF(file);
    fatal_error.file = file;
    fatal_error.fd = fd;
    fatal_error.all_threads = all_threads;
    fatal_error.interp = tstate->interp;

    if (!fatal_error.enabled) {
        fatal_error.enabled = 1;

        for (i=0; i < faulthandler_nsignals; i++) {
            handler = &faulthandler_handlers[i];
#ifdef HAVE_SIGACTION
            action.sa_handler = faulthandler_fatal_error;
            sigemptyset(&action.sa_mask);
            /* Do not prevent the signal from being received from within
               its own signal handler */
            action.sa_flags = SA_NODEFER;
#ifdef HAVE_SIGALTSTACK
            if (stack.ss_sp != NULL) {
                /* Call the signal handler on an alternate signal stack
                   provided by sigaltstack() */
                action.sa_flags |= SA_ONSTACK;
            }
#endif
            err = sigaction(handler->signum, &action, &handler->previous);
#else
            handler->previous = signal(handler->signum,
                                       faulthandler_fatal_error);
            err = (handler->previous == SIG_ERR);
#endif
            if (err) {
                PyErr_SetFromErrno(PyExc_RuntimeError);
                return NULL;
            }
            handler->enabled = 1;
        }
    }
    Py_RETURN_NONE;
}
Example #19
0
int main(int argc, char **argv) {
	/* Slave threads */
	sgcomm_thread *st_rd; // Reader
	sgcomm_thread *st_tx; // Transmitter
	shared_buffer *sbtx; // shared buffer for read+transmit
	
	/* Reader message parameters */
	char *fmtstr = "/mnt/disks/%u/%u/data/%s";
	char *pattern_read = "input.vdif";
	char *host = "localhost";
	uint16_t port = 61234;
	int n_mod = 4;
	int mod_list[4] = { 1, 2, 3, 4};
	int n_disk = 8;
	int disk_list_read[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
	int disk_list_write[8] = { 1, 0, 2, 3, 4, 5, 6, 7 };
	
	/* Transmitter message parameters */
	if (argc > 1)
		pattern_read = argv[1];
	if (argc > 2)
		fmtstr = argv[2];
	if (argc > 3)
		host = argv[3];
	if (argc > 4)
		port = atoi(argv[4]);
	
	log_message(RL_NOTICE,"%s:Using input file '%s' matching pattern '%s'",__FUNCTION__,pattern_read,fmtstr);
	log_message(RL_NOTICE,"%s:Transmitting to %s:%u",__FUNCTION__,host,port);
	
	/* This thread */
	sgcomm_thread *st = &st_main;
	ctrl_state state;
	
	log_message(RL_DEBUG,"%s:Creating shared buffer",__FUNCTION__);
	
	/* Initialize shared data buffer */
	sbtx = create_shared_buffer(SHARED_BUFFER_SIZE_TX);
	if (sbtx == NULL)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot create shared buffer for read+transmit",__FUNCTION__,__LINE__);
	
	log_message(RL_DEBUG,"%s:Creating slave threads",__FUNCTION__);
	
	/* Create thread instances */
	st_rd = create_thread(TT_READER);
	if (st_rd == NULL)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot create reader thread",__FUNCTION__,__LINE__);
	st_tx = create_thread(TT_TRANSMITTER);
	if (st_tx == NULL)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot create transmitter thread",__FUNCTION__,__LINE__);
	
	log_message(RL_DEBUG,"%s:Initializing thread messages",__FUNCTION__);
	
	/* Initialize thread messages */
	init_reader_msg((reader_msg *)st_rd->type_msg, sbtx, pattern_read, fmtstr,
					mod_list, n_mod, disk_list_read, n_disk);
	init_transmitter_msg((transmitter_msg *)st_tx->type_msg, sbtx,
					host, port);
	
	/* Start transmitter thread */
	if (start_thread(st_tx) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot start transmitter thread",__FUNCTION__,__LINE__);
	/* Pause, then see if transmitter has error, if so, abort */
	usleep(MAIN_WAIT_PERIOD_US);
	if ((get_thread_state(st_tx,&state) == 0) && (state >= CS_STOP)) {
		set_thread_state(st,CS_ERROR,"%s(%d):Transmitter terminated prematurely, aborting start.",__FUNCTION__,__LINE__);
	} else {
		if (start_thread(st_rd) != 0)
			set_thread_state(st,CS_ERROR,"%s(%d):Cannot start reader thread",__FUNCTION__,__LINE__);
	}
	
	//~ log_message(RL_DEBUG,"%s:Entering main thread run loop",__FUNCTION__);
	
	if ((get_thread_state(st,&state) == 0) && !(state >= CS_STOP))
		set_thread_state(st,CS_RUN,"%s:Thread running",__FUNCTION__);
	while ((get_thread_state(st,&state) == 0) && !(state >= CS_STOP)) {
				
		// TODO: do something
		
		usleep(MAIN_WAIT_PERIOD_US);
		
		/* If any thread has a problem, stop all of them */
		if ( ((get_thread_state(st_rd,&state) == 0) && (state >= CS_ERROR)) ||
			 ((get_thread_state(st_tx,&state) == 0) && (state >= CS_ERROR)) ) {
			// TODO: Some cleanup?
			break;
		}
		
		/* If all threads are stopped, break */
		if ( ((get_thread_state(st_rd,&state) == 0) && (state >= CS_STOP)) &&
			 ((get_thread_state(st_tx,&state) == 0) && (state >= CS_STOP)) ) {
			log_message(RL_NOTICE,"%s:All threads stopped of their own volition",__FUNCTION__);
			break;
		}
		
		/* If reader thread is done, stop transmitter */
		if ( (get_thread_state(st_rd,&state) == 0) && (state >= CS_STOP) && 
			 (get_thread_state(st_tx,&state) == 0) && (state < CS_STOP)) {
			log_message(RL_NOTICE,"%s:Reader is done, stop transmitter",__FUNCTION__);
			/* Two wait periods should be enough - reader is the only
			 * other thread that can cause transmitter to wait on a 
			 * resource, and then it will only be a single wait. */
			usleep(MAIN_WAIT_PERIOD_US);
			usleep(MAIN_WAIT_PERIOD_US);
			if (stop_thread(st_tx) != 0)
				set_thread_state(st,CS_ERROR,"%s(%d):Cannot stop transmitter thread",__FUNCTION__,__LINE__);
		}
		
	}
	
	log_message(RL_DEBUG,"%s:Stopping slave threads",__FUNCTION__);
	
	/* Stop slave threads on tx side */
	if ( (get_thread_state(st_rd,&state) == 0) && (state < CS_STOP) && (state > CS_INIT) && stop_thread(st_rd) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot stop reader thread",__FUNCTION__,__LINE__);
	log_message(RL_DEBUGVVV,"%s:Reader thread stopped",__FUNCTION__);
	if ( (get_thread_state(st_tx,&state) == 0) && (state < CS_STOP) && (state > CS_INIT) && stop_thread(st_tx) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot stop transmitter thread",__FUNCTION__,__LINE__);
	log_message(RL_DEBUGVVV,"%s:Transmitter thread stopped",__FUNCTION__);
	
	log_message(RL_DEBUG,"%s:Destroying shared buffer",__FUNCTION__);
	
	/* Destroy shared data buffer */
	if (destroy_shared_buffer(&sbtx) != 0)
		set_thread_state(st,CS_ERROR,"%s(%d):Cannot destroy shared buffer for read+transmit",__FUNCTION__,__LINE__);
	
	log_message(RL_DEBUG,"%s:Destroying slave threads",__FUNCTION__);
	
	/* Destroy threads */
	destroy_thread(&st_rd);
	destroy_thread(&st_tx);
	
	log_message(RL_DEBUG,"%s:Everything is done, goodbye",__FUNCTION__);
	
	/* That's all folks! */
	// TODO: Report that we're done
	return EXIT_SUCCESS;
}
Example #20
0
int
mono_thread_info_current_state (MonoThreadInfo *info)
{
	return get_thread_state (info->thread_state);
}