[Date Prev][Date Next] [Chronological] [Thread] [Top]

No Subject



From: Aleksandar Bakic <bakicale@brazil.tcimet.net>
Subject: communication under RTL (was bounced back)
Message-ID: <m2r9g5tu2o.fsf@brazil.tcimet.net>
Lines: 183
X-Mailer: Gnus v5.7/Emacs 20.4

> What code is sending the packets and how are they received (I mean user
> space application, or some kernel code?)

Most of the network traffic is incoming (99.99...%). There is a server
application (in user space) that receives the data and stores it in
the shared memory, accessible to RT tasks for processing.

> I guess you should somehow allow network interrupt to be serviced while
> your RT task is running. How much time is your RT task taking?

That was my idea. I modified the rate-monotonic scheduler (the
original is available on the RTL web page), so that rt_linux_task (the
Linux kernel) is assigned a period, just like the RT tasks. For a
start, I set this period to 20ms, while the RT tasks had periods of
50ms and 500ms (two sets of them, currently). Each time the
rt_linux_task preempts another task, I set the timer to call
rt_schedule() after, say, 2ms (it is possible that some delayed RT
task has sooner resume_time, so that the 2ms is the upper bound of
time that rt_linux_task has available). When the following call to
rt_schedule() is made, rt_linux_task is made delayed (from ready), so
that the RT tasks can continue to run. This idea seems to work for
some values of the period and "demand"... I am attaching chunks of the
modified code (look for "AMB") in rt_monotonic_sched.c; I admit I am
not 100% sure about the interrupt and flag "fix".

> Tomek

Thanks!
Aleks

void 
rt_schedule(void)
{
	RTIME now;
	RTIME preemption_time;
	RT_TASK *task;
	RT_TASK *new_task;
	RT_TASK *preemptor;
	RTIME 	shortest_period;

	int flags, flags2; /* AMB */

	r_save_flags(flags);
	save_flags(flags2); /* AMB */
	r_cli();
	cli(); /* AMB */

	now = rt_get_time(); /* moved up by AMB */
#ifdef DEBUG
	if (rt_current->identifier != -1) {
	    debug.state = EXEC;
	    debug.id    = rt_current->identifier;
	    debug.in    = init_time;
	    debug.out   = now;
	    rtf_put(DEBUG_FIFO, (char *) &debug,  sizeof(debug));
	}
#endif	

	for (task = rt_tasks; task; task = task->next)
	  {
	    if (task->state == RT_TASK_DELAYED && 
		task->resume_time < (now+10))
	      {
		task->state = RT_TASK_READY;
	      }
	  }
	new_task = 0; /* &rt_linux_task; AMB */

/* begin rate-monotonic scheduling    */
	shortest_period = RT_BIGGEST_PERIOD; /* rt_linux_task.period; AMB */

	/* AMB begin */
	if ((rt_current == &rt_linux_task) &&
	    (rt_linux_task.priority == RT_LOWEST_PRIORITY))
	  {
	    rt_linux_task.state = RT_TASK_DELAYED;
	    rt_linux_task.priority = RT_LOWEST_PRIORITY - 1;
	    rt_linux_task.resume_time += rt_linux_task.period;
	  }
	/* AMB end */
      
	for (task = rt_tasks; task; task = task->next)
	  {
	    if (task->state == RT_TASK_READY && 
	        task->period < shortest_period)
	      {
		new_task = task;
		shortest_period = task->period;
	      }
	  }

 	preemptor = 0;
	preemption_time = RT_TIME_END;
	/* AMB begin */
	if (new_task == &rt_linux_task)
	  {
	    rt_linux_task.priority = RT_LOWEST_PRIORITY;
	    preemptor = &rt_linux_task;
	    preemption_time = now + RT_TICKS_PER_SEC / 100;
	  }
	/* AMB end */
	for (task = rt_tasks; task; task = task->next)
	  {
	    if (task->state == RT_TASK_DELAYED && 
	        task->resume_time < preemption_time)
	      {
		preemption_time = task->resume_time;
	    	preemptor = task;
	      }
	  }

	/* AMB begin */
	if (new_task == 0)
	  {
	    rt_linux_task.state = RT_TASK_READY;
	    rt_linux_task.priority = RT_LOWEST_PRIORITY - 2;
	    new_task = &rt_linux_task;
	  }
	/* AMB end */

/* End of rate-monotonic scheduler */

	if (preemptor)
	  {
	    rt_set_timer(preemption_time);
	  }
	else
	  {
	    rt_no_timer();
	  }
	
	if (new_task == rt_current)
	  {
	    if (rt_current != &rt_linux_task)
	      rt_current->resume_time += rt_current->period; /* AMB */
	    r_restore_flags(flags);
	    restore_flags(flags2); /* AMB */
	    return;
	  }

	if (new_task == &rt_linux_task)
	  {
	    SFIF = linux_irq_state;
	  }
	else
	  if (rt_current == &rt_linux_task)
	    {
	      linux_irq_state = SFIF;
	      SFIF = 0;
	    }

#ifdef DEBUG
	if (new_task->identifier != -1)	{	/* Monotonic scheduler */
		init_time = now;
	}
#endif

	new_task->state = RT_TASK_READY;
	rt_switch_to(new_task);
	r_restore_flags(flags);
	restore_flags(flags2); /* AMB */
}

int 
init_module(void)
{
#ifdef DEBUG
	rtf_create(DEBUG_FIFO, 4000);
#endif
	rt_tasks = &rt_linux_task;
	rt_current = &rt_linux_task;
	rt_linux_task.priority = RT_LOWEST_PRIORITY - 1; /* AMB */
	rt_linux_task.period   = RT_TICKS_PER_SEC / 50; /* RT_BIGGEST_PERIOD; AMB */
	rt_linux_task.resume_time = rt_get_time(); /* AMB */
	rt_linux_task.next = 0;
	rt_linux_task.identifier = -1; /* Monotonic */
	rt_linux_task.state = RT_TASK_READY;
	rt_request_timer(&rt_schedule);
	return 0;
}

--CAA13150.945846827/brazil.tcimet.net--
------- End of forwarded message -------
--- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail majordomo@rtlinux.cs.nmt.edu OR
echo "unsubscribe rtl <Your_email>" | mail majordomo@rtlinux.cs.nmt.edu
----
For more information on Real-Time Linux see:
http://www.rtlinux.org/~rtlinux/