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

Re: [tyndur-devel] [PATCH 1/5] kernel2: IRQ-Sharing



On Sat, Jan 29, 2011 at 01:38:34PM +0100, max@xxxxxxxxxx wrote:
> From: Max Reitz <max@xxxxxxxxxx>
> 
> + Bis zu vier Tasks können jetzt beim Auftreten eines IRQs
>   benachrichtigt werden.
> 
> Signed-off-by: Max Reitz <max@xxxxxxxxxx>
> ---
>  src/kernel2/src/interrupts/im.c |   89 ++++++++++++++++++++++++++++----------
>  1 files changed, 65 insertions(+), 24 deletions(-)
> 
> diff --git a/src/kernel2/src/interrupts/im.c b/src/kernel2/src/interrupts/im.c
> index d266959..96bfdd9 100644
> --- a/src/kernel2/src/interrupts/im.c
> +++ b/src/kernel2/src/interrupts/im.c
> @@ -33,6 +33,7 @@
>   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>   */
>  
> +#include <stdbool.h>
>  #include <types.h>
>  #include <lost/config.h>
>  
> @@ -51,8 +52,18 @@ extern size_t cpu_count;
>  /** Einheit: Mikrosekunden */
>  uint64_t timer_ticks = 0;
>  
> -static pm_process_t* intr_handling_task[IM_NUM_INTERRUPTS];
> -static uint32_t intr_to_send[IM_NUM_INTERRUPTS];
> +#define MAX_INTERRUPTS 4
> +
> +// Wenn mehrere Tasks für einen Interrupt registriert sind, dann werden sie im
> +// Array so angeordnet, dass nur die ersten Einträge gefüllt sind
> +static pm_process_t* intr_handling_task[IM_NUM_INTERRUPTS][MAX_INTERRUPTS];
> +static uint32_t intr_to_send[IM_NUM_INTERRUPTS][MAX_INTERRUPTS];
> +// Anzahl von Tasks pro Interrupt
> +static int intr_num_tasks[IM_NUM_INTERRUPTS];
> +// Gibt an, ob überhaupt irgendein Interrupt für die jeweilige Nummer
> +// auszuliefern ist (ist also false, wenn alle intr_to_send-Einträge für den
> +// Interrupt 0 sind, sonst true).
> +static bool any_intr[IM_NUM_INTERRUPTS];
>  
>  void im_send_interrupts(void);
>  bool fastrpc_irq(pm_process_t* callee, size_t metadata_size, void* metadata,
> @@ -193,7 +204,11 @@ interrupt_stack_frame_t* im_handler(interrupt_stack_frame_t* isf)
>              // Timer ausloesen, wenn noetig
>              timer_notify(timer_ticks);
>          } else {
> -            intr_to_send[int_num]++;
> +            int i;
> +            for (i = 0; i < intr_num_tasks[int_num]; i++) {
> +                intr_to_send[int_num][i]++;
> +            }
> +            any_intr[int_num] = true;
>              im_disable_irq(int_num - IM_IRQ_BASE);
>          }
>      } else if (int_num == 0x30) {
> @@ -261,12 +276,25 @@ static void on_process_destroy(pm_process_t* process, void* prv)
>          panic("im.c: on_process_destroy(): Korrupte Interruptnummer %d", intr);
>      }
>  
> -    if (intr_handling_task[intr] != process) {
> -        panic("im.c: on_process_destroy(): Prozess nicht fuer Interrupt %d "
> -            "zustaendig", intr);
> +    int i, j;
> +    for (i = 0; i < intr_num_tasks[intr]; i++) {
> +        if (intr_handling_task[intr][i] == process) {
> +            intr_handling_task[intr][i] = NULL;
> +
> +            // Nach vorn schieben, sodass immer nur die vorderen Plätze des
> +            // Arrays belegt sind
> +            for (j = --intr_num_tasks[intr]; j > i; j--) {
> +                if (intr_handling_task[intr][j] != NULL) {
> +                    intr_handling_task[intr][i] = intr_handling_task[intr][j];
> +                }
> +            }

Bist du dir mit dem Algorithmus sicher? Angenommen wir haben vier Tasks
und löschen den ersten:

0 1 2 3, i = 0, j = 3
3 1 2,   i = 0, j = 2 -- hier besser aufhören, tun wir aber nicht
2 1 2,   i = 0, j = 1
1 1 2,   i = 0, j = 0

Ansonsten sieht der Patch in Ordnung aus.