[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tyndur-devel] [Lost] [PATCH v2 06/10] kernel2: Syscall add_timer



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: pgpx0kRsYsA87.pgp
Description: PGP signature