Added handling of task pending events from scheduler.

Previously all pending events were handled on return of exceptions
in process context. This was causing threads that run in userspace
and take no exceptions not handle their pending events indefinitely.
Now scheduler handles them in irq context as well.
This commit is contained in:
Bahadir Balban
2009-11-01 01:03:17 +02:00
parent 0f537ea1f5
commit 5fd0f12017
5 changed files with 48 additions and 23 deletions

View File

@@ -8,6 +8,7 @@
#include INC_ARCH(asm.h)
static inline void enable_irqs()
{
__asm__ __volatile__(
@@ -38,30 +39,29 @@ static inline void disable_irqs()
);
}
#if 0 /* These will be useful for nested irq disable/enable calls */
/* Disable the irqs unconditionally, but also keep the previous state such that
* if it was already disabled before the call, the restore call would retain
* this state. */
static inline void irq_local_disable_save(unsigned long *flags)
static inline void irq_local_disable_save(unsigned long *state)
{
unsigned long temp;
__asm__ __volatile__ (
"mrs %0, cpsr_fc\n"
"orr %1, %0, #0x80\n"
"msr cpsr_fc, %1\n"
: "=r"(*flags), "=r" (temp)
:: "r" (*state), "r" (temp)
);
}
/* Simply change it back to original state supplied in @flags. This might enable
* or retain disabled state of the irqs for example. Useful for nested calls. */
static inline void irq_local_restore(unsigned long flags)
static inline void irq_local_restore(unsigned long state)
{
__asm__ __volatile__ (
"msr cpsr_fc, %0\n"
: "r" (flags)
:: "r" (state)
);
}
#endif
static inline void irq_local_enable()
{
enable_irqs();

View File

@@ -39,19 +39,21 @@ static inline void spin_unlock(struct spinlock *s)
* - To be used for synchronising against processes and irqs
* on other cpus.
*/
static inline void spin_lock_irq(struct spinlock *s)
static inline void spin_lock_irq(struct spinlock *s,
unsigned long state)
{
irq_local_disable(); /* Even in UP an irq could deadlock us */
irq_local_disable_save(&state);
#if defined(CONFIG_SMP)
__spin_lock(&s->lock);
#endif
}
static inline void spin_unlock_irq(struct spinlock *s)
static inline void spin_unlock_irq(struct spinlock *s,
unsigned long state)
{
#if defined(CONFIG_SMP)
__spin_unlock(&s->lock);
#endif
irq_local_enable();
irq_local_restore(state);
}
#endif /* __LIB__SPINLOCK_H__ */