/* ================================================================= * This program has two tasks switching control back-and-forth * to demonstrate suspend/resume and semaphores. In order to * be doing something useful, they implement a stock producer * consumer process with the producer creating data and the consumer * outputting it. * * * ================================================================= */ #include #include #include #include #include #include MODULE_DESCRIPTION("Producer-Consumer"); MODULE_AUTHOR("Gary Harkin"); MODULE_LICENSE("GPL"); #define STACK_SIZE 4000 MODULE_PARM(stack_size, "i"); MODULE_PARM_DESC(stack_size, "Task stack size in bytes (default: 4000)"); #define SEM_TYPE (CNT_SEM | FIFO_Q) #define FIFO 0 #define TASK_PRIORITY 1 static RT_TASK prod_task, cons_task; static SEM sem; static int start_seed = 3452; static int sh_value; static SEM pc_sem; static void prod_proc (int dummy) { int val; int seed; seed = start_seed; while (1) { /* * Wait an amount of time using the busy wait. */ rt_busy_sleep (2000000000); /* * Create a value */ val = seed << 16; val = seed >> 24; val = val * val; seed = val; /* * Output the value */ printk ("Producing a %ld\n", val); /* * Put the data in the shared memory location. */ sh_value = val; /* * Now wakeup consumer and suspend self to wait for a wakeup */ rt_task_resume (&cons_task); rt_task_suspend (&prod_task); /* * * rtf_put sends a character buffer to the fifo * the fifo identifier * a pointer to the buffer * the size of the buffer (useable data) */ /* rtf_put (FIFO, &interval, sizeof (interval)); rtf_put (FIFO, &error, sizeof (error)); */ /* * That was fun, lets do it again. * rt_task_wait_period suspends this task until the next period is * reached. */ } } static void cons_proc (int dummy) { int val; while (1) { /* * Wait a time with a busy wait. */ rt_busy_sleep (1000000000); /* * Read a value from shared memory */ val = sh_value; /* * Output the value */ printk ("Consuming a %ld\n", val); /* * Now wakeup producer and suspend self to wait for a wakeup */ rt_task_resume (&prod_task); rt_task_suspend (&cons_task); /* * * rtf_put sends a character buffer to the fifo * the fifo identifier * a pointer to the buffer * the size of the buffer (useable data) */ /* rtf_put (FIFO, &interval, sizeof (interval)); rtf_put (FIFO, &error, sizeof (error)); */ /* * That was fun, lets do it again. * rt_task_wait_period suspends this task until the next period is * reached. */ } } int init_module (void) { RTIME tick_period; /* Create the FIFO buffer * rtf_create creates the fifo * FIFO is the fifo ID * the size of the fifo in bytes */ // rtf_create (FIFO, 4000); /* * Create a semaphore * rt_sem_init * the address of the semaphore structure, * the initial value which is usually 1 */ rt_sem_init(&sem, 1); /* * Create two tasks and then start the producer. */ rt_task_init (&prod_task, prod_proc, 1, STACK_SIZE, TASK_PRIORITY, 0, 0); rt_task_init (&cons_task, cons_proc, 1, STACK_SIZE, TASK_PRIORITY, 0, 0); rt_task_resume (&prod_task); return 0; } void cleanup_module (void) { /* * Stop the timer and dispose of the fifo and task. */ // stop_rt_timer (); // rtf_destroy (FIFO); rt_task_delete (&prod_task); rt_task_delete (&cons_task); return; }