Esempio n. 1
0
/**
 * Creates a new message spscq.
 * @param name Name of the new spscq interface
 * @param max_msg Positive integer. Maximum number of messages that can be inserted in the spscq
 * @param msg_sz Positive integer. Maximum message size
 * @return non-null value on success, zero on error
 */
r_itf_t rtdal_itfspscq_new(int max_msg, int max_msg_sz, int delay) {
	hdebug("max_msg=%d,max_msg_sz=%d\n",max_msg,max_msg_sz);
	assert(context);
	RTDAL_ASSERT_PARAM_P(max_msg>=0);
	RTDAL_ASSERT_PARAM_P(max_msg_sz>=0);
	int i;


	pthread_mutex_lock(&context->mutex);
	for (i=0;i<MAX(rtdal_itfspscq);i++) {
		if (!context->spscqs[i].parent.id)
			break;
	}
	if (i == MAX(rtdal_itfspscq)) {
		RTDAL_SETERROR(RTDAL_ERROR_NOTFOUND);
		return NULL;
	}
	hdebug("i=%d\n",i);
	context->spscqs[i].max_msg = max_msg;
	context->spscqs[i].max_msg_sz = max_msg_sz;
	context->spscqs[i].parent.delay = delay;
	context->spscqs[i].parent.id = i+1;

	if (rtdal_itfspscq_init(&context->spscqs[i])) {
		context->spscqs[i].parent.id = 0;
		pthread_mutex_unlock(&context->mutex);
		return NULL;
	}

	pthread_mutex_unlock(&context->mutex);
	return (r_itf_t) &context->spscqs[i];
}
Esempio n. 2
0
int rtdal_itfspscq_recv(r_itf_t obj, void* buffer, int len) {

	RTDAL_ASSERT_PARAM(buffer);
	RTDAL_ASSERT_PARAM(len>=0);

	int n, plen;
	void *ptr;

	if ((n = rtdal_itfspscq_pop(obj, &ptr, &plen, rtdal_time_slot())) != 1) {
		return n;
	}
	if (plen > len) {
		plen = len;
	}

	hdebug("obj=0x%x, rcv pkt=0x%x\n",obj,ptr);
	memcpy(buffer, ptr, (size_t) plen);

	if ((n = rtdal_itfspscq_release(obj)) == 1) {
		return n;
	}

	hdebug("release pkt 0x%x\n",ptr);

	return plen;
}
Esempio n. 3
0
inline static void pipeline_run_time_slot(pipeline_t *obj) {
	int idx;
	rtdal_process_t *run_proc;
	hdebug("pipeid=%d, tslot=%d, nof_process=%d thread=%d\n",obj->id,obj->ts_counter,
			obj->nof_processes, obj->thread);
	obj->finished = 0;

	pipeline_run_thread_print_time(obj);

	run_proc = obj->first_process;
	idx = 0;

	while(run_proc) {
		hdebug("%d/%d: run=%d code=%d next=0x%x\n",idx,obj->nof_processes,run_proc->runnable,
				run_proc->finish_code,run_proc->next);
		if (idx > obj->nof_processes) {
			aerror_msg("Fatal error. Corrupted pipeline-%d process list at process %d\n",
					obj->id, idx);
			kill(getpid(),SIGTERM);
			pthread_exit(NULL);
		}
		pipeline_run_thread_check_status(obj,run_proc);
		pipeline_run_thread_run_module(obj,run_proc, idx);
		run_proc = run_proc->next;
		idx++;
	}
	obj->ts_counter++;
	obj->finished = 1;
}
Esempio n. 4
0
/**
 * Removes the process proc from the pipeline pointed by obj.
 * @param obj Pointer to the pipeline object
 * @param proc Pointer to the process to remove
 * @return Zero on success, -1 on error
 */
