Changeset f9061b4 in mainline
- Timestamp:
- 2011-05-16T13:38:04Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4e1a2f5
- Parents:
- e0f52bf
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/ipc/event.h
re0f52bf rf9061b4 51 51 /** Counter. */ 52 52 size_t counter; 53 /** Masked flag. */ 54 bool masked; 53 55 } event_t; 54 56 55 57 extern void event_init(void); 56 extern sysarg_t sys_event_subscribe(sysarg_t, sysarg_t);57 extern bool event_is_subscribed(event_type_t);58 58 extern void event_cleanup_answerbox(answerbox_t *); 59 59 60 #define event_notify_0(e ) \61 event_notify((e), 0, 0, 0, 0, 0)62 #define event_notify_1(e, a1) \63 event_notify((e), ( a1), 0, 0, 0, 0)64 #define event_notify_2(e, a1, a2) \65 event_notify((e), ( a1), (a2), 0, 0, 0)66 #define event_notify_3(e, a1, a2, a3) \67 event_notify((e), ( a1), (a2), (a3), 0, 0)68 #define event_notify_4(e, a1, a2, a3, a4) \69 event_notify((e), ( a1), (a2), (a3), (a4), 0)70 #define event_notify_5(e, a1, a2, a3, a4, a5) \71 event_notify((e), ( a1), (a2), (a3), (a4), (a5))60 #define event_notify_0(e, m) \ 61 event_notify((e), (m), 0, 0, 0, 0, 0) 62 #define event_notify_1(e, m, a1) \ 63 event_notify((e), (m), (a1), 0, 0, 0, 0) 64 #define event_notify_2(e, m, a1, a2) \ 65 event_notify((e), (m), (a1), (a2), 0, 0, 0) 66 #define event_notify_3(e, m, a1, a2, a3) \ 67 event_notify((e), (m), (a1), (a2), (a3), 0, 0) 68 #define event_notify_4(e, m, a1, a2, a3, a4) \ 69 event_notify((e), (m), (a1), (a2), (a3), (a4), 0) 70 #define event_notify_5(e, m, a1, a2, a3, a4, a5) \ 71 event_notify((e), (m), (a1), (a2), (a3), (a4), (a5)) 72 72 73 extern void event_notify(event_type_t, sysarg_t, sysarg_t, sysarg_t,73 extern int event_notify(event_type_t, bool, sysarg_t, sysarg_t, sysarg_t, 74 74 sysarg_t, sysarg_t); 75 76 extern sysarg_t sys_event_subscribe(sysarg_t, sysarg_t); 77 extern sysarg_t sys_event_unmask(sysarg_t); 75 78 76 79 #endif -
kernel/generic/include/ipc/event_types.h
re0f52bf rf9061b4 39 39 /** New data available in kernel log */ 40 40 EVENT_KLOG = 0, 41 /** Returning from kernel console to us erspace */41 /** Returning from kernel console to uspace */ 42 42 EVENT_KCONSOLE, 43 43 /** A task/thread has faulted and will be terminated */ -
kernel/generic/include/syscall/syscall.h
re0f52bf rf9061b4 75 75 76 76 SYS_EVENT_SUBSCRIBE, 77 SYS_EVENT_UNMASK, 77 78 78 79 SYS_CAP_GRANT, -
kernel/generic/src/console/cmd.c
re0f52bf rf9061b4 1107 1107 release_console(); 1108 1108 1109 event_notify_0(EVENT_KCONSOLE );1109 event_notify_0(EVENT_KCONSOLE, false); 1110 1110 indev_pop_character(stdin); 1111 1111 -
kernel/generic/src/console/console.c
re0f52bf rf9061b4 265 265 spinlock_lock(&klog_lock); 266 266 267 if ((klog_inited) && (event_is_subscribed(EVENT_KLOG)) && (klog_uspace > 0)) { 268 event_notify_3(EVENT_KLOG, klog_start, klog_len, klog_uspace); 269 klog_uspace = 0; 267 if ((klog_inited) && (klog_uspace > 0)) { 268 if (event_notify_3(EVENT_KLOG, true, klog_start, klog_len, 269 klog_uspace) == EOK) 270 klog_uspace = 0; 270 271 } 271 272 -
kernel/generic/src/ipc/event.c
re0f52bf rf9061b4 48 48 static event_t events[EVENT_END]; 49 49 50 /** Initialize kernel events. */ 50 /** Initialize kernel events. 51 * 52 */ 51 53 void event_init(void) 52 54 { 53 unsigned int i; 54 55 for (i = 0; i < EVENT_END; i++) { 55 for (unsigned int i = 0; i < EVENT_END; i++) { 56 56 spinlock_initialize(&events[i].lock, "event.lock"); 57 57 events[i].answerbox = NULL; 58 58 events[i].counter = 0; 59 59 events[i].imethod = 0; 60 events[i].masked = false; 60 61 } 61 62 } 62 63 64 /** Unsubscribe kernel events associated with an answerbox 65 * 66 * @param answerbox Answerbox to be unsubscribed. 67 * 68 */ 69 void event_cleanup_answerbox(answerbox_t *answerbox) 70 { 71 for (unsigned int i = 0; i < EVENT_END; i++) { 72 spinlock_lock(&events[i].lock); 73 74 if (events[i].answerbox == answerbox) { 75 events[i].answerbox = NULL; 76 events[i].counter = 0; 77 events[i].imethod = 0; 78 events[i].masked = false; 79 } 80 81 spinlock_unlock(&events[i].lock); 82 } 83 } 84 85 /** Send kernel notification event 86 * 87 * @param evno Event type. 88 * @param mask Mask further notifications after a successful 89 * sending. 90 * @param a1 First argument. 91 * @param a2 Second argument. 92 * @param a3 Third argument. 93 * @param a4 Fourth argument. 94 * @param a5 Fifth argument. 95 * 96 * @return EOK if notification was successfully sent. 97 * @return ENOMEM if the notification IPC message failed to allocate. 98 * @return EBUSY if the notifications of the given type are 99 * currently masked. 100 * @return ENOENT if the notifications of the given type are 101 * currently not subscribed. 102 * 103 */ 104 int event_notify(event_type_t evno, bool mask, sysarg_t a1, sysarg_t a2, 105 sysarg_t a3, sysarg_t a4, sysarg_t a5) 106 { 107 ASSERT(evno < EVENT_END); 108 109 spinlock_lock(&events[evno].lock); 110 111 int ret; 112 113 if (events[evno].answerbox != NULL) { 114 if (!events[evno].masked) { 115 call_t *call = ipc_call_alloc(FRAME_ATOMIC); 116 117 if (call) { 118 call->flags |= IPC_CALL_NOTIF; 119 call->priv = ++events[evno].counter; 120 121 IPC_SET_IMETHOD(call->data, events[evno].imethod); 122 IPC_SET_ARG1(call->data, a1); 123 IPC_SET_ARG2(call->data, a2); 124 IPC_SET_ARG3(call->data, a3); 125 IPC_SET_ARG4(call->data, a4); 126 IPC_SET_ARG5(call->data, a5); 127 128 irq_spinlock_lock(&events[evno].answerbox->irq_lock, true); 129 list_append(&call->link, &events[evno].answerbox->irq_notifs); 130 irq_spinlock_unlock(&events[evno].answerbox->irq_lock, true); 131 132 waitq_wakeup(&events[evno].answerbox->wq, WAKEUP_FIRST); 133 134 if (mask) 135 events[evno].masked = true; 136 137 ret = EOK; 138 } else 139 ret = ENOMEM; 140 } else 141 ret = EBUSY; 142 } else 143 ret = ENOENT; 144 145 spinlock_unlock(&events[evno].lock); 146 147 return ret; 148 } 149 150 /** Subscribe event notifications 151 * 152 * @param evno Event type. 153 * @param imethod IPC interface and method to be used for 154 * the notifications. 155 * @param answerbox Answerbox to send the notifications to. 156 * 157 * @return EOK if the subscription was successful. 158 * @return EEXISTS if the notifications of the given type are 159 * already subscribed. 160 * 161 */ 63 162 static int event_subscribe(event_type_t evno, sysarg_t imethod, 64 163 answerbox_t *answerbox) 65 164 { 66 if (evno >= EVENT_END) 67 return ELIMIT; 165 ASSERT(evno < EVENT_END); 68 166 69 167 spinlock_lock(&events[evno].lock); … … 75 173 events[evno].imethod = imethod; 76 174 events[evno].counter = 0; 175 events[evno].masked = false; 77 176 res = EOK; 78 177 } else … … 84 183 } 85 184 185 /** Unmask event notifications 186 * 187 * @param evno Event type to unmask. 188 * 189 */ 190 static void event_unmask(event_type_t evno) 191 { 192 ASSERT(evno < EVENT_END); 193 194 spinlock_lock(&events[evno].lock); 195 events[evno].masked = false; 196 spinlock_unlock(&events[evno].lock); 197 } 198 199 /** Event notification syscall wrapper 200 * 201 * @param evno Event type to subscribe. 202 * @param imethod IPC interface and method to be used for 203 * the notifications. 204 * 205 * @return EOK on success. 206 * @return ELIMIT on unknown event type. 207 * @return EEXISTS if the notifications of the given type are 208 * already subscribed. 209 * 210 */ 86 211 sysarg_t sys_event_subscribe(sysarg_t evno, sysarg_t imethod) 87 212 { 213 if (evno >= EVENT_END) 214 return ELIMIT; 215 88 216 return (sysarg_t) event_subscribe((event_type_t) evno, (sysarg_t) 89 217 imethod, &TASK->answerbox); 90 218 } 91 219 92 bool event_is_subscribed(event_type_t evno) 93 { 94 bool res; 95 96 ASSERT(evno < EVENT_END); 97 98 spinlock_lock(&events[evno].lock); 99 res = events[evno].answerbox != NULL; 100 spinlock_unlock(&events[evno].lock); 101 102 return res; 103 } 104 105 106 void event_cleanup_answerbox(answerbox_t *answerbox) 107 { 108 unsigned int i; 109 110 for (i = 0; i < EVENT_END; i++) { 111 spinlock_lock(&events[i].lock); 112 if (events[i].answerbox == answerbox) { 113 events[i].answerbox = NULL; 114 events[i].counter = 0; 115 events[i].imethod = 0; 116 } 117 spinlock_unlock(&events[i].lock); 118 } 119 } 120 121 void event_notify(event_type_t evno, sysarg_t a1, sysarg_t a2, sysarg_t a3, 122 sysarg_t a4, sysarg_t a5) 123 { 124 ASSERT(evno < EVENT_END); 125 126 spinlock_lock(&events[evno].lock); 127 if (events[evno].answerbox != NULL) { 128 call_t *call = ipc_call_alloc(FRAME_ATOMIC); 129 if (call) { 130 call->flags |= IPC_CALL_NOTIF; 131 call->priv = ++events[evno].counter; 132 IPC_SET_IMETHOD(call->data, events[evno].imethod); 133 IPC_SET_ARG1(call->data, a1); 134 IPC_SET_ARG2(call->data, a2); 135 IPC_SET_ARG3(call->data, a3); 136 IPC_SET_ARG4(call->data, a4); 137 IPC_SET_ARG5(call->data, a5); 138 139 irq_spinlock_lock(&events[evno].answerbox->irq_lock, true); 140 list_append(&call->link, &events[evno].answerbox->irq_notifs); 141 irq_spinlock_unlock(&events[evno].answerbox->irq_lock, true); 142 143 waitq_wakeup(&events[evno].answerbox->wq, WAKEUP_FIRST); 144 } 145 } 146 spinlock_unlock(&events[evno].lock); 220 /** Event notification unmask syscall wrapper 221 * 222 * Note that currently no tests are performed whether the calling 223 * task is entitled to unmask the notifications. However, thanks 224 * to the fact that notification masking is only a performance 225 * optimization, this has probably no security implications. 226 * 227 * @param evno Event type to unmask. 228 * 229 * @return EOK on success. 230 * @return ELIMIT on unknown event type. 231 * 232 */ 233 sysarg_t sys_event_unmask(sysarg_t evno) 234 { 235 if (evno >= EVENT_END) 236 return ELIMIT; 237 238 event_unmask((event_type_t) evno); 239 return EOK; 147 240 } 148 241 -
kernel/generic/src/proc/task.c
re0f52bf rf9061b4 534 534 */ 535 535 if (notify) { 536 if (event_is_subscribed(EVENT_FAULT)) { 537 /* Notify the subscriber that a fault occurred. */ 538 event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid), 539 UPPER32(TASK->taskid), (sysarg_t) THREAD); 540 536 /* Notify the subscriber that a fault occurred. */ 537 if (event_notify_3(EVENT_FAULT, false, LOWER32(TASK->taskid), 538 UPPER32(TASK->taskid), (sysarg_t) THREAD) == EOK) { 541 539 #ifdef CONFIG_UDEBUG 542 540 /* Wait for a debugging session. */ -
kernel/generic/src/syscall/syscall.c
re0f52bf rf9061b4 161 161 /* Event notification syscalls. */ 162 162 (syshandler_t) sys_event_subscribe, 163 (syshandler_t) sys_event_unmask, 163 164 164 165 /* Capabilities related syscalls. */ -
uspace/app/klog/klog.c
re0f52bf rf9061b4 74 74 fsync(fileno(log)); 75 75 } 76 77 event_unmask(EVENT_KLOG); 76 78 } 77 79 … … 111 113 } 112 114 113 rc = event_subscribe(EVENT_KLOG, 0);114 if (rc != EOK) {115 fprintf(stderr, "%s: Unable to register klog notifications\n",116 NAME);117 return rc;118 }119 120 115 log = fopen(LOG_FNAME, "a"); 121 116 if (log == NULL) … … 124 119 125 120 async_set_interrupt_received(interrupt_received); 121 rc = event_subscribe(EVENT_KLOG, 0); 122 if (rc != EOK) { 123 fclose(log); 124 fprintf(stderr, "%s: Unable to register klog notifications\n", 125 NAME); 126 return rc; 127 } 128 129 event_unmask(EVENT_KLOG); 130 126 131 klog_update(); 127 132 async_manager(); -
uspace/lib/c/generic/event.c
re0f52bf rf9061b4 41 41 #include <kernel/ipc/event_types.h> 42 42 43 /** Subscribe forevent notifications.43 /** Subscribe event notifications. 44 44 * 45 * @param evno Event number.46 * @param method Use thismethod for notifying me.45 * @param evno Event type to subscribe. 46 * @param imethod Use this interface and method for notifying me. 47 47 * 48 48 * @return Value returned by the kernel. 49 * 49 50 */ 50 int event_subscribe(event_type_t e , sysarg_tmethod)51 int event_subscribe(event_type_t evno, sysarg_t imethod) 51 52 { 52 return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) e, (sysarg_t) method); 53 return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno, 54 (sysarg_t) imethod); 55 } 56 57 /** Unmask event notifications. 58 * 59 * @param evno Event type to unmask. 60 * 61 * @return Value returned by the kernel. 62 * 63 */ 64 int event_unmask(event_type_t evno) 65 { 66 return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno); 53 67 } 54 68 -
uspace/lib/c/include/event.h
re0f52bf rf9061b4 39 39 40 40 extern int event_subscribe(event_type_t, sysarg_t); 41 extern int event_unmask(event_type_t); 41 42 42 43 #endif
Note:
See TracChangeset
for help on using the changeset viewer.