/branches/rcu/kernel/test/synch/rcu1.c |
---|
42,7 → 42,7 |
#include <proc/thread.h> |
//number of nodes in the list. The sum of the list will grow up to RCU_MAX_I^2 |
#define RCU_MAX_I 5000 |
#define RCU_MAX_I 500 |
//number of reader and writer threads in the test |
#define READER_THREADS 10 |
#define WRITER_THREADS 10 |
69,7 → 69,8 |
a = (a); |
data_t* cur; |
int i = 0; |
while (true) { |
while (true) |
{ |
//entering read critical section |
rcu_read_lock(); |
//proper dereferencing |
78,17 → 79,14 |
i += cur->number; |
} |
rcu_read_unlock(); |
if (i>RCU_MAX_I*RCU_MAX_I || cfinished>0) { |
if (!gquiet) |
printf("@"); |
if (i>RCU_MAX_I*RCU_MAX_I || cfinished>0) |
{ |
printf("@"); |
break; |
} |
thread_usleep(THREADS_SLEEP_LENGTH); |
} |
//we must achieve some kind of synchronization gcc wont emit inc [cfinished] |
spinlock_lock(&write_lock); |
cfinished++; |
spinlock_unlock(&write_lock); |
} |
static void writer(void* a) |
99,7 → 97,8 |
data_t* oldata; |
rcu_callback_list_t* rcudata; |
int i = 0; |
while (true) { |
while (true) |
{ |
//we must allocate the rcu structure each time, because it gets freed after the callback |
//we allocate it outside any critical section, as it could block |
rcudata = malloc(sizeof(rcu_callback_list_t),0); |
109,11 → 108,11 |
i += cur->number; |
} |
rcu_read_unlock(); |
if (!gquiet && false) |
if (!gquiet) |
printf("i%d ",i); |
if (i>RCU_MAX_I*RCU_MAX_I || cfinished>0) { |
if (!gquiet) |
printf("!"); |
if (i>RCU_MAX_I*RCU_MAX_I || cfinished>0) |
{ |
printf("!"); |
break; |
} |
120,17 → 119,20 |
//insert a new member |
newdata = malloc(sizeof(data_t),0); |
newdata->number = (i/(RCU_MAX_I/2))+1; |
rcu_read_lock(); |
//we have to acquire the lock for writing to the structure |
spinlock_lock(&write_lock); |
newdata->next = first; |
//rcu_assign_pointer takes care of the necessary write barriers |
rcu_assign_pointer(first, newdata); |
if (!gquiet && false) |
if (!gquiet) |
printf("prepending:%x,n:%d ", newdata, newdata->number); |
spinlock_unlock(&write_lock); |
rcu_read_unlock(); |
//replace a random member |
rcu_read_lock(); |
//we have to lock the spinlock now, because we'll use the cur pointer later |
//RCU doesn't provide guarantee that cur->next will point to a member of the list |
//note that read critical section DOES guarantee that the *cur will be allocated space |
142,10 → 144,10 |
if (cur->next != NULL) { |
newdata = malloc(sizeof(data_t),0); |
//the change of number member could be done atomically, its here just to simulate some real work |
newdata->number = (i/(RCU_MAX_I/2))+10; |
newdata->number = (i/(RCU_MAX_I/2))+5; |
newdata->next = cur->next->next; |
oldata = cur->next; |
if (!gquiet && false) |
if (!gquiet) |
printf("free:%x,n:%d ", cur->next, cur->next->number); |
rcu_assign_pointer(cur->next, newdata); |
//free the old member when it is safe (i.e. no references are held) |
152,11 → 154,9 |
rcu_sync_callback(&rcu_callback_free, oldata, rcudata); |
spinlock_unlock(&write_lock); |
} |
rcu_read_unlock(); |
} |
//we must achieve some kind of synchronization gcc wont emit inc [cfinished] |
spinlock_lock(&write_lock); |
cfinished++; |
spinlock_unlock(&write_lock); |
} |
char * test_rcu1(bool quiet) |
195,8 → 195,7 |
} |
//wait for completion |
while (cfinished<WRITER_THREADS+READER_THREADS); |
if (!gquiet) |
printf("\nfinished all threads!\n"); |
printf("\nfinished all threads!\n"); |
//free the list |
for(cur=first->next;cur!=NULL;) { |
oldata = cur->next; |
/branches/rcu/kernel/test/tasklet/tasklet1.c |
---|
37,13 → 37,12 |
#include <arch/types.h> |
#include <config.h> |
bool gquiet; |
static void func(void *data) |
{ |
if (!gquiet) |
printf("cpu%d: %s",CPU->id, data); |
printf("cpu%d: %s",CPU->id, data); |
} |
bool gquiet; |
#ifdef CONFIG_SMP |
static void running_tasklet(void * data) |
/branches/rcu/kernel/generic/src/adt/listrcu.c |
---|
File deleted |
/branches/rcu/kernel/generic/src/ddi/irq.c |
---|
71,9 → 71,7 |
#include <arch/types.h> |
#include <synch/spinlock.h> |
#include <arch.h> |
#include <synch/rcu.h> |
#define KEY_INR 0 |
#define KEY_DEVNO 1 |
147,13 → 145,12 |
irq->claim = NULL; |
irq->handler = NULL; |
irq->arg = NULL; |
irq->notif_cfg = malloc(sizeof(ipc_notif_cfg_t), 0); |
irq->notif_cfg->notify = false; |
irq->notif_cfg->answerbox = NULL; |
irq->notif_cfg->code = NULL; |
irq->notif_cfg->method = 0; |
irq->notif_cfg->counter = 0; |
link_initialize(&irq->notif_cfg->link); |
irq->notif_cfg.notify = false; |
irq->notif_cfg.answerbox = NULL; |
irq->notif_cfg.code = NULL; |
irq->notif_cfg.method = 0; |
irq->notif_cfg.counter = 0; |
link_initialize(&irq->notif_cfg.link); |
} |
/** Register IRQ for device. |
/branches/rcu/kernel/generic/src/ipc/irq.c |
---|
57,8 → 57,6 |
#include <syscall/copy.h> |
#include <console/console.h> |
#include <print.h> |
#include <synch/rcu.h> |
#include <adt/listrcu.h> |
/** Execute code associated with IRQ notification. |
* |
173,27 → 171,21 |
{ |
ipl_t ipl; |
irq_t *irq; |
ipc_notif_cfg_t *new_notify, *old_notify; |
ipl = interrupts_disable(); |
irq = irq_find_and_lock(inr, devno); |
if (irq) { |
if (rcu_dereference_pointer(irq->notif_cfg).answerbox == box) { |
new_notify = malloc(sizeof(ipc_notif_cfg_t),0); |
if (irq->notif_cfg.answerbox == box) { |
code_free(irq->notif_cfg.code); |
irq->notif_cfg.notify = false; |
irq->notif_cfg.answerbox = NULL; |
irq->notif_cfg.code = NULL; |
irq->notif_cfg.method = 0; |
irq->notif_cfg.counter = 0; |
new_notify->notify = false; |
new_notify->answerbox = NULL; |
new_notify->code = NULL; |
new_notify->method = 0; |
new_notify->counter = 0; |
old_notify = irq->notif_cfg; |
copy_link_rcu(&irq->notif_cfg->link, &new_notify->link); |
rcu_assign_pointer(old_notify, new_notify); |
spinlock_lock(&box->irq_lock); |
list_remove_rcu(&rcu_dereference_pointer(irq->notif_cfg).link); |
list_remove(&irq->notif_cfg.link); |
spinlock_unlock(&box->irq_lock); |
rcu_sync_callback_normal_alloc(&ipc_notif_free_callback, irq->notif_cfg); |
spinlock_unlock(&irq->lock); |
} |
201,13 → 193,6 |
interrupts_restore(ipl); |
} |
void ipc_notif_free_callback(void* notif) |
{ |
code_free(((ipc_notif_cfg_t *)notif)->code); |
free(notif); |
} |
/** Register an answerbox as a receiving end for IRQ notifications. |
* |
* @param box Receiving answerbox. |
223,7 → 208,6 |
ipl_t ipl; |
irq_code_t *code; |
irq_t *irq; |
ipc_notif_cfg_t *new_notify, *old_notify; |
if (ucode) { |
code = code_from_uspace(ucode); |
240,25 → 224,21 |
return ENOENT; |
} |
if (rcu_dereference_pointer(irq->notif_cfg).answerbox) { |
if (irq->notif_cfg.answerbox) { |
spinlock_unlock(&irq->lock); |
interrupts_restore(ipl); |
code_free(code); |
return EEXISTS; |
} |
new_notify = malloc(sizeof(ipc_notif_cfg_t),0); |
new_notify->notify = true; |
new_notify->answerbox = box; |
new_notify->method = method; |
new_notify->code = code; |
new_notify->counter = 0; |
copy_link_rcu(&irq->notif_cfg->link, &new_notify->link); |
old_notify = irq->notif_cfg; |
rcu_assign_pointer(irq->notif_cfg, new_notify); |
rcu_sync_callback_normal_alloc(&ipc_notif_free_callback, old_notify); |
irq->notif_cfg.notify = true; |
irq->notif_cfg.answerbox = box; |
irq->notif_cfg.method = method; |
irq->notif_cfg.code = code; |
irq->notif_cfg.counter = 0; |
spinlock_lock(&box->irq_lock); |
list_append_rcu(&new_notify->link, &box->irq_head); |
list_append(&irq->notif_cfg.link, &box->irq_head); |
spinlock_unlock(&box->irq_lock); |
spinlock_unlock(&irq->lock); |
274,11 → 254,11 |
*/ |
static void send_call(irq_t *irq, call_t *call) |
{ |
spinlock_lock(&rcu_dereference_pointer(irq->notif_cfg).answerbox->irq_lock); |
list_append_rcu(&call->link, &rcu_dereference_pointer(irq->notif_cfg).answerbox->irq_notifs); |
spinlock_unlock(&rcu_dereference_pointer(irq->notif_cfg).answerbox->irq_lock); |
spinlock_lock(&irq->notif_cfg.answerbox->irq_lock); |
list_append(&call->link, &irq->notif_cfg.answerbox->irq_notifs); |
spinlock_unlock(&irq->notif_cfg.answerbox->irq_lock); |
waitq_wakeup(&rcu_dereference_pointer(irq->notif_cfg).answerbox->wq, WAKEUP_FIRST); |
waitq_wakeup(&irq->notif_cfg.answerbox->wq, WAKEUP_FIRST); |
} |
/** Send notification message |
290,7 → 270,7 |
spinlock_lock(&irq->lock); |
if (rcu_dereference_pointer(irq->notif_cfg).answerbox) { |
if (irq->notif_cfg.answerbox) { |
call = ipc_call_alloc(FRAME_ATOMIC); |
if (!call) { |
spinlock_unlock(&irq->lock); |
297,12 → 277,12 |
return; |
} |
call->flags |= IPC_CALL_NOTIF; |
IPC_SET_METHOD(call->data, rcu_dereference_pointer(irq->notif_cfg).method); |
IPC_SET_METHOD(call->data, irq->notif_cfg.method); |
IPC_SET_ARG1(call->data, a1); |
IPC_SET_ARG2(call->data, a2); |
IPC_SET_ARG3(call->data, a3); |
/* Put a counter to the message */ |
call->priv = ++rcu_dereference_pointer(irq->notif_cfg).counter; |
call->priv = ++irq->notif_cfg.counter; |
send_call(irq, call); |
} |
319,7 → 299,7 |
ASSERT(irq); |
if (rcu_dereference_pointer(irq->notif_cfg).answerbox) { |
if (irq->notif_cfg.answerbox) { |
call = ipc_call_alloc(FRAME_ATOMIC); |
if (!call) { |
return; |
326,12 → 306,12 |
} |
call->flags |= IPC_CALL_NOTIF; |
/* Put a counter to the message */ |
call->priv = ++rcu_dereference_pointer(irq->notif_cfg).counter; |
call->priv = ++irq->notif_cfg.counter; |
/* Set up args */ |
IPC_SET_METHOD(call->data, rcu_dereference_pointer(irq->notif_cfg).method); |
IPC_SET_METHOD(call->data, irq->notif_cfg.method); |
/* Execute code to handle irq */ |
code_execute(call, rcu_dereference_pointer(irq->notif_cfg).code); |
code_execute(call, irq->notif_cfg.code); |
send_call(irq, call); |
} |
348,7 → 328,6 |
void ipc_irq_cleanup(answerbox_t *box) |
{ |
ipl_t ipl; |
ipc_notif_cfg_t *new_notify, *old_notify; |
loop: |
ipl = interrupts_disable(); |
359,7 → 338,7 |
irq_t *irq; |
DEADLOCK_PROBE_INIT(p_irqlock); |
irq = list_get_instance(cur, irq_t, notif_cfg->link); |
irq = list_get_instance(cur, irq_t, notif_cfg.link); |
if (!spinlock_trylock(&irq->lock)) { |
/* |
* Avoid deadlock by trying again. |
370,22 → 349,21 |
goto loop; |
} |
ASSERT(irq->notif_cfg->answerbox == box); |
ASSERT(irq->notif_cfg.answerbox == box); |
list_remove_rcu(&irq->notif_cfg->link); |
list_remove(&irq->notif_cfg.link); |
new_notify = malloc(sizeof(ipc_notif_cfg_t),0); |
new_notify->notify = false; |
new_notify->answerbox = NULL; |
new_notify->method = 0; |
new_notify->code = NULL; |
new_notify->counter = 0; |
copy_link_rcu(&irq->notif_cfg->link, &new_notify->link); |
old_notify = irq->notif_cfg; |
rcu_assign_pointer(irq->notif_cfg, new_notify); |
rcu_sync_callback_normal_alloc(&ipc_notif_free_callback, old_notify); |
/* |
* Don't forget to free any top-half pseudocode. |
*/ |
code_free(irq->notif_cfg.code); |
irq->notif_cfg.notify = false; |
irq->notif_cfg.answerbox = NULL; |
irq->notif_cfg.code = NULL; |
irq->notif_cfg.method = 0; |
irq->notif_cfg.counter = 0; |
spinlock_unlock(&irq->lock); |
} |
/branches/rcu/kernel/generic/include/adt/listrcu.h |
---|
File deleted |
/branches/rcu/kernel/generic/include/ddi/irq.h |
---|
145,7 → 145,7 |
void *arg; |
/** Notification configuration structure. */ |
ipc_notif_cfg_t* notif_cfg; |
ipc_notif_cfg_t notif_cfg; |
} irq_t; |
extern void irq_init(count_t inrs, count_t chains); |
/branches/rcu/kernel/generic/include/ipc/irq.h |
---|
50,8 → 50,6 |
extern void ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno); |
extern void ipc_irq_cleanup(answerbox_t *box); |
extern void ipc_notif_free_callback(void* notif); |
#endif |
/** @} |
/branches/rcu/kernel/Makefile |
---|
154,7 → 154,6 |
generic/src/adt/btree.c \ |
generic/src/adt/hash_table.c \ |
generic/src/adt/list.c \ |
generic/src/adt/listrcu.c \ |
generic/src/adt/avl.c \ |
generic/src/adt/extavl.c \ |
generic/src/adt/extavlrel.c \ |
/branches/rcu/kernel/arch/ia64/src/ski/ski.c |
---|
44,7 → 44,6 |
#include <proc/thread.h> |
#include <synch/spinlock.h> |
#include <arch/asm.h> |
#include <synch/rcu.h> |
#define SKI_KBD_INR 0 |
143,7 → 142,7 |
if(ch == '\r') |
ch = '\n'; |
if (ch) { |
if (rcu_dereference_pointer(ski_kbd_irq.notif_cfg).notify && rcu_dereference_pointer(ski_kbd_irq.notif_cfg).answerbox) { |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
chardev_push_character(&ski_uconsole, ch); |
ipc_irq_send_notif(&ski_kbd_irq); |
} else { |
156,7 → 155,7 |
} |
if (last) { |
if (rcu_dereference_pointer(ski_kbd_irq.notif_cfg).notify && rcu_dereference_pointer(ski_kbd_irq.notif_cfg).answerbox) { |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
chardev_push_character(&ski_uconsole, 0); |
ipc_irq_send_notif(&ski_kbd_irq); |
} |
233,9 → 232,9 |
void ski_kbd_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
//rcu_read_lock() is not needed, ints are disabled |
//rcu: atomic update doesn't need reallocation |
rcu_dereference_pointer(ski_kbd_irq.notif_cfg).notify = false; |
spinlock_lock(&ski_kbd_irq.lock); |
ski_kbd_irq.notif_cfg.notify = false; |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
} |
242,10 → 241,9 |
void ski_kbd_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
//rcu: atomic update doesn't need reallocation |
spinlock_lock(&ski_kbd_irq.lock); |
if (rcu_dereference_pointer(ski_kbd_irq.notif_cfg).answerbox) |
rcu_dereference_pointer(ski_kbd_irq.notif_cfg).notify = true; |
if (ski_kbd_irq.notif_cfg.answerbox) |
ski_kbd_irq.notif_cfg.notify = true; |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
} |
/branches/rcu/kernel/arch/ppc32/src/drivers/cuda.c |
---|
41,7 → 41,6 |
#include <sysinfo/sysinfo.h> |
#include <interrupt.h> |
#include <stdarg.h> |
#include <synch/rcu.h> |
#define CUDA_IRQ 10 |
#define SPECIAL '?' |
250,7 → 249,7 |
static void cuda_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if ((rcu_dereference_pointer(irq->notif_cfg).notify) && (rcu_dereference_pointer(irq->notif_cfg).answerbox)) |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
else { |
int scan_code = cuda_get_scancode(); |
273,9 → 272,9 |
void cuda_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
//rcu_read_lock() is not needed, ints are disabled |
//rcu: atomic update doesn't need reallocation |
rcu_dereference_pointer(cuda_irq.notif_cfg).notify = false; |
spinlock_lock(&cuda_irq.lock); |
cuda_irq.notif_cfg.notify = false; |
spinlock_unlock(&cuda_irq.lock); |
interrupts_restore(ipl); |
} |
284,10 → 283,9 |
void cuda_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
//rcu: atomic update doesn't need reallocation |
spinlock_lock(&cuda_irq.lock); |
if (rcu_dereference_pointer(cuda_irq.notif_cfg).answerbox) |
rcu_dereference_pointer(cuda_irq.notif_cfg).notify = true; |
if (cuda_irq.notif_cfg.answerbox) |
cuda_irq.notif_cfg.notify = true; |
spinlock_unlock(&cuda_irq.unlock); |
interrupts_restore(ipl); |
} |
/branches/rcu/kernel/arch/mips32/src/drivers/serial.c |
---|
38,7 → 38,6 |
#include <arch/drivers/serial.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <synch/rcu.h> |
#define SERIAL_IRQ 2 |
113,7 → 112,7 |
/** Process keyboard interrupt. Does not work in simics? */ |
static void serial_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if ((rcu_dereference_pointer(irq->notif_cfg).notify) && (rcu_dereference_pointer(irq->notif_cfg).answerbox)) |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
else |
serial_handler(); |
/branches/rcu/kernel/arch/mips32/src/drivers/msim.c |
---|
39,7 → 39,6 |
#include <arch/cp0.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <synch/rcu.h> |
/** Address of devices. */ |
#define MSIM_VIDEORAM 0xB0000000 |
100,7 → 99,7 |
/** Process keyboard interrupt. */ |
static void msim_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if ((rcu_dereference_pointer(irq->notif_cfg).notify) && (rcu_dereference_pointer(irq->notif_cfg).answerbox)) |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
else { |
char ch = 0; |
122,9 → 121,9 |
void msim_kbd_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
//rcu_read_lock() is not needed, ints are disabled |
//rcu: atomic update doesn't need reallocation |
rcu_dereference_pointer(msim_irq.notif_cfg).notify = false; |
spinlock_lock(&msim_irq.lock); |
msim_irq.notif_cfg.notify = false; |
spinlock_unlock(&msim_irq.lock); |
interrupts_restore(ipl); |
} |
131,10 → 130,9 |
void msim_kbd_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
//rcu: atomic update doesn't need reallocation |
spinlock_lock(&msim_irq.lock); |
if (rcu_dereference_pointer(msim_irq.notif_cfg).answerbox) |
rcu_dereference_pointer(msim_irq.notif_cfg).notify = true; |
if (msim_irq.notif_cfg.answerbox) |
msim_irq.notif_cfg.notify = true; |
spinlock_unlock(&msim_irq.lock); |
interrupts_restore(ipl); |
} |
/branches/rcu/kernel/genarch/src/kbd/ns16550.c |
---|
51,7 → 51,6 |
#include <arch/interrupt.h> |
#include <sysinfo/sysinfo.h> |
#include <synch/spinlock.h> |
#include <synch/rcu.h> |
#define LSR_DATA_READY 0x01 |
87,9 → 86,9 |
while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) |
(void) ns16550_rbr_read(&ns16550); |
//rcu_read_lock() is not needed, ints are disabled |
//rcu: atomic update doesn't need reallocation |
rcu_dereference_pointer(ns16550_irq.notif_cfg).notify = false; |
spinlock_lock(&ns16550_irq.lock); |
ns16550_irq.notif_cfg.notify = false; |
spinlock_unlock(&ns16550_irq.lock); |
interrupts_restore(ipl); |
} |
97,10 → 96,9 |
void ns16550_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
//rcu: atomic update doesn't need reallocation |
spinlock_lock(&ns16550_irq.lock); |
if (rcu_dereference_pointer(ns16550_irq.notif_cfg).answerbox) |
rcu_dereference_pointer(ns16550_irq.notif_cfg).notify = true; |
if (ns16550_irq.notif_cfg.answerbox) |
ns16550_irq.notif_cfg.notify = true; |
spinlock_unlock(&ns16550_irq.lock); |
interrupts_restore(ipl); |
} |
185,7 → 183,7 |
spinlock_lock(&ns16550_irq.lock); |
if (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) { |
if (rcu_dereference_pointer(ns16550_irq.notif_cfg).notify && rcu_dereference_pointer(ns16550_irq.notif_cfg).answerbox) { |
if (ns16550_irq.notif_cfg.notify && ns16550_irq.notif_cfg.answerbox) { |
/* |
* Send IPC notification. |
*/ |
/branches/rcu/kernel/genarch/src/kbd/i8042.c |
---|
49,7 → 49,6 |
#include <interrupt.h> |
#include <sysinfo/sysinfo.h> |
#include <ipc/irq.h> |
#include <generic/synch/rcu.h> |
/* Keyboard commands. */ |
#define KBD_ENABLE 0xf4 |
108,11 → 107,13 |
i8042_data_write(i8042_COMMAND); |
i8042_wait(); |
//rcu_read_lock() is not needed, ints are disabled |
//rcu: atomic update doesn't need reallocation |
rcu_dereference_pointer(i8042_kbd_irq.notif_cfg).notify = false; |
spinlock_lock(&i8042_kbd_irq.lock); |
i8042_kbd_irq.notif_cfg.notify = false; |
spinlock_unlock(&i8042_kbd_irq.lock); |
rcu_dereference_pointer(i8042_mouse_irq.notif_cfg).notify = false; |
spinlock_lock(&i8042_mouse_irq.lock); |
i8042_mouse_irq.notif_cfg.notify = false; |
spinlock_unlock(&i8042_mouse_irq.lock); |
interrupts_restore(ipl); |
} |
120,15 → 121,15 |
void i8042_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
//rcu: atomic update doesn't need reallocation |
spinlock_lock(&i8042_kbd_irq.lock); |
if (rcu_dereference_pointer(i8042_kbd_irq.notif_cfg).answerbox) |
rcu_dereference_pointer(i8042_kbd_irq.notif_cfg).notify = true; |
if (i8042_kbd_irq.notif_cfg.answerbox) |
i8042_kbd_irq.notif_cfg.notify = true; |
spinlock_unlock(&i8042_kbd_irq.lock); |
spinlock_lock(&i8042_mouse_irq.lock); |
if (rcu_dereference_pointer(i8042_mouse_irq.notif_cfg).answerbox) |
rcu_dereference_pointer(i8042_mouse_irq.notif_cfg).notify = true; |
if (i8042_mouse_irq.notif_cfg.answerbox) |
i8042_mouse_irq.notif_cfg.notify = true; |
spinlock_unlock(&i8042_mouse_irq.lock); |
interrupts_restore(ipl); |
141,7 → 142,7 |
static void i8042_kbd_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if (rcu_dereference_pointer(irq->notif_cfg).notify && rcu_dereference_pointer(irq->notif_cfg).answerbox) |
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) |
ipc_irq_send_notif(irq); |
else { |
uint8_t x; |
163,7 → 164,7 |
static void i8042_mouse_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if (rcu_dereference_pointer(irq->notif_cfg).notify && rcu_dereference_pointer(irq->notif_cfg).answerbox) |
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) |
ipc_irq_send_notif(irq); |
} |
/branches/rcu/kernel/genarch/src/kbd/z8530.c |
---|
52,7 → 52,6 |
#include <interrupt.h> |
#include <sysinfo/sysinfo.h> |
#include <print.h> |
#include <synch/rcu.h> |
/* |
* These codes read from z8530 data register are silently ignored. |
91,9 → 90,9 |
z8530_write_a(&z8530, WR9, WR9_MIE); /* Master Interrupt Enable. */ |
//rcu_read_lock() is not needed, ints are disabled |
//rcu: atomic update doesn't need reallocation |
rcu_dereference_pointer(z8530_irq.notif_cfg).notify = false; |
spinlock_lock(&z8530_irq.lock); |
z8530_irq.notif_cfg.notify = false; |
spinlock_unlock(&z8530_irq.lock); |
interrupts_restore(ipl); |
} |
101,10 → 100,9 |
void z8530_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
//rcu: atomic update doesn't need reallocation |
spinlock_lock(&z8530_irq.lock); |
if (rcu_dereference_pointer(z8530_irq.notif_cfg).answerbox) |
rcu_dereference_pointer(z8530_irq.notif_cfg).notify = true; |
if (z8530_irq.notif_cfg.answerbox) |
z8530_irq.notif_cfg.notify = true; |
spinlock_unlock(&z8530_irq.lock); |
interrupts_restore(ipl); |
} |
206,7 → 204,7 |
* we cannot handle it by scheduling one of the level |
* interrupt traps. Process the interrupt directly. |
*/ |
if (rcu_dereference_pointer(irq->notif_cfg).notify && rcu_dereference_pointer(irq->notif_cfg).answerbox) |
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) |
ipc_irq_send_notif(irq); |
else |
z8530_interrupt(); |