int pipeline_remove(pipeline_t *obj, rtdal_process_t *proc) {
	hdebug("pipeid=%d, nof_process=%d, pid=%d, pid_pos=%d\n",obj->id,obj->nof_processes,
			proc->pid,proc->attributes.exec_position);
	RTDAL_ASSERT_PARAM(obj);
	RTDAL_ASSERT_PARAM(proc);

	rtdal_process_t *cur, *prev;

	prev = NULL;
	cur = obj->first_process;
	while(cur != proc && cur) {
		hdebug("pipeid=%d, prev=0x%x, cur=0x%x\n", obj->id,
				prev,cur);
		prev = cur;
		cur = cur->next;
	}
	if (!cur) {
		RTDAL_SETERROR(RTDAL_ERROR_NOTFOUND);
		return -1;
	}
	if (prev) {
		hdebug("pipeid=%d remove middle/end\n",obj->id);
		prev->next = cur->next;
	} else {
		hdebug("pipeid=%d remove first\n",obj->id);
		obj->first_process = cur->next;
	}

	obj->nof_processes--;
	proc->next = NULL;

	return 0;
}
Esempio n. 5
0
/**
 * Creates a new process to be executed by one of the kernel pipelines.
 * The structure pointed by attr is defined in rtdal_process_attr.

 *
 * rtdal_process_new() configures the process parameters and loads it into the
 * pipeline. The process won't execute until a success call to rtdal_process_run()
 * is performed.
 *
 * The address pointed by arg will be passed to the process as a parameter.
 *
 * Notes: The shared library must conform with the rtdal_process_t requirements.
 *
 * @param attr Configures the process attributes
 * @param arg Argument to pass to the process each execution cycle
 * @return non-null value on success, zero on error
 */
r_proc_t rtdal_process_new(struct rtdal_process_attr *attr, void *arg) {
	hdebug("binary=%s, proc=%d, pos=%d, finish=0x%x, arg=0x%x\n",attr->binary_path,attr->pipeline_id,
			attr->exec_position,attr->finish_callback,arg);
	assert(context);
	RTDAL_ASSERT_PARAM_P(attr);
	RTDAL_ASSERT_PARAM_P(arg);

	pthread_mutex_lock(&context->mutex);
	int i=0;
	/* find empty space on process db */
	for (i=0;i<MAX(rtdal_process);i++) {
		if (!context->processes[i].pid)
			break;
	}

	if (i == MAX(rtdal_process)) {
		RTDAL_SETERROR(RTDAL_ERROR_NOSPACE);
		goto out;
	}

	if (attr->process_group_id > MAX_PROCESS_GROUP_ID) {
		RTDAL_SETERROR(RTDAL_ERROR_NOSPACE);
		goto out;
	}

	if (attr->process_group_id < 0) {
		RTDAL_SETERROR(RTDAL_ERROR_INVAL);
		goto out;
	}

	pgroup_notified_failure[attr->process_group_id] = 0;
	memset(&context->processes[i],0,sizeof(rtdal_process_t));
	context->processes[i].pid=i+1;

	hdebug("i=%d, pid=%d\n",context->processes[i].pid);

	memcpy(&context->processes[i].attributes, attr,
			sizeof(struct rtdal_process_attr));
	context->processes[i].arg = arg;
	context->processes[i].finish_code = FINISH_OK;

	if (pipeline_add(&context->pipelines[attr->pipeline_id],
			&context->processes[i]) == -1) {
		goto out;
	}

	if (rtdal_process_launch(&context->processes[i])) {
		pipeline_remove(&context->pipelines[attr->pipeline_id],
				&context->processes[i]);
		goto out;
	}

	pthread_mutex_unlock(&context->mutex);
	return (r_proc_t) &context->processes[i];
out:
	pthread_mutex_unlock(&context->mutex);
	return NULL;
}
Esempio n. 6
0
/**
 * Loads a process binary into memory. The process must have been created using
 *  rtdal_process_new(). This function loads the library defined in the process
 *  attributes during the call to rtdal_process_new().
 *  @param obj Pointer to the rtdal_process_t object.
 *  @return Zero on success, -1 on error.
 */
