source: mainline/kernel/generic/include/ipc/ipc.h@ bab75df6

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

Use user-defined labels instead of phone hashes

This commit changes the way how the async framework maps incomming calls
to connections. Instead of abusing the kernel addresses of attached
phones as identifiers, the IPC_M_CONNECT_TO_ME and IPC_M_CONNECT_ME_TO
messages allow the server to specify an arbitrary label which is
remembered in the connected phone and consequently imprinted on each
call which is routed through this phone.

The async framework uses the address of the connection structure as the
label. This removes the need for a connection hash table because each
incoming call already remembers the connection in its label.

To disambiguate this new label and the other user-defined label used for
answers, the call structure now has the request_label member for the
former and answer_label member for the latter.

This commit also moves the kernel definition of ipc_data_t to abi/ and
removes the uspace redefinition thereof. Finally, when forwarding the
IPC_M_CONNECT_TO_ME call, the phone capability and the kernel object
allocated in request_process are now correctly disposed of.

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 * Copyright (c) 2006 Ondrej Palkovsky
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 kernel_generic_ipc
30 * @{
31 */
32/** @file
33 */
34
35#ifndef KERN_IPC_H_
36#define KERN_IPC_H_
37
38#include <synch/spinlock.h>
39#include <synch/mutex.h>
40#include <synch/waitq.h>
41#include <abi/ipc/ipc.h>
42#include <abi/proc/task.h>
43#include <typedefs.h>
44#include <mm/slab.h>
45#include <cap/cap.h>
46
47struct answerbox;
48struct task;
49
50typedef enum {
51 /** Phone is free and can be allocated */
52 IPC_PHONE_FREE = 0,
53 /** Phone is connecting somewhere */
54 IPC_PHONE_CONNECTING,
55 /** Phone is connected */
56 IPC_PHONE_CONNECTED,
57 /** Phone is hung up, waiting for answers to come */
58 IPC_PHONE_HUNGUP,
59 /** Phone was hungup from server */
60 IPC_PHONE_SLAMMED
61} ipc_phone_state_t;
62
63/** Structure identifying phone (in TASK structure) */
64typedef struct phone {
65 mutex_t lock;
66 link_t link;
67 struct task *caller;
68 struct answerbox *callee;
69 ipc_phone_state_t state;
70 atomic_t active_calls;
71 /** User-defined label */
72 sysarg_t label;
73 kobject_t *kobject;
74} phone_t;
75
76typedef struct answerbox {
77 IRQ_SPINLOCK_DECLARE(lock);
78
79 /** Answerbox is active until it enters cleanup. */
80 bool active;
81
82 struct task *task;
83
84 waitq_t wq;
85
86 /**
87 * Number of answers the answerbox is expecting to eventually arrive.
88 */
89 atomic_t active_calls;
90
91 /** Phones connected to this answerbox. */
92 list_t connected_phones;
93 /** Received calls. */
94 list_t calls;
95 list_t dispatched_calls; /* Should be hash table in the future */
96
97 /** Answered calls. */
98 list_t answers;
99
100 IRQ_SPINLOCK_DECLARE(irq_lock);
101
102 /** Notifications from IRQ handlers. */
103 list_t irq_notifs;
104} answerbox_t;
105
106typedef struct call {
107 kobject_t *kobject;
108
109 /**
110 * Task link.
111 * Valid only when the call is not forgotten.
112 * Protected by the task's active_calls_lock.
113 */
114 link_t ta_link;
115
116 /** Answerbox link. */
117 link_t ab_link;
118
119 unsigned int flags;
120
121 /** Protects the forget member. */
122 SPINLOCK_DECLARE(forget_lock);
123
124 /**
125 * True if the caller 'forgot' this call and donated it to the callee.
126 * Forgotten calls are discarded upon answering (the answer is not
127 * delivered) and answered calls cannot be forgotten. Forgotten calls
128 * also do not figure on the task's active call list.
129 *
130 * We keep this separate from the flags so that it is not necessary
131 * to take a lock when accessing them.
132 */
133 bool forget;
134
135 /** True if the call is in the active list. */
136 bool active;
137
138 /**
139 * Identification of the caller.
140 * Valid only when the call is not forgotten.
141 */
142 struct task *sender;
143
144 /*
145 * Answerbox that will receive the answer.
146 * This will most of the times be the sender's answerbox,
147 * but we allow for useful exceptions.
148 */
149 answerbox_t *callerbox;
150
151 /** Phone which was used to send the call. */
152 phone_t *caller_phone;
153
154 /** Private data to internal IPC. */
155 sysarg_t priv;
156
157 /** Data passed from/to userspace. */
158 ipc_data_t data;
159
160 /** Method as it was sent in the request. */
161 sysarg_t request_method;
162
163 /** Buffer for IPC_M_DATA_WRITE and IPC_M_DATA_READ. */
164 uint8_t *buffer;
165} call_t;
166
167extern slab_cache_t *phone_cache;
168
169extern answerbox_t *ipc_box_0;
170
171extern void ipc_init(void);
172
173extern call_t *ipc_call_alloc(unsigned int);
174extern void ipc_call_free(call_t *);
175extern void ipc_call_hold(call_t *);
176extern void ipc_call_release(call_t *);
177
178extern errno_t ipc_call_sync(phone_t *, call_t *);
179extern errno_t ipc_call(phone_t *, call_t *);
180extern errno_t ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int, call_t **);
181extern errno_t ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int);
182extern void ipc_answer(answerbox_t *, call_t *);
183extern void _ipc_answer_free_call(call_t *, bool);
184
185extern void ipc_phone_init(phone_t *, struct task *);
186extern bool ipc_phone_connect(phone_t *, answerbox_t *);
187extern errno_t ipc_phone_hangup(phone_t *);
188
189extern void ipc_answerbox_init(answerbox_t *, struct task *);
190
191extern void ipc_cleanup(void);
192extern void ipc_backsend_err(phone_t *, call_t *, errno_t);
193extern void ipc_answerbox_slam_phones(answerbox_t *, bool);
194extern void ipc_cleanup_call_list(answerbox_t *, list_t *);
195
196extern void ipc_print_task(task_id_t);
197
198#endif
199
200/** @}
201 */
Note: See TracBrowser for help on using the repository browser.