void rtl_schedule(void)
{
	RTIME now;
	RT_TASK *t;
	RT_TASK *newt = 0; /* new task to run, if any */
	RT_TASK *nextt = 0; /* task that will preempt, if any */
	unsigned long interrupt_state;

	rtl_no_interrupts(interrupt_state);
	now = GETTIME();

        /* find a task that can be run  */
	for (t = rtl_tasks; t; t = t->next) {
		if( (t->state == RT_TASK_DELAYED)&&
				( t->resume_time < now + ADJUSTUP)){
		   t->state = RT_TASK_READY;
		}
		if(t->state == RT_TASK_READY)
			if (!newt || (t->priority < newt->priority)) {
				newt = t;
			}
	}
	/* find the pre-empting task */
	for (t = rtl_tasks; t; t = t->next) {
		if( (t->state == RT_TASK_DELAYED) &&
				(!newt || (t->priority < newt->priority)) &&
				(!nextt ||(t->resume_time < nextt->resume_time))
				)
			nextt = t;
	}

				

	/* DEBUG */
	{
		static int nolinux = 0;
		if(newt) nolinux++;
		else nolinux = 0;
		if(nolinux > 100000){
			conpr("HELP NO LINUX EVER!!!");
			nolinux = 0;
			newt->resume_time = now+100000;
		}
	}
	/* END DEBUG */


	/* if nextt there is a preemptor so set timer to preempt
	   if !nextt
	        if there is a rt task, turn off the timer
		if there is no rt task, linux needs a clock interrupt
		*/
	if (nextt) {
		rt_set_timer(nextt->resume_time - ADJUSTDOWN ); 
	} else {
	       	if (newt) { rt_no_timer(); }
		else { rt_set_timer(now+LATCH);}
	}

	/* if there is no rt task to run, then run linux */
	if (!newt){
		newt = &rtl_linux_task;
		rtl_make_unrtactive();
	} else {
		rtl_make_rtactive();
	}
	/* if the new task is the current task nothing to do */
	if (newt == rtl_current) {
		rtl_restore_interrupts(interrupt_state);
		return;
	} else	{ /*else switch out old, switch in new */

		rtl_switch_to(newt); /* switch the integer registers and the control flow */

		/* delay switching the FPU context until it is really needed */
		/* this trick works for uniprocessors and SMP with no RT-task migration (?) */
		if (rtl_current -> uses_fp && rtl_task_fpu_owner != rtl_current) {
			if (rtl_task_fpu_owner) {
/* 				conpr("s"); */
				rtl_fpu_save (rtl_task_fpu_owner);
			}
/* 			conpr("r"); */

			rtl_fpu_restore (rtl_current);
			rtl_task_fpu_owner = rtl_current;
		}
		rtl_restore_interrupts(interrupt_state);
	}
	if (rtl_is_linux_task (rtl_current)) {
		/* it is safe to do if we require that rt_task_delete() is called from Linux */
		/* but it's probably better to use task queues anyway */
		rtl_delete_zombies();
	}
}