int rtdal_process_launch(rtdal_process_t *obj) {
	hdebug("path=%s\n",obj->attributes.binary_path);
	RTDAL_ASSERT_PARAM(obj);
	char *error;

	snprintf(tmp,LSTR_LEN,"/tmp/am_%d.so",obj->pid);
	snprintf(tmp2,LSTR_LEN,"cp %s/%s %s",libs_path,obj->attributes.binary_path,tmp);
	if (system(tmp2) == -1) {
		aerror("Error removing file\n");
		return -1;
	}

	obj->dl_handle = dlopen(tmp,RTLD_NOW);
	if (!obj->dl_handle) {
		RTDAL_DLERROR(dlerror());
		return -1;
	}

	dlerror();

	*(void**) (&obj->run_point) = dlsym(obj->dl_handle, "_run_cycle");
	if ((error = dlerror()) != NULL) {
		RTDAL_DLERROR(error);
		return -1;
	}

	return 0;
}
Esempio n. 7
0
/**
 * Creates a new low-priority periodic function. If it succeeds, the function callback
 * will be called every period timeslots with low priority.
 *
 * @param callback Pointer to the periodic function
 * @param period Positive integer, in time slots
 * @return zero on success, -1 on error
 */
int rtdal_periodic_add(void (*callback)(void), int period) {
	assert(context);
	RTDAL_ASSERT_PARAM(callback);
	RTDAL_ASSERT_PARAM(period>0);

	pthread_mutex_lock(&context->mutex);

	int i;

	for (i=0;i<MAX(rtdal_periodic);i++) {
		if (!context->periodic[i].callback)
			break;
	}
	if (i == MAX(rtdal_periodic)) {
		RTDAL_SETERROR(RTDAL_ERROR_NOSPACE);
		pthread_mutex_unlock(&context->mutex);
		return -1;
	}
	context->periodic[i].counter = 0;
	context->periodic[i].period = period;
	context->periodic[i].callback = callback;
	pthread_mutex_unlock(&context->mutex);
	hdebug("i=%d, period=%d, callback=0x%x\n",i,period,callback);
	return 0;
}
Esempio n. 8
0
/**
 * Disables the execution of the process identified by the first argument.
 * The process must have been previously loaded using rtdal_process_new().
 * @param process Process handler given by rtdal_process_new()
 * @returns zero on success, -1 on error
 */
int rtdal_process_stop(r_proc_t process) {
	RTDAL_ASSERT_PARAM(process);
	rtdal_process_t *obj = (rtdal_process_t*) process;
	hdebug("pid=%d\n",obj->pid);
	obj->runnable = 0;
	return 0;
}
Esempio n. 9
0
/**
 * Sets an error code for a process.
 * \param proc Process handler given by rtdal_process_new()
 * \returns zero on success, -1 on error
 */
int rtdal_process_seterror(r_proc_t proc, rtdal_processerrors_t code) {
	RTDAL_ASSERT_PARAM(proc);
	rtdal_process_t *obj = (rtdal_process_t*) proc;
	hdebug("pid=%d, code=%d\n",obj->pid,(int)code);
	obj->finish_code = code;
	return 0;
}
Esempio n. 10
0
/**
 * Runs one process after another (calling process[i].run_point()) and then
 * sleeps waiting for the semaphore
 */
void *pipeline_run_thread(void *self) {
	assert(self);
	pipeline_t *obj = (pipeline_t*) self;
	assert(obj->id>=0);

	hdebug("pipeid=%d waiting\n",obj->id);

	obj->stop = 0;
	pipeline_sync_thread_waits(obj->id);
	hdebug("pipeid=%d start\n",obj->id);
	while(!obj->stop) {
		pipeline_run_time_slot(obj);
		pipeline_sync_thread_waits(obj->id);
	}
	hdebug("pipeid=%d exiting\n",obj->id);
	return NULL;
}
Esempio n. 11
0
/**  sleep the calling thread for the time specified by the time_t structure.
 */
int rtdal_sleep(time_t *t) {
	assert(context);
	RTDAL_ASSERT_PARAM(t);
	hdebug("sleep_for=%d:%d\n",t->tv_sec,t->tv_usec);
	struct timespec sleep;

	sleep.tv_sec = t->tv_sec;
	sleep.tv_nsec = t->tv_usec*1000;

	if (clock_nanosleep(CLOCK_REALTIME,0,&sleep,NULL)) {
		RTDAL_SYSERROR("clock_nanosleep");
		return -1;
	}

	hdebug("waking up at %d\n",rtdal_time_slot());
	return 0;
}
Esempio n. 12
0
/**
 * Returns a handler to the first physical interface matching the id.
 * @param id Id of the physical interface
 * @return non-null value on success, zero on error
 */
