On Sat, Dec 20 23:49, Kevin Wolf wrote: > + kernel2: Timer-Funkionen von kernel uebernommen > + kernel2: Syscall add_timer > --- > src/kernel2/include/syscall.h | 2 + > src/kernel2/include/timer.h | 47 ++++++++++++ > src/kernel2/src/interrupts/im.c | 4 + > src/kernel2/src/syscall.c | 2 + > src/kernel2/src/syscalls/misc.c | 9 +++ > src/kernel2/src/tasks/pm.c | 4 + > src/kernel2/src/timer.c | 150 +++++++++++++++++++++++++++++++++++++++ > 7 files changed, 218 insertions(+), 0 deletions(-) > create mode 100644 src/kernel2/include/timer.h > create mode 100644 src/kernel2/src/timer.c > > diff --git a/src/kernel2/include/syscall.h b/src/kernel2/include/syscall.h > index b65e57e..b30b389 100644 > --- a/src/kernel2/include/syscall.h > +++ b/src/kernel2/include/syscall.h > @@ -130,6 +130,8 @@ void* syscall_shm_attach(uint32_t id); > /// Shared Memory schliessen > void syscall_shm_detach(uint32_t id); > > +/// Einen Timer anlegen > +void syscall_add_timer(uint32_t timer_id, uint32_t usec); > > // RPC > /// RPC-Handler registrieren > diff --git a/src/kernel2/include/timer.h b/src/kernel2/include/timer.h > new file mode 100644 > index 0000000..856b37d > --- /dev/null > +++ b/src/kernel2/include/timer.h > @@ -0,0 +1,47 @@ > +/* > + * Copyright (c) 2006-2007 The LOST Project. All rights reserved. Ist mittlerweile nicht schon fast 2009? ;-) > + * > + * This code is derived from software contributed to the LOST Project > + * by Kevin Wolf. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the LOST Project > + * and its contributors. > + * 4. Neither the name of the LOST Project nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR > + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, > + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, > + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; > + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifndef _TIMER_H_ > +#define _TIMER_H_ > + > +#include <stdint.h> > +#include "tasks.h" > + > +void timer_init(void); > +void timer_register(pm_process_t* task, uint32_t timer_id, uint32_t usec); > +void timer_notify(uint64_t microtime); > +void timer_cancel_all(pm_process_t* task); > + > +#endif > diff --git a/src/kernel2/src/interrupts/im.c b/src/kernel2/src/interrupts/im.c > index 560f5fe..1838b4d 100644 > --- a/src/kernel2/src/interrupts/im.c > +++ b/src/kernel2/src/interrupts/im.c > @@ -44,6 +44,7 @@ > #include "apic.h" > #include "kernel.h" > #include "syscall.h" > +#include "timer.h" > > extern size_t cpu_count; > > @@ -140,6 +141,9 @@ interrupt_stack_frame_t* im_handler(interrupt_stack_frame_t* isf) > > // Einen neuen Thread holen. > cpu_get_current()->thread = pm_scheduler_pop(); > + > + // Timer ausloesen, wenn noetig > + timer_notify(timer_ticks); > } else { > intr_to_send[int_num]++; > im_disable_irq(int_num - IM_IRQ_BASE); > diff --git a/src/kernel2/src/syscall.c b/src/kernel2/src/syscall.c > index f15021b..836d1e7 100644 > --- a/src/kernel2/src/syscall.c > +++ b/src/kernel2/src/syscall.c > @@ -74,6 +74,8 @@ void syscall_init() > syscall_register(SYSCALL_FASTRPC_RET, &syscall_fastrpc_ret, 0); > #endif > > + syscall_register(SYSCALL_ADD_TIMER, &syscall_add_timer, 2); > + > syscall_register(SYSCALL_PM_REQUEST_PORT, syscall_io_request_port, 2); > syscall_register(SYSCALL_ADD_INTERRUPT_HANDLER, > syscall_add_interrupt_handler, 1); > diff --git a/src/kernel2/src/syscalls/misc.c b/src/kernel2/src/syscalls/misc.c > index beed606..5095c9b 100644 > --- a/src/kernel2/src/syscalls/misc.c > +++ b/src/kernel2/src/syscalls/misc.c > @@ -39,6 +39,7 @@ > #include "syscall.h" > #include "kprintf.h" > #include "console.h" > +#include "timer.h" > > /** > * Debug-Ausgaben; Nur solange benutzen, bis der definitve Treiber im Usermode > @@ -61,3 +62,11 @@ uint64_t syscall_get_tick_count(void) > { > return timer_ticks; > } > + > +/** > + * Registriert einen neuen Timer > + */ > +void syscall_add_timer(uint32_t timer_id, uint32_t usec) > +{ > + timer_register(cpu_get_current()->thread->process, timer_id, usec); > +} > diff --git a/src/kernel2/src/tasks/pm.c b/src/kernel2/src/tasks/pm.c > index 0324c33..3f43688 100644 > --- a/src/kernel2/src/tasks/pm.c > +++ b/src/kernel2/src/tasks/pm.c > @@ -40,6 +40,7 @@ > > #include "tasks.h" > #include "lock.h" > +#include "timer.h" > > > struct on_destroy_info { > @@ -162,6 +163,9 @@ void pm_destroy(pm_process_t* process) > } > list_destroy(process->on_destroy); > > + // Timer freigeben > + timer_cancel_all(process); > + > // RPC-Strukturen freigeben > // TODO Die einzelnen Listenglieder freigeben > list_destroy(process->rpcs); > diff --git a/src/kernel2/src/timer.c b/src/kernel2/src/timer.c > new file mode 100644 > index 0000000..5c85827 > --- /dev/null > +++ b/src/kernel2/src/timer.c > @@ -0,0 +1,150 @@ > +/* > + * Copyright (c) 2006-2008 The tyndur Project. All rights reserved. Schon besser, reicht aber noch nicht. *g* Jaja ich weiss, ich bin schuld. ;-) > + * > + * This code is derived from software contributed to the tyndur Project > + * by Kevin Wolf. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * 3. All advertising materials mentioning features or use of this software > + * must display the following acknowledgement: > + * This product includes software developed by the tyndur Project > + * and its contributors. > + * 4. Neither the name of the tyndur Project nor the names of its > + * contributors may be used to endorse or promote products derived > + * from this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR > + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, > + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, > + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; > + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include <collections.h> > +#include <stdlib.h> > + > +#include "timer.h" > +#include "syscall.h" > + > +extern uint64_t timer_ticks; > + > +/** > + * Liste aller registrierten Timer > + */ > +static list_t* timers; > + > +/** > + * Repraesentiert einen registrierten Timer. Ein Timer gehoert zun einem > + * bestimmten Prozess und nach Ablauf der vorgegebenen Zeitspanne wird ein RPC > + * zu diesem Prozess durchgefuehrt > + */ > +struct timeout { > + pm_process_t* task; > + uint32_t timer_id; > + uint64_t timeout; > +}; > + > +/** > + * Initialisiert die Timerverwaltung > + */ > +void timer_init(void) > +{ > + timers = list_create(); > +} > + > +/** > + * Registriert einen neuen Timer > + */ > +void timer_register(pm_process_t* task, uint32_t timer_id, uint32_t usec) > +{ > + // Anlegen des Timeout-Objekts > + struct timeout* timeout = malloc(sizeof(struct timeout)); > + > + timeout->task = task; > + timeout->timer_id = timer_id; > + timeout->timeout = timer_ticks + usec; > + > + // An der richtigen Stelle in der Liste einsortieren, so dass immer nur > + // das erste Listenelement geprueft werden muss > + struct timeout* item; > + int i; > + for (i = 0; (item = list_get_element_at(timers, i)); i++) { > + if (item->timeout > timeout->timeout) { > + break; > + } > + } > + > + list_insert(timers, i, timeout); > +} > + > +/** > + * Auszurufen bei jeder Aktualisierung der Systemzeit. Fuehrt die KRITIKEL! > + * RPC-Benachrichtigungen fuer alle faelligen Timer aus. > + */ > +void timer_notify(uint64_t microtime) > +{ > + static uint64_t last_microtime = 0; > + static const uint32_t rpc_timer_function = 514; > + > + struct timeout* item; > + int i = 0; > + while ((item = list_get_element_at(timers, i))) > + { > + // Die Schleife soll nur so lange laufen, wie die Timeouts in der > + // Vergangenheit liegen. Da die Liste sortiert ist, kann beim ersten > + // Timeout, der in der Zukunft liegt, abgebrochen werden. > + // > + // Overflows muessen abgefangen werden, da in diesem Spezialfall eine > + // groessere Zahl dennoch Vergangenheit bedeutet. Wie ich grad sehe, > + // reden wir von einem qword und damit von einer Uptime von ein paar > + // hunderttausend Jahren, aber tyndur ist ja stabil und wir daher > + // optimistisch. > + if (((item->timeout > microtime) && (microtime > last_microtime)) > + || ((item->timeout < last_microtime) && (microtime < last_microtime))) > + { > + break; > + } > + > + // Task per RPC informieren, dass der Timer abgelaufen ist. > + // Im Fehlerfall ueberspringen und es beim naechsten Mal nochmal > + // versuchen. > + if (!syscall_fastrpc(item->task->pid, > + 4, (char*) &rpc_timer_function, > + 4, (char*) &item->timer_id)) > + { > + i++; > + continue; > + } > + > + free(list_remove(timers, i)); > + } > + > + last_microtime = microtime; > +} > + > +/** > + * Entfernt alle registrierten Timer eines Prozesses > + */ > +void timer_cancel_all(pm_process_t* task) > +{ > + struct timeout* item; > + int i; > + for (i = 0; (item = list_get_element_at(timers, i)); i++) { > + if (item->task == task) { > + list_remove(timers, i); > + } > + } > +} Sonst sieht es gut aus. Ich glaube du kriegst das noch in und kannst danach einchecken. ;-) -- Antoine Kaufmann <toni@xxxxxxxxxxxxxxxx>
Attachment:
pgpLLKfSSNHu3.pgp
Description: PGP signature