Subversion Repositories HelenOS

Rev

Rev 2359 | Rev 2637 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2359 Rev 2471
Line 130... Line 130...
130
#include <arch.h>
130
#include <arch.h>
131
#include <proc/task.h>
131
#include <proc/task.h>
132
#include <ipc/ipcrsc.h>
132
#include <ipc/ipcrsc.h>
133
#include <debug.h>
133
#include <debug.h>
134
 
134
 
135
/** Find call_t * in call table according to callid
135
/** Find call_t * in call table according to callid.
136
 *
136
 *
137
 * TODO: Some speedup (hash table?)
137
 * @todo Some speedup (hash table?)
-
 
138
 *
-
 
139
 * @param callid    Userspace hash of the call. Currently it is the call
-
 
140
 *          structure kernel address.
-
 
141
 *
138
 * @return NULL on not found, otherwise pointer to call structure
142
 * @return      NULL on not found, otherwise pointer to the call
-
 
143
 *          structure.
139
 */
144
 */
140
call_t * get_call(unative_t callid)
145
call_t *get_call(unative_t callid)
141
{
146
{
142
    link_t *lst;
147
    link_t *lst;
143
    call_t *call, *result = NULL;
148
    call_t *call, *result = NULL;
144
 
149
 
145
    spinlock_lock(&TASK->answerbox.lock);
150
    spinlock_lock(&TASK->answerbox.lock);
146
    for (lst = TASK->answerbox.dispatched_calls.next;
151
    for (lst = TASK->answerbox.dispatched_calls.next;
147
         lst != &TASK->answerbox.dispatched_calls; lst = lst->next) {
152
        lst != &TASK->answerbox.dispatched_calls; lst = lst->next) {
148
        call = list_get_instance(lst, call_t, link);
153
        call = list_get_instance(lst, call_t, link);
149
        if ((unative_t)call == callid) {
154
        if ((unative_t) call == callid) {
150
            result = call;
155
            result = call;
151
            break;
156
            break;
152
        }
157
        }
153
    }
158
    }
154
    spinlock_unlock(&TASK->answerbox.lock);
159
    spinlock_unlock(&TASK->answerbox.lock);
155
    return result;
160
    return result;
156
}
161
}
157
 
162
 
158
/** Allocate new phone slot in current TASK structure */
163
/** Allocate new phone slot in the current TASK structure.
-
 
164
 *
-
 
165
 * @return      New phone handle or -1 if the phone handle limit is
-
 
166
 *          exceeded.
-
 
167
 */
159
int phone_alloc(void)
168
int phone_alloc(void)
160
{
169
{
161
    int i;
170
    int i;
162
 
171
 
163
    spinlock_lock(&TASK->lock);
172
    spinlock_lock(&TASK->lock);
164
   
173
   
165
    for (i=0; i < IPC_MAX_PHONES; i++) {
174
    for (i = 0; i < IPC_MAX_PHONES; i++) {
166
        if (TASK->phones[i].state == IPC_PHONE_HUNGUP && \
175
        if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
167
            atomic_get(&TASK->phones[i].active_calls) == 0)
176
            atomic_get(&TASK->phones[i].active_calls) == 0)
168
            TASK->phones[i].state = IPC_PHONE_FREE;
177
            TASK->phones[i].state = IPC_PHONE_FREE;
169
 
178
 
170
        if (TASK->phones[i].state == IPC_PHONE_FREE) {
179
        if (TASK->phones[i].state == IPC_PHONE_FREE) {
171
            TASK->phones[i].state = IPC_PHONE_CONNECTING;
180
            TASK->phones[i].state = IPC_PHONE_CONNECTING;
Line 177... Line 186...
177
    if (i >= IPC_MAX_PHONES)
186
    if (i >= IPC_MAX_PHONES)
178
        return -1;
187
        return -1;
179
    return i;
188
    return i;
180
}
189
}
181
 
190
 
-
 
191
/** Mark a phone structure free.
-
 
192
 *
-
 
193
 * @param phone     Phone structure to be marked free.
-
 
194
 */
182
static void phone_deallocp(phone_t *phone)
195
static void phone_deallocp(phone_t *phone)
183
{
196
{
184
    ASSERT(phone->state == IPC_PHONE_CONNECTING);
197
    ASSERT(phone->state == IPC_PHONE_CONNECTING);
185
   
198
   
186
    /* atomic operation */
199
    /* atomic operation */
187
    phone->state = IPC_PHONE_FREE;
200
    phone->state = IPC_PHONE_FREE;
188
}
201
}
189
 
202
 
190
/** Free slot from a disconnected phone
203
/** Free slot from a disconnected phone.
-
 
204
 *
-
 
205
 * All already sent messages will be correctly processed.
191
 *
206
 *
192
 * All already sent messages will be correctly processed
207
 * @param phoneid   Phone handle of the phone to be freed.
193
 */
208
 */
194
void phone_dealloc(int phoneid)
209
void phone_dealloc(int phoneid)
195
{
210
{
196
    phone_deallocp(&TASK->phones[phoneid]);
211
    phone_deallocp(&TASK->phones[phoneid]);
197
}
212
}
198
 
213
 
199
/** Connect phone to a given answerbox
214
/** Connect phone to a given answerbox.
200
 *
215
 *
201
 * @param phoneid The slot that will be connected
216
 * @param phoneid   Phone handle to be connected.
-
 
217
 * @param box       Answerbox to which to connect the phone handle.
202
 *
218
 *
203
 * The procedure _enforces_ that the user first marks the phone
219
 * The procedure _enforces_ that the user first marks the phone
204
 * busy (e.g. via phone_alloc) and then connects the phone, otherwise
220
 * busy (e.g. via phone_alloc) and then connects the phone, otherwise
205
 * race condition may appear.
221
 * race condition may appear.
206
 */
222
 */