r_itf_t rtdal_itfphysic_get_id(int id) {
	hdebug("id=%d\n",id);
	assert(context);
	RTDAL_ASSERT_PARAM_P(id);
	int i;
	for (i=0;i<MAX(rtdal_itfphysic);i++) {
		if (context->physic_itfs[i].parent.id == id)
			break;
	}

	hdebug("i=%d\n",i);
	if (i == MAX(rtdal_itfphysic)) {
		RTDAL_SETERROR(RTDAL_ERROR_NOTFOUND);
		return NULL;
	}

	return (r_itf_t) &context->physic_itfs[i];
}
Esempio n. 13
0
/**
 * Returns a handler to the first physical interface matching the name.
 * @param name Name of the physical interface
 * @return non-null value on success, zero on error
 */
r_itf_t rtdal_itfphysic_get(string name) {
	hdebug("name=%s\n",name);
	assert(context);
	RTDAL_ASSERT_PARAM_P(name);

	int i;
	for (i=0;i<MAX(rtdal_itfphysic);i++) {
		if (!strcmp(context->physic_itfs[i].parent.name, name))
			break;
	}
	hdebug("i=%d\n",i);

	if (i == MAX(rtdal_itfphysic)) {
		RTDAL_SETERROR(RTDAL_ERROR_NOTFOUND);
		return NULL;
	}
	return (r_itf_t) &context->physic_itfs[i];
}
Esempio n. 14
0
inline static void pipeline_run_thread_check_status(pipeline_t *pipe,
		rtdal_process_t *proc) {

	hdebug("pipeid=%d, pid=%d, run=%d, code=%d, waveform_notify=%d\n",pipe->id,proc->pid,
			proc->runnable,proc->finish_code, pgroup_notified_failure[proc->attributes.process_group_id]);
	if (proc->runnable && proc->finish_code != FINISH_OK &&
			!pgroup_notified_failure[proc->attributes.process_group_id]) {
		if (proc->attributes.finish_callback) {
			hdebug("calling finish 0x%x arg=0x%x\n",proc->attributes.finish_callback,
					proc->arg);
			pgroup_notified_failure[proc->attributes.process_group_id] = 1;
			rtdal_task_new(NULL, proc->attributes.finish_callback,proc->arg);
		} else {
			aerror_msg("Abnormal pid=%d termination but no callback was defined\n",
					proc->pid);
		}
	}
}
Esempio n. 15
0
/**
 * Adds a process to the pipeline. It is inserted in the position
 * min(n,exec_position) where n is the number of
 * elements in the spscq and exec_position is defined in the process attributes
 * used in the call to rtdal_process_new().
 * Returns the position it has finally been inserted.
 *
 *  @param obj Pointer to the pipeline_t object where the process is inserted
 *  @param process pointer to the rtdal_process_t object to insert.
 *  @returns non-negative integer number indicating the position it has been
 *  inserted, or -1 on error.
 */
int pipeline_add(pipeline_t *obj, rtdal_process_t *process) {
	hdebug("pipeid=%d, nof_process=%d, pid=%d, exec_pos=%d\n",obj->id,obj->nof_processes,
			process->pid,process->attributes.exec_position);
	RTDAL_ASSERT_PARAM(obj);
	RTDAL_ASSERT_PARAM(process);
	int exec_pos, i;
	rtdal_process_t *p = NULL;

	exec_pos = process->attributes.exec_position;

	/* head because empty list */
	if (!obj->first_process) {
		hdebug("pipeid=%d add pid=%d to head\n", obj->id, process->pid);
		obj->first_process = process;
		process->next = NULL;
		goto end;
	}
	/* head because first exec position */
	if (exec_pos < obj->first_process->attributes.exec_position) {
		hdebug("pipeid=%d add pid=%d to head\n", obj->id, process->pid);
		process->next = obj->first_process;
		obj->first_process = process;
		goto end;
	}
	/* middle */
	i=0;
	p = obj->first_process;
	while(p->next && exec_pos < p->next->attributes.exec_position) {
		p=p->next;
		i++;
	}
	process->next = p->next;
	p->next = process;

	hdebug("pipeid=%d, add pid=%d to pos=%d\n", obj->id, process->pid,i);

end:
	obj->nof_processes++;
	/* assign pipeline to object */
	process->pipeline = obj;

	return i;
}
Esempio n. 16
0
/**
 * Acknowledges that the process group error notification has been processed, enabling another
 * future call to the finish_callback function.
 * \returns 0 on success, -1 on error
 */
