mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Converted all wait/wakeup runqueue lock/unlock paths to irq versions.
Irqs can now touch runqueues and do async wakeups. This necessitated that we implement all wake up wait and runqueue locking work with irqs. All this, assumes that in an SMP setup we may have cross-cpu wake ups, runqueue manipulation. If we later decide that we only wake up threads in the current container, (and lock containers to cpus) we won't really need spinlocks, or irq disabling anymore. The current set up might be trivially less responsive, but is more flexible.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#define __GENERIC_IRQ_H__
|
||||
|
||||
#include <l4/lib/string.h>
|
||||
#include <l4/lib/wait.h>
|
||||
#include INC_PLAT(irq.h)
|
||||
#include INC_ARCH(types.h)
|
||||
|
||||
@@ -45,6 +46,9 @@ struct irq_desc {
|
||||
/* Notification slot for this irq */
|
||||
int task_notify_slot;
|
||||
|
||||
/* Waitqueue head for this irq */
|
||||
struct waitqueue_head wqh_irq;
|
||||
|
||||
/* NOTE: This could be a list for multiple handlers for shared irqs */
|
||||
irq_handler_t handler;
|
||||
};
|
||||
|
||||
@@ -15,7 +15,6 @@ struct waitqueue {
|
||||
enum wakeup_flags {
|
||||
WAKEUP_INTERRUPT = (1 << 0), /* Set interrupt flag for task */
|
||||
WAKEUP_SYNC = (1 << 1), /* Wake it up synchronously */
|
||||
WAKEUP_IRQ = (1 << 2) /* Disable irqs on spinlocks */
|
||||
};
|
||||
|
||||
#define CREATE_WAITQUEUE_ON_STACK(wq, tsk) \
|
||||
@@ -51,18 +50,20 @@ void task_unset_wqh(struct ktcb *task);
|
||||
do { \
|
||||
ret = 0; \
|
||||
for (;;) { \
|
||||
spin_lock(&(wqh)->slock); \
|
||||
unsigned long irqsave; \
|
||||
spin_lock_irq(&(wqh)->slock, &irqsave); \
|
||||
if (condition) { \
|
||||
spin_unlock(&(wqh)->slock); \
|
||||
spin_unlock_irq(&(wqh)->slock, irqsave);\
|
||||
break; \
|
||||
} \
|
||||
CREATE_WAITQUEUE_ON_STACK(wq, current); \
|
||||
task_set_wqh(current, wqh, &wq); \
|
||||
(wqh)->sleepers++; \
|
||||
list_insert_tail(&wq.task_list, &(wqh)->task_list);\
|
||||
/* printk("(%d) waiting...\n", current->tid); */ \
|
||||
list_insert_tail(&wq.task_list, \
|
||||
&(wqh)->task_list); \
|
||||
/* printk("(%d) waiting...\n", current->tid); */\
|
||||
sched_prepare_sleep(); \
|
||||
spin_unlock(&(wqh)->slock); \
|
||||
spin_unlock_irq(&(wqh)->slock, irqsave); \
|
||||
schedule(); \
|
||||
/* Did we wake up normally or get interrupted */\
|
||||
if (current->flags & TASK_INTERRUPTED) { \
|
||||
@@ -73,6 +74,7 @@ do { \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
|
||||
void wake_up(struct waitqueue_head *wqh, unsigned int flags);
|
||||
int wake_up_task(struct ktcb *task, unsigned int flags);
|
||||
void wake_up_all(struct waitqueue_head *wqh, unsigned int flags);
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
#define SIC_CHIP_OFFSET 32
|
||||
|
||||
/* Maximum irqs on VIC and SIC */
|
||||
#define VIC_IRQS_MAX PL190_IRQS_MAX
|
||||
#define SIC_IRQS_MAX PL190_SIC_IRQS_MAX
|
||||
#define VIC_IRQS_MAX 32
|
||||
#define SIC_IRQS_MAX 32
|
||||
|
||||
#define IRQS_MAX VIC_IRQS_MAX + SIC_IRQS_MAX
|
||||
|
||||
|
||||
Reference in New Issue
Block a user