Re: Best way for start a rt-thread and wait

Der Herr Hofrat <[email protected]> Fri, 28 Jan 2005 06:47:17 +0100 (CET)
Newsgroups gmane.linux.real-time.rtlinux.general
Message-ID <[email protected]>
> 	<mailto:[email protected]?subject=subscribe>
> Sender: [email protected]
> Errors-To: [email protected]
> Status: RO
> 
> Hi all...
> 
> 
>  I need to start a rt-thread from user space, wait for the rt-thread to
> complete his job and return a result in user space...
> 
>  in order to do this, I've created a rt-fifo and linked the user space
> ioctl with the rtf_link_user_ioctl() function.
> 
> the problem is that sometimes my ioctl code put the user process to
> sleep and never wake it up.
> 
> is there a best way to achieve this kind of functionality ?
> 
>
not sure if its better or not - but an alternative would be to use the proc filesystem - here is a modified version of proc_start_stop.c that allows
loading in an inactive state-starting via user-space task and then controlling the termination through the proc filesystem - to descide when to terminate you can monitor the status via the proc file aswell.

 
/* vim: set ts=4: */
/*
 * Copyrite 2004 Der Herr Hofrat
 * License GPL V2
 * Author [email protected]
 */
/*
 * control a rt-thread via /proc/thread_status
 * to launche it use : echo 1 > /proc/thread_status
 * to stop it use: echo 0 > /proc/thread_status
 * to retriev status use : cat /proc/thread_status
 */

#include <rtl.h>
#include <time.h>
#include <rtl_time.h>
#include <pthread.h>
#include <linux/proc_fs.h> /* create_proc_entry remove_proc_entry */

pthread_t thread;
hrtime_t start_nanosec;

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Der Herr Hofrat");
MODULE_DESCRIPTION("simple proc example");

static int running=0; /* start by echo 1 > /proc/thread_status */
struct proc_dir_entry *proc_thread_status;

void * start_routine(void *arg)
{
	int i=0;
	struct sched_param p;
	hrtime_t elapsed_time,now;
	p . sched_priority = 1;
	pthread_setschedparam (pthread_self(), SCHED_FIFO, &p);

	pthread_make_periodic_np (pthread_self(), gethrtime(), 500000000);
	pthread_kill(pthread_self(),RTL_SIGNAL_SUSPEND);
	rtl_schedule();
	pthread_testcancel();
	while (running) {
		pthread_wait_np ();
		now = clock_gethrtime(CLOCK_REALTIME);
		elapsed_time = now - start_nanosec;
		rtl_printf("elapsed_time = %Ld\n",(long long)elapsed_time);
		i++;
	}
	return (void *)i;
}

int 
get_status(
	char *page,
	char **start, 
	off_t off, 
	int count,
	int *eof, 
	void *data)
{
	int size = 0;
    
	MOD_INC_USE_COUNT;
	
	size+=sprintf(page+size,"Thread State:%d\n",(int)running);

	MOD_DEC_USE_COUNT;
	return(size);
}

static int 
set_status(
	struct file *file, 
	const char *user_buffer,
	unsigned long count, 
	void *data)
{
	MOD_INC_USE_COUNT;

	/* brute force atoi - values should be checked in real apps */
	if((int)*user_buffer-'0'){
		pthread_kill(thread,RTL_SIGNAL_WAKEUP);
		rtl_schedule();
	} else {
		running=(int)*user_buffer-'0';
	}
	printk("terminating rt-thread - set running to %x\n",running);

	MOD_DEC_USE_COUNT;
	return count;
}
  
int init_module(void) {
	int retval;
	start_nanosec = clock_gethrtime(CLOCK_REALTIME);
	retval = pthread_create (&thread, NULL, start_routine, 0);
	if(retval){
		printk("pthread create failed\n");
		return -1;
	}
	proc_thread_status = create_proc_entry("thread_status",
        S_IFREG | S_IWUSR,
        &proc_root);

	proc_thread_status->read_proc = get_status;
	proc_thread_status->write_proc = set_status;
	return 0;
}

void cleanup_module(void) {
	void * ret_val;
	pthread_cancel(thread);
	pthread_kill(thread,RTL_SIGNAL_WAKEUP);
	rtl_schedule();
	pthread_join(thread,&ret_val);
	printk("Thread terminated with %d\n",(int)ret_val);
    	remove_proc_entry("thread_status", &proc_root);
}
_______________________________________________
Rtl mailing list
[email protected]
http://www2.fsmlabs.com/mailman/listinfo/rtl