int rtdal_process_group_notified(r_proc_t proc) {
	RTDAL_ASSERT_PARAM(proc);
	rtdal_process_t *obj = (rtdal_process_t*) proc;
	hdebug("pid=%d, running=%d\n",obj->pid,obj->runnable);
	if (obj->attributes.process_group_id < 0 || obj->attributes.process_group_id > MAX_PROCESS_GROUP_ID) {
		RTDAL_SETERROR(RTDAL_ERROR_INVAL);
		return -1;
	}
	pgroup_notified_failure[obj->attributes.process_group_id] = 0;
	return 0;
}
Esempio n. 17
0
void pipeline_run_from_timer(void *arg, struct timespec *time) {
	pipeline_t *obj = (pipeline_t*) arg;
	time_t realtime;
#ifdef KERNEL_DEB_TIME
	rtdal_time_get(&realtime);
	hdebug("now is %d:%d\n",realtime.tv_sec,realtime.tv_usec);
#else
	hdebug("now is %d:%d\n",time->tv_sec,time->tv_nsec);
#endif

	if (!timer_first_cycle && time) {
		rtdal_time_reset_realtime(time);
		timer_first_cycle = 1;
	}

	if (!is_first_in_cycle()) {
		kernel_tslot_run();
	}

	pipeline_run_time_slot(obj);
}
Esempio n. 18
0
/**  Called from the sigwait kernel thread after a pipeline thread has died.
 * Set the process that caused the fault as non-runnable and create a new pipeline thread.
 */
int pipeline_recover_thread(pipeline_t *obj) {
	hdebug("pipeline_id=%d\n",obj->id);
	obj->finished = 1;
	if (rtdal_process_seterror((r_proc_t) obj->running_process, SIG_RECV)) {
		aerror("setting process error\n");
		return -1;
	}
	if (kernel_initialize_create_pipeline(obj, NULL)) {
		aerror("creating pipeline thread\n");
		return -1;
	}
	return 0;
}
Esempio n. 19
0
int rtdal_itfspscq_send(r_itf_t obj, void* buffer, int len) {
	cast(obj,itf);
	RTDAL_ASSERT_PARAM(buffer);
	RTDAL_ASSERT_PARAM(len>=0);

	int n;
	void *ptr;

	if (len > itf->max_msg_sz) {
		RTDAL_SETERROR(RTDAL_ERROR_LARGE);
		return -1;
	}

	hdebug("requesting pkt for 0x%x\n",obj);
	if ((n = rtdal_itfspscq_request(obj, &ptr)) != 1) {
		return n;
	}

	memcpy(ptr, buffer, (size_t) len);

	hdebug("put pkt for 0x%x pkt 0x%x\n",obj,ptr);
	return rtdal_itfspscq_push(obj,len,rtdal_time_slot());
}
Esempio n. 20
0
inline static void pipeline_run_thread_run_module(pipeline_t *pipe,
		rtdal_process_t *proc, int idx) {
	hdebug("pipeid=%d, pid=%d, idx=%d, run=%d\n",pipe->id,proc->pid,idx,proc->runnable);
	if (proc->runnable) {
		pipe->running_process = proc;
		pipe->running_process_idx = idx;
		proc->is_running = 1;
		if (proc->run_point(proc->arg)) {
			aerror_msg("Error running module %d:%d\n",
					pipe->id,pipe->running_process_idx);
			pipeline_remove(pipe,proc);
			proc->is_running = 0;
		}
		proc->is_running = 0;
	}
}
Esempio n. 21
0
/**  Called when there is an rtfault in the pipeline
 */
