source: mainline/kernel/generic/src/event/event.c@ c3ebc47

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c3ebc47 was 05641a9e, checked in by Jakub Jermar <jakub@…>, 17 years ago

Revive kernel notifications.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2 * Copyright (c) 2009 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup generic
30 * @{
31 */
32/**
33 * @file
34 * @brief Kernel event notifications.
35 */
36
37#include <event/event.h>
38#include <event/event_types.h>
39#include <mm/slab.h>
40#include <arch/types.h>
41#include <synch/spinlock.h>
42#include <console/console.h>
43#include <memstr.h>
44#include <errno.h>
45#include <arch.h>
46
47/**
48 * The events array.
49 * Arranging the events in this two-dimensional array should decrease the
50 * likelyhood of cacheline ping-pong.
51 */
52static event_t *events[EVENT_END];
53
54/** Initialize kernel events. */
55void event_init(void)
56{
57 int i;
58
59 for (i = 0; i < EVENT_END; i++) {
60 events[i] = (event_t *) malloc(sizeof(event_t), 0);
61 spinlock_initialize(&events[i]->lock, "event.lock");
62 events[i]->answerbox = NULL;
63 events[i]->counter = 0;
64 events[i]->method = 0;
65 }
66}
67
68static int
69event_subscribe(event_type_t e, unative_t method, answerbox_t *answerbox)
70{
71 if (e >= EVENT_END)
72 return ELIMIT;
73
74 int res = EEXISTS;
75 event_t *event = events[e];
76
77 spinlock_lock(&event->lock);
78 if (!event->answerbox) {
79 event->answerbox = answerbox;
80 event->method = method;
81 event->counter = 0;
82 res = EOK;
83 }
84 spinlock_unlock(&event->lock);
85
86 return res;
87}
88
89unative_t sys_event_subscribe(unative_t evno, unative_t method)
90{
91 return (unative_t) event_subscribe((event_type_t) evno, (unative_t)
92 method, &TASK->answerbox);
93}
94
95bool event_is_subscribed(event_type_t e)
96{
97 bool res;
98
99 ASSERT(e < EVENT_END);
100 spinlock_lock(&events[e]->lock);
101 res = events[e]->answerbox != NULL;
102 spinlock_unlock(&events[e]->lock);
103
104 return res;
105}
106
107
108void event_cleanup_answerbox(answerbox_t *answerbox)
109{
110 int i;
111
112 for (i = 0; i < EVENT_END; i++) {
113 spinlock_lock(&events[i]->lock);
114 if (events[i]->answerbox == answerbox) {
115 events[i]->answerbox = NULL;
116 events[i]->counter = 0;
117 events[i]->method = 0;
118 }
119 spinlock_unlock(&events[i]->lock);
120 }
121}
122
123void
124event_notify(event_type_t e, unative_t a1, unative_t a2, unative_t a3,
125 unative_t a4, unative_t a5)
126{
127 ASSERT(e < EVENT_END);
128 event_t *event = events[e];
129 spinlock_lock(&event->lock);
130 if (event->answerbox) {
131 call_t *call = ipc_call_alloc(FRAME_ATOMIC);
132 if (call) {
133 call->flags |= IPC_CALL_NOTIF;
134 call->priv = ++event->counter;
135 IPC_SET_METHOD(call->data, event->method);
136 IPC_SET_ARG1(call->data, a1);
137 IPC_SET_ARG2(call->data, a2);
138 IPC_SET_ARG3(call->data, a3);
139 IPC_SET_ARG4(call->data, a4);
140 IPC_SET_ARG5(call->data, a5);
141
142 spinlock_lock(&event->answerbox->irq_lock);
143 list_append(&call->link, &event->answerbox->irq_notifs);
144 spinlock_unlock(&event->answerbox->irq_lock);
145
146 waitq_wakeup(&event->answerbox->wq, WAKEUP_FIRST);
147 }
148 }
149 spinlock_unlock(&event->lock);
150}
151
152/** @}
153 */
Note: See TracBrowser for help on using the repository browser.