source: mainline/kernel/generic/src/ipc/event.c@ 2845930

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2845930 was 13a638d, checked in by Martin Decky <martin@…>, 16 years ago

move event notification to the ipc directory (where it probably belogs to, side-by-side to IRQ notifications)
cleanup the notification code a little bit (there is probably no need to allocate two structured dynamically)

  • Property mode set to 100644
File size: 4.1 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 <ipc/event.h>
38#include <ipc/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 unsigned int i;
58
59 for (i = 0; i < EVENT_END; i++) {
60 spinlock_initialize(&events[i].lock, "event.lock");
61 events[i].answerbox = NULL;
62 events[i].counter = 0;
63 events[i].method = 0;
64 }
65}
66
67static int
68event_subscribe(event_type_t evno, unative_t method, answerbox_t *answerbox)
69{
70 if (evno >= EVENT_END)
71 return ELIMIT;
72
73 spinlock_lock(&events[evno].lock);
74
75 int res;
76
77 if (events[evno].answerbox == NULL) {
78 events[evno].answerbox = answerbox;
79 events[evno].method = method;
80 events[evno].counter = 0;
81 res = EOK;
82 } else
83 res = EEXISTS;
84
85 spinlock_unlock(&events[evno].lock);
86
87 return res;
88}
89
90unative_t sys_event_subscribe(unative_t evno, unative_t method)
91{
92 return (unative_t) event_subscribe((event_type_t) evno, (unative_t)
93 method, &TASK->answerbox);
94}
95
96bool event_is_subscribed(event_type_t evno)
97{
98 bool res;
99
100 ASSERT(evno < EVENT_END);
101
102 spinlock_lock(&events[evno].lock);
103 res = events[evno].answerbox != NULL;
104 spinlock_unlock(&events[evno].lock);
105
106 return res;
107}
108
109
110void event_cleanup_answerbox(answerbox_t *answerbox)
111{
112 unsigned int i;
113
114 for (i = 0; i < EVENT_END; i++) {
115 spinlock_lock(&events[i].lock);
116 if (events[i].answerbox == answerbox) {
117 events[i].answerbox = NULL;
118 events[i].counter = 0;
119 events[i].method = 0;
120 }
121 spinlock_unlock(&events[i].lock);
122 }
123}
124
125void
126event_notify(event_type_t evno, unative_t a1, unative_t a2, unative_t a3,
127 unative_t a4, unative_t a5)
128{
129 ASSERT(evno < EVENT_END);
130
131 spinlock_lock(&events[evno].lock);
132 if (events[evno].answerbox != NULL) {
133 call_t *call = ipc_call_alloc(FRAME_ATOMIC);
134 if (call) {
135 call->flags |= IPC_CALL_NOTIF;
136 call->priv = ++events[evno].counter;
137 IPC_SET_METHOD(call->data, events[evno].method);
138 IPC_SET_ARG1(call->data, a1);
139 IPC_SET_ARG2(call->data, a2);
140 IPC_SET_ARG3(call->data, a3);
141 IPC_SET_ARG4(call->data, a4);
142 IPC_SET_ARG5(call->data, a5);
143
144 spinlock_lock(&events[evno].answerbox->irq_lock);
145 list_append(&call->link, &events[evno].answerbox->irq_notifs);
146 spinlock_unlock(&events[evno].answerbox->irq_lock);
147
148 waitq_wakeup(&events[evno].answerbox->wq, WAKEUP_FIRST);
149 }
150 }
151 spinlock_unlock(&events[evno].lock);
152}
153
154/** @}
155 */
Note: See TracBrowser for help on using the repository browser.