int pipeline_rt_fault(pipeline_t *obj) {
#ifdef KILL_RT_FAULT
	hdebug("pipeline_id=%d, process_idx=%d\n",obj->id,obj->running_process_idx,obj->running_process_idx);
	obj->finished = 1;
	aerror_msg("RT-Fault detected at pipeline %d, process %d\n",obj->id,
			obj->running_process_idx);
	if (obj->thread) {
		int s = pthread_kill(obj->thread,SIGUSR1);
		if (s) {
			rtdal_POSERROR(s, "pthread_kill");
			return -1;
		}
	}
#else
	obj->finished = 1;
	printf("+++[ts=%d]+++ RT-Fault: Process %d/%d still running in pipeline %d\n",
			obj->ts_counter, obj->running_process_idx, obj->nof_processes, obj->id);
#endif
	return 0;
}
Esempio n. 22
0
/**
 * Removes the function pointed by callback from the kernel periodic callback functions,
 * previously added with rtdal_periodic_add().
 *
 * @param callback Pointer to the periodic function
 * @returns zero on success, -1 on error
 */
int rtdal_periodic_remove(void (*callback)(void)) {
	assert(context);
	RTDAL_ASSERT_PARAM(callback);

	int i;
	pthread_mutex_lock(&context->mutex);
	for (i=0;i<MAX(rtdal_periodic);i++) {
		if (context->periodic[i].callback == callback)
			break;
	}

	if (i == MAX(rtdal_periodic)) {
		RTDAL_SETERROR(RTDAL_ERROR_NOTFOUND);
		return -1;
	}
	context->periodic[i].counter = 0;
	context->periodic[i].period = 0;
	context->periodic[i].callback = NULL;
	pthread_mutex_unlock(&context->mutex);
	hdebug("i=%d\n",i);
	return 0;
}
Esempio n. 23
0
/**
 * This is a thread with priority kernel_prio that synchronously waits for
 * rtdal_pipeline signals (usign sigwaitinfo). All signals except thread-specific
 * ones (SIGSEGV,SIGILL,SIGBUS,SIGFPE) are blocked by all threads except this one.
 * Thread-specific signals are handled by ProcThreads which send a SIGRTMIN+1,
 * SIGRTMIN+2,SIGRTMIN+3,SIGRTMIN+4 (respectively) to this thread, which takes
 * actions accordingly.
 *
 * for signals SIGRTMIN to SIGRTMIN+4, cast the rtdal_pipeline object from this
 * si_value pointer and call rtdal_pipeline_recover_thread(pipeline,
 * pipeline->running_process, TRUE)
 */
void sigwait_loop(void) {

	int signum;
	sigset_t set;
	siginfo_t info;

	sigfillset(&set);
	sigdelset(&set,TASK_TERMINATION_SIGNAL);
	while(!sigwait_stops) {
		do {
			signum = sigwaitinfo(&set, &info);
		} while (signum == -1 && errno == EINTR);
		if (signum == -1) {
			poserror(errno, "sigwaitinfo");
			goto out;
		}
		hdebug("detected signal %d\n",signum);
		if (signum == KERNEL_SIG_THREAD_SPECIFIC) {
			printf("[rtdal]: Caught thread-specific signal\n");
#ifdef EXIT_ON_THREADSIG
			fflush(stdout);
			goto out;
#else
			sigwait_loop_process_thread_signal(&info);
#endif
		} else if (signum == SIGINT) {
			printf("Caught SIGINT, exiting\n");
			fflush(stdout);
			goto out;
		} else if (signum != SIGWINCH && signum != SIGCHLD) {
			printf("Got signal %d, exiting\n", signum);
			fflush(stdout);
			goto out;
		}
	}

out:
	kernel_exit();
}
Esempio n. 24
0
static int sigwait_loop_process_thread_signal(siginfo_t *info) {
	int thread_id, signum;

	signum = info->si_value.sival_int & 0xffff;
	thread_id = info->si_value.sival_int >> 16;
	hdebug("signum=%d, thread_id=%d\n",signum,thread_id);
	if (signum < N_THREAD_SPECIFIC_SIGNALS) {
		snprintf(tmp_msg, STR_LEN, "[rtdal]: Got signal %s from ",
				thread_specific_signals_name[signum]);
	} else {
		snprintf(tmp_msg, STR_LEN, "[rtdal]: Got unknown signal from ");
	}

	/* now try to restore the pipeline, if the thread was a pipeline */
	if (thread_id > -1) {
		if (strnlen(tmp_msg,STR_LEN)>1) {
			snprintf(&tmp_msg[strlen(tmp_msg)-1],STR_LEN,
					" pipeline thread %d. Current running process idx is %d\n",
					thread_id,
					rtdal.pipelines[thread_id].running_process_idx);
		}
#ifdef RECOVER_THREAD
		if (pipeline_recover_thread(
				&rtdal.pipelines[thread_id])) {
			aerror("recovering pipeline thread\n");
		}
#endif

	} else if (info->si_value.sival_int == -1) {
		strcat(tmp_msg, " the kernel thread\n");
		kernel_timer_recover_thread();
	} else {
		strcat(tmp_msg, " an unkown thread\n");
	}
	write(0,tmp_msg,strlen(tmp_msg));
	return 1;
}
Esempio n. 25
0
void pipeline_initialize(int _num_pipelines) {
	hdebug("num_pipelines=%d\n",_num_pipelines);
	num_pipelines = _num_pipelines;
	pipeline_sync_initialize_;
}
Esempio n. 26
0
/**
 * Returns 1 if the process is running or zero otherwise
 */
