Good news. The applied patch seems to work correctly. I tested oskit-mach
for about an hour with a stress test. No panics:)
Please look through the patch, and tell me how far away from a good patch
I am.
wagi
Index: osenv_timer.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/oskit/pc/Attic/osenv_timer.c,v
retrieving revision 1.1.2.1
diff -p -c -r1.1.2.1 osenv_timer.c
*** osenv_timer.c 1999/11/25 23:27:56 1.1.2.1
--- osenv_timer.c 2001/09/29 11:40:09
*************** softclock_oskit (void)
*** 54,59 ****
--- 54,63 ----
for (th = timer_head; th; th = th->next)
(*th->func)();
osenv_intr_enable();
+
+ osenv_softintr_disable();
+ softint_handler(NULL);
+ osenv_softintr_enable();
}
/*
*** /dev/null Wed May 2 00:58:33 2001
--- osenv_softirq.c Sat Sep 29 13:36:39 2001
***************
*** 0 ****
--- 1,261 ----
+ /*
+ * Copyright (c) 2000 University of Utah and the Flux Group.
+ * All rights reserved.
+ *
+ * This file is part of the Flux OSKit. The OSKit is free software, also known
+ * as "open source;" you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License (GPL), version 2, as published by the Free
+ * Software Foundation (FSF). To explore alternate licensing terms, contact
+ * the University of Utah at [EMAIL PROTECTED] or +1-801-585-3271.
+ *
+ * The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GPL for more details. You should have
+ * received a copy of the GPL along with the OSKit; see the file COPYING. If
+ * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
+ */
+
+ /*
+ * oskit Software Interrupt management for Mach.
+ */
+
+ #include <oskit/error.h>
+ #include <oskit/debug.h>
+ #include <oskit/dev/dev.h>
+ #include <oskit/dev/softirq.h>
+ #include <oskit/machine/base_irq.h>
+ #include <stdio.h>
+
+ #include <machine/spl.h>
+ #include "ds_oskit.h"
+
+
+ /* Linked list of functions for a software interrupt. */
+ struct softint_handler {
+ void (*func)(void *);
+ void *data;
+ struct softint_handler *next;
+ int flags;
+ };
+
+ /* Array of pointers to lists of interrupt handlers. */
+ static struct softint_handler *softint_handlers[SOFT_IRQ_COUNT];
+
+ /* Mask of allocated vectors, for the benefit of osenv_softirq_request() */
+ static unsigned int softint_allocated = ((1 << OSENV_SOFT_IRQ_SOFTWARE)
+ | (1 << OSENV_SOFT_IRQ_PTHREAD));
+
+ /* Pending softirqs that have been software scheduled. */
+ static volatile unsigned int softint_pending;
+
+ static spl_t osenv_softintr_spl;
+ extern spl_t curr_ipl;
+
+ /* This will override the stub function in the kernel library. It is the
+ entrypoint from the hardware interrupt handler, and is invoked when
+ it is safe to deliver a software interrupt, and one or more software
+ interrupts is pending.
+
+ Called with hardware interrupts enabled and software interrupts disabled.
+ Upon return to the caller, hardware interrupts will be disabled again and
+ software interrupts will be renabled.
+
+ The handler will be invoked with hardware interrupts enabled. Since
+ software interrupts are still disabled, if the handler results in a context
+ switch, software interrupts will need to be renabled. The pthreads
+ code does this in its software interrupt handler, but I think thats the
+ wrong place since some other operation could result in a context switch,
+ which would leave softints disabled. Perhaps there needs to be something
+ in the context switch code?
+
+ A software interrupt handler should obviously not allocate or deallocate
+ a software interrupt. It may schedule one of course. */
+ void
+ softint_handler (struct trap_state *ts)
+ {
+ osenv_intr_disable ();
+
+ while (softint_pending)
+ {
+ int i;
+ struct softint_handler *current;
+
+ for (i = 0; i < SOFT_IRQ_COUNT; i++)
+ {
+ if (softint_pending & (1 << i))
+ {
+ softint_pending &= ~(1 << i);
+
+ current = softint_handlers[i];
+ osenv_intr_enable ();
+ while (current)
+ {
+ current->func (current->data);
+ current = current->next;
+ }
+ osenv_intr_disable ();
+ }
+ }
+ }
+
+ assert (!osenv_softintr_enabled ());
+ osenv_intr_enable ();
+ }
+
+
+ /* Allocate a (well-known) software interrupt handler. */
+ oskit_error_t
+ osenv_softirq_alloc (int irq, void (*handler)(void *), void *data, int flags)
+ {
+ struct softint_handler *temp, **p;
+
+ if (irq < 0 || irq >= SOFT_IRQ_COUNT)
+ return OSKIT_EINVAL;
+
+ /* Do this to ensure that the free vectors are explicitly allocated
+ before having a handler assigned. */
+ if ((irq >= SOFT_IRQ_FREEBASE) && !(softint_allocated & (1 << irq)))
+ return OSKIT_EINVAL;
+
+ /* This is a blocking operation, so to avoid races we need to do it
+ before we start mucking with data structures. */
+ temp = osenv_mem_alloc (sizeof(struct softint_handler), 0, 1);
+ if (temp == NULL)
+ return OSKIT_ENOMEM;
+ temp->func = handler;
+ temp->data = data;
+ temp->next = NULL;
+ temp->flags = flags;
+
+ /* Do this first. */
+ base_irq_softint_handler = softint_handler;
+
+ /* Note that we only hook in the new handler after its structure has been
+ fully initialized; this way we don't have to disable interrupts, because
+ interrupt-level code only scans the list. */
+ for (p = &softint_handlers[irq]; *p != NULL; p = &(*p)->next)
+ ;
+ *p = temp;
+
+ return 0;
+ }
+
+ /* Request an unused software interrupt handler vector. This just reserves
+ and returns the vector number for use with osenv_softirq_alloc() above. */
+ oskit_error_t
+ osenv_softirq_alloc_vector (int *out_irq)
+ {
+ int i, enabled;
+
+ /* Go ahead and block interrupts, cause its easy. */
+ enabled = osenv_intr_enabled ();
+ if (enabled)
+ osenv_intr_disable ();
+
+ /* Search for an empty slot above the well-known vectors. */
+ for (i = SOFT_IRQ_FREEBASE; i < SOFT_IRQ_COUNT; i++)
+ {
+ if (! (softint_allocated & (1 << i)))
+ break;
+ }
+ if (i == SOFT_IRQ_COUNT)
+ {
+ if (enabled)
+ osenv_intr_enable ();
+ return OSKIT_ERANGE;
+ }
+
+ softint_allocated |= (1 << i);
+ *out_irq = i;
+
+ if (enabled)
+ osenv_intr_enable ();
+ return 0;
+ }
+
+ /* Free up a vector. */
+ oskit_error_t
+ osenv_softirq_free_vector (int irq)
+ {
+ /* Must be allocated */
+ if (! (softint_allocated & (1 << irq)))
+ return OSKIT_EINVAL;
+
+ /* Must no longer be in use */
+ if (softint_handlers[irq])
+ return OSKIT_EINVAL;
+
+ softint_allocated &= ~(1 << irq);
+
+ return 0;
+ }
+
+ /* Deallocate a software interrupt. Need a handle so know WHICH
+ interrupt handler to remove. */
+ void
+ osenv_softirq_free (int irq, void (*handler)(void *), void *data)
+ {
+ struct softint_handler *temp, **p;
+
+ osenv_assert (irq >= 0 && irq < SOFT_IRQ_COUNT);
+
+ /* Find and unlink the handler from the list. */
+ p = &softint_handlers[irq];
+ while (((temp = *p) != NULL)
+ && (temp->func != handler || temp->data != data))
+ p = &temp->next;
+
+ /* not found? */
+ if (temp == NULL)
+ {
+ osenv_log (OSENV_LOG_WARNING,
+ "osenv_softirq_free: handler not registered!\n");
+ return;
+ }
+
+ /* remove it! */
+ *p = temp->next;
+ osenv_softintr_disable ();
+ osenv_mem_free (temp, 0, sizeof(struct softint_handler));
+ }
+
+ /* Schedule a software interrupt to be delivered next time its appropriate. */
+ void
+ osenv_softirq_schedule (int irq)
+ {
+ osenv_assert (softint_handlers[irq]);
+
+ softint_pending |= (1 << irq);
+ setsoftclock ();
+ }
+
+ void
+ osenv_softintr_enable (void)
+ {
+ spl_t s = osenv_softintr_spl;
+ osenv_softintr_spl = SPL0;
+ splx (s);
+ }
+
+ void
+ osenv_softintr_disable (void)
+ {
+ /* We can be called with interrupts already disabled! */
+ if (curr_ipl > SPLIO)
+ /* We are already at higher priority than oskit code normally runs.
+ I think this only happens in the calls from oskit_rtc_{get,set}.
+ On the assumption that osenv_intr_enable will be called in
+ parity from the sameqq interrupt level, we will want to stay at the
+ same high interrupt level. */
+ osenv_softintr_spl = curr_ipl;
+ else if (curr_ipl < SPLIO)
+ /* We are at a level where oskit interrupts are enabled, so we must go
+ to splio. osenv_intr_enable we will return to the current level. */
+ osenv_softintr_spl = splsoftclock ();
+ }
+
+ int
+ osenv_softintr_enabled (void)
+ {
+ return curr_ipl < SPLIO;
+ }
_______________________________________________
Bug-hurd mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/bug-hurd