diff -BbNru sigtim_rt/include/rtl_sched.h exetimers_rt/include/rtl_sched.h --- sigtim_rt/include/rtl_sched.h 2004-03-02 10:20:35.000000000 -0800 +++ exetimers_rt/include/rtl_sched.h 2004-03-02 12:45:23.000000000 -0800 @@ -72,6 +72,10 @@ hrtime_t resume_time; hrtime_t period; hrtime_t timeval; +#ifdef CONFIG_OC_EXECTIMERS + hrtime_t last_activation; + clockid_t cpuclock; +#endif struct module *creator; void (*abort)(void *); void *abortdata; @@ -86,6 +90,10 @@ void *tsd [RTL_PTHREAD_KEYS_MAX]; }; +#ifdef CONFIG_OC_EXECTIMERS +#define _POSIX_CPUTIME +#endif + #define RTL_POSIX_DATA(th) (&(th)->posix_data) #define hrt2ts(hrt) ((const struct timespec *) ({ pthread_self()->timeval = hrt; (&pthread_self()->timeval); })) diff -BbNru sigtim_rt/include/rtl_time.h exetimers_rt/include/rtl_time.h --- sigtim_rt/include/rtl_time.h 2004-03-02 10:20:35.000000000 -0800 +++ exetimers_rt/include/rtl_time.h 2004-03-02 12:45:23.000000000 -0800 @@ -50,7 +50,11 @@ typedef void (* clock_irq_handler_t)(struct pt_regs *r); enum { RTL_CLOCK_MODE_UNINITIALIZED = 1, RTL_CLOCK_MODE_ONESHOT, -RTL_CLOCK_MODE_PERIODIC}; +RTL_CLOCK_MODE_PERIODIC +#ifdef CONFIG_OC_EXECTIMERS +,RTL_CLOCK_MODE_EXECTIME +#endif +}; struct rtl_clock { int (*init) (struct rtl_clock *); diff -BbNru sigtim_rt/include/rtl_timer.h exetimers_rt/include/rtl_timer.h --- sigtim_rt/include/rtl_timer.h 2004-03-02 10:20:35.000000000 -0800 +++ exetimers_rt/include/rtl_timer.h 2004-03-02 12:45:23.000000000 -0800 @@ -75,6 +75,12 @@ if (t->clock_id == CLOCK_MONOTONIC && mode == RTL_CLOCK_MODE_PERIODIC){ now=clock_gethrtime(CLOCK_MONOTONIC); } +#ifdef CONFIG_OC_EXECTIMERS + if (t->clock_id->mode == RTL_CLOCK_MODE_EXECTIME){ + now=clock_gethrtime(t->owner->cpuclock); + } +#endif + return (now>=t->expires.it_value) ? 1 : 0; } diff -BbNru sigtim_rt/schedulers/Makefile exetimers_rt/schedulers/Makefile --- sigtim_rt/schedulers/Makefile 2004-03-02 10:20:35.000000000 -0800 +++ exetimers_rt/schedulers/Makefile 2004-03-02 12:45:23.000000000 -0800 @@ -23,11 +23,11 @@ depend: rtl_sched.o $(CC) ${INCLUDE} ${CFLAGS} -M rtl_sched.c > .depends -rtl_sched.o: rtl_sched_tmp.o switch.o sw.o rtl_mutex.o unistd.o signal.o rtl_sema.o rtl_posix.o rtl_timer.o $(LIBGCC) - $(LD) $(LDFLAGS) -r -o rtl_sched.o rtl_sched_tmp.o switch.o sw.o rtl_mutex.o unistd.o signal.o rtl_sema.o rtl_posix.o rtl_timer.o -static ${LIBGCC} +rtl_sched.o: rtl_sched_tmp.o switch.o sw.o rtl_mutex.o unistd.o signal.o rtl_sema.o rtl_posix.o rtl_timer.o rtl_cpuclocks.o $(LIBGCC) + $(LD) $(LDFLAGS) -r -o rtl_sched.o rtl_sched_tmp.o switch.o sw.o rtl_mutex.o unistd.o signal.o rtl_sema.o rtl_posix.o rtl_timer.o rtl_cpuclocks.o -static ${LIBGCC} cp -f rtl_sched.o ../modules/ -rtl_sched_tmp.o: rtl_sched.c ../include/rtl_sched.h +rtl_sched_tmp.o: rtl_sched.c ../include/rtl_sched.h ../include/rtl_cpuclocks.h $(CC) ${INCLUDE} ${CFLAGS} -o rtl_sched_tmp.o -c rtl_sched.c rtl_compat.o: rtl_compat.c ../include/rtl_sched.h @@ -52,6 +52,10 @@ rtl_timer.o: rtl_timer.c ../include/rtl_timer.h $(CC) ${INCLUDE} ${CFLAGS} -o rtl_timer.o -c rtl_timer.c +rtl_cpuclocks.o: rtl_cpuclocks.c ../include/rtl_cpuclocks.h + $(CC) ${INCLUDE} ${CFLAGS} -o rtl_cpuclocks.o -c rtl_cpuclocks.c + + install: rtl_sched.o install -c -m 644 rtl_sched.o ${RTL_DIR}/modules diff -BbNru sigtim_rt/schedulers/rtl_sched.c exetimers_rt/schedulers/rtl_sched.c --- sigtim_rt/schedulers/rtl_sched.c 2004-03-02 10:20:35.000000000 -0800 +++ exetimers_rt/schedulers/rtl_sched.c 2004-03-02 12:45:23.000000000 -0800 @@ -21,6 +21,7 @@ * Fixed long long casting in usleep P. Mendoza & J. Vidal (OCERA) * See example/bug directory for more info. * Thanks to I.Ripoll, P. Mendoza & P. Perez. + * Added POSIX cpu clocks & timers support - Dec, 2003 Josep Vidal (OCERA) */ #include @@ -46,6 +47,10 @@ #ifdef CONFIG_OC_PTIMERS #include #endif +#ifdef CONFIG_OC_EXECTIMERS +#include +#endif + static spinlock_t rtl_tqueue_lock; static int rtl_sched_irq; @@ -236,6 +241,15 @@ static void rtl_task_free_memory(void *p) { struct rtl_thread_struct *task = (struct rtl_thread_struct *) p; + +#ifdef CONFIG_OC_EXECTIMERS + if (task->cpuclock){ + //rtl_printf("before freeing stack, cpuclock struct %p\n", task->cpuclock); + kfree(task->cpuclock); + task->cpuclock=0; + } +#endif + if (task->kmalloc_stack_bottom) { /* rtl_printf("freeing %#x %#x\n", task->kmalloc_stack_bottom); */ kfree (task->kmalloc_stack_bottom); @@ -354,6 +369,10 @@ timer_t timer =0; hrtime_t preempt_time=HRTIME_INFINITY; #endif +#ifdef CONFIG_OC_EXECTIMERS + hrtime_t now=s->clock->gethrtime(s->clock); + hrtime_t aux=0; +#endif for (t = s->rtl_tasks; t; t = t->next) { if (test_bit(RTL_THREAD_TIMERARMED, &t->threadflags)) { @@ -378,6 +398,18 @@ } } } else { /* timer list is ordered by owner priority */ +#ifdef CONFIG_OC_EXECTIMERS + if( TIMER_ARMED(timer)){ + /* chosen task execution time credit will expire before leaving CPU? */ + if (timer->clock_id->mode == RTL_CLOCK_MODE_EXECTIME && timer->owner == chosen){ + aux=now + timer->expires.it_value - clock_gethrtime(timer->owner->cpuclock); + if ( aux < preempt_time ) { + preempt_time=aux; + // rtl_printf("task execution time credit will expire at %u s %u ns. NOW: %u s %u ns \n", (unsigned) ( aux / NSECS_PER_SEC ), (unsigned)(aux % NSECS_PER_SEC),(unsigned)( now / NSECS_PER_SEC ),(unsigned) ( now % NSECS_PER_SEC)); + } + } + } +#endif break; } } @@ -543,6 +575,13 @@ goto idle; } +#ifdef CONFIG_OC_EXECTIMERS + if (sched->rtl_current->cpuclock && sched->rtl_current->last_activation){ + sched->rtl_current->cpuclock->value+=now - sched->rtl_current->last_activation; + } + new_task->last_activation=now; +#endif + if (sched->clock->mode == RTL_CLOCK_MODE_ONESHOT && !test_bit (RTL_SCHED_TIMER_OK, &sched->sched_flags)) { if ( (preempt_time = find_preemptor(sched,new_task))) { (sched->clock)->settimer(sched->clock, preempt_time - now); @@ -723,6 +763,13 @@ task->cleanup = 0; task->resume_time = HRTIME_INFINITY; + +#ifdef CONFIG_OC_EXECTIMERS + task->last_activation= 0; + if (init_cpuclock(&task->cpuclock) != 0 ) { + return EAGAIN; + } +#endif task->period = 0; task->sched_param = attr->sched_param; task->stack = stack_addr + stack_size / sizeof(int); @@ -992,6 +1039,10 @@ s -> rtl_linux_task . creator = 0; s -> rtl_linux_task . abort = 0; +#ifdef CONFIG_OC_EXECTIMERS + s -> rtl_linux_task . last_activation= 0; + s -> rtl_linux_task . cpuclock = 0; +#endif s -> rtl_task_fpu_owner = &s->rtl_linux_task; s -> sched_flags = 0; rtl_posix_init (&s->rtl_linux_task); diff -BbNru sigtim_rt/schedulers/rtl_timer.c exetimers_rt/schedulers/rtl_timer.c --- sigtim_rt/schedulers/rtl_timer.c 2004-03-02 10:20:35.000000000 -0800 +++ exetimers_rt/schedulers/rtl_timer.c 2004-03-02 12:45:23.000000000 -0800 @@ -32,8 +33,12 @@ return -1; } - // for now, only CLOCK_REALTIME & CLOCK_MONOTONIC. - if (clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC){ + // for now, only CLOCK_REALTIME, CLOCK_MONOTONIC & EXECUTION TIME CLOCKS. + if (clock_id != CLOCK_REALTIME && clock_id != CLOCK_MONOTONIC +#ifdef CONFIG_OC_EXECTIMERS + && clock_id->mode != RTL_CLOCK_MODE_EXECTIME +#endif +){ errno=EINVAL; return -1; } diff -BbNru sigtim_rt/scripts/config.in exetimers_rt/scripts/config.in --- sigtim_rt/scripts/config.in 2004-03-02 10:20:35.000000000 -0800 +++ exetimers_rt/scripts/config.in 2004-03-02 12:45:23.000000000 -0800 @@ -42,6 +42,11 @@ if [ "$CONFIG_RTL_OC_PSIGNALS" = "y" ]; then bool 'POSIX Timers' CONFIG_RTL_OC_PTIMERS fi +if [ "$CONFIG_RTL_OC_PTIMERS" = "y" ]; then + bool 'Execution Timers' CONFIG_OC_EXECTIMERS +fi + + source main/arch/config.in endmenu