#include <linux/module.h>
#include <rtai.h>
#include <rtai_sched.h>
#include <rtai_sem.h>

#define STACK_SIZE 4096
#define TIMERTICKS 100000000 /*  .1 second */
#define ONE_SECOND 1000000000
#define HIGH_PRIO 50
#define LOW_PRIO 100

/* Semaphore demo */

static RT_TASK task_l, task_h;
static SEM flag;
RTIME tick_period;

static void led_on(int n)
{
	outb(inb(0x378)|(1 << n), 0x378);
}

static void led_off(int n)
{
	outb(inb(0x378) & ~(1 << n), 0x378);
}

static void taskh_code(int t)
{
	rt_sem_wait(&flag);
	led_on(3);
	rt_sem_signal(&flag);
}

static void taskl_code(int t)
{
	int i;
	rt_sem_wait(&flag);
	led_on(0);
	for(i = 0; i < 10; i++)
		rt_sleep(10*tick_period);
	rt_sem_signal(&flag);
	led_off(0);
}


int init_module(void)
{
	RTIME  now;

	rt_set_periodic_mode();
	rt_sem_init(&flag, 1);
	rt_task_init(&task_l, taskl_code, 0, STACK_SIZE, LOW_PRIO, 0, 0);
	rt_task_init(&task_h, taskh_code, 0, STACK_SIZE, HIGH_PRIO, 0, 0);

	tick_period = start_rt_timer(nano2count(TIMERTICKS));
	now = rt_get_time();
	rt_task_make_periodic(&task_l, now + tick_period, tick_period);
	rt_task_make_periodic(&task_h, now + 2*tick_period, tick_period);
	return 0;
}

void cleanup_module(void)
{
	stop_rt_timer();
	rt_busy_sleep(10000000);

	rt_task_delete(&task_l);
	rt_task_delete(&task_h);
}