int rtdal_process_isrunning(r_proc_t proc) {
	RTDAL_ASSERT_PARAM(proc);
	rtdal_process_t *obj = (rtdal_process_t*) proc;
	hdebug("pid=%d, running=%d\n",obj->pid,obj->runnable);
	return obj->is_running;
}
Esempio n. 27
0
/**
 * Handler for thread-specific signals (SIGSEGV,SIGILL,SIGFPE,SIGBUS).
 * Forwards a signal above SIGRTMIN to myself. Since it is blocked, it will
 * be received by sigwait_loop(), which is runs in the main kernel thread.
 *
 * The thread terminates after exiting the handler.
 */
void thread_signal_handler(int signum, siginfo_t *info, void *ctx) {
	union sigval value;
	int thread_id;
	int i;

#ifdef PRINT_BT_ON_SIGSEGV
	if (signum == SIGSEGV) {
		signal_segv(signum,info,ctx);
	}
#endif

	signal_received++;
	thread_id = -1;

	hdebug("[ts=%d] signal %d received\n",rtdal_time_slot(),signum);

	/* try to find the thread that caused the signal */

	/** todo: Caution!! is pthread_self() safe in the handler?
	 * it is not async-signal-safe by the standard,
	 * but the signals are synchronous.
	 */
	pthread_t thisthread = pthread_self();

	/* if signum is SIGUSR2, its a task termination signal, just exit */
	if (signum == TASK_TERMINATION_SIGNAL) {
		hdebug("sigusr2 signal. thread=%d\n",thisthread);
		goto cancel_and_exit;
	}

	/* is it a pipeline thread? */
	for (i=0;i<rtdal.machine.nof_cores;i++) {
		if (thisthread == rtdal.pipelines[i].thread) {
			break;
		}
	}
	if (i < rtdal.machine.nof_cores) {
		hdebug("pipeline_idx=%d\n",i);
		thread_id = i;

		/* set the thread to 0 because is terminating */
		rtdal.pipelines[thread_id].thread = 0;
	} else {
		/* it is not, may be it is the kernel timer */
		if (thisthread == single_timer_thread) {
			hdebug("timer thread=%d\n",thisthread);
			thread_id = -1;
		} else {
			/* @TODO: check if it is a status or init thread of any module */

			hdebug("other thread=%d\n",thisthread);
			goto cancel_and_exit;
		}
	}

	/* Now send a signal to the kernel */
	for (i=0;i<N_THREAD_SPECIFIC_SIGNALS;i++) {
		if (thread_specific_signals[i] == signum)
			break;
	}
	hdebug("signal=%d, thread=%d\n",i,thread_id);
	value.sival_int = thread_id<<16 | i;
	if (sigqueue(kernel_pid,
			KERNEL_SIG_THREAD_SPECIFIC,
			value)) {
		poserror(errno, "sigqueue");
	}

cancel_and_exit:
	if (signum != SIGABRT || thread_id == -1) {
		pthread_exit(NULL);
	} else {
		rtdal.pipelines[thread_id].waiting=1;
		while(rtdal.pipelines[thread_id].waiting) {
			hdebug("waiting\n",0);
			usleep(1000);
		}
	}
}