31,8 → 31,8 |
* First the answerbox, then the phone |
*/ |
|
#include <synch/condvar.h> |
#include <synch/mutex.h> |
#include <synch/spinlock.h> |
#include <synch/waitq.h> |
#include <ipc/ipc.h> |
#include <errno.h> |
#include <mm/slab.h> |
84,8 → 84,8 |
*/ |
void ipc_answerbox_init(answerbox_t *box) |
{ |
mutex_initialize(&box->mutex); |
condvar_initialize(&box->cv); |
spinlock_initialize(&box->lock, "ipc_box_lock"); |
waitq_initialize(&box->wq); |
list_initialize(&box->connected_phones); |
list_initialize(&box->calls); |
list_initialize(&box->dispatched_calls); |
93,19 → 93,27 |
box->task = TASK; |
} |
|
/** Initialize phone structure and connect phone to naswerbox |
*/ |
void ipc_phone_init(phone_t *phone, answerbox_t *box) |
/** Connect phone to answerbox */ |
void ipc_phone_connect(phone_t *phone, answerbox_t *box) |
{ |
spinlock_initialize(&phone->lock, "phone_lock"); |
|
ASSERT(!phone->callee); |
phone->busy = 1; |
phone->callee = box; |
|
mutex_lock(&box->mutex); |
spinlock_lock(&box->lock); |
list_append(&phone->list, &box->connected_phones); |
mutex_unlock(&box->mutex); |
spinlock_unlock(&box->lock); |
} |
|
/** Initialize phone structure and connect phone to naswerbox |
*/ |
void ipc_phone_init(phone_t *phone) |
{ |
spinlock_initialize(&phone->lock, "phone_lock"); |
phone->callee = NULL; |
phone->busy = 0; |
} |
|
/** Disconnect phone from answerbox */ |
void ipc_phone_destroy(phone_t *phone) |
{ |
113,9 → 121,9 |
|
ASSERT(box); |
|
mutex_lock(&box->mutex); |
spinlock_lock(&box->lock); |
list_remove(&phone->list); |
mutex_unlock(&box->mutex); |
spinlock_unlock(&box->lock); |
} |
|
/** Helper function to facilitate synchronous calls */ |
137,18 → 145,36 |
* @param phone Phone connected to answerbox |
* @param request Request to be sent |
*/ |
void ipc_call(phone_t *phone, call_t *request) |
void ipc_call(phone_t *phone, call_t *call) |
{ |
answerbox_t *box = phone->callee; |
|
ASSERT(box); |
|
mutex_lock(&box->mutex); |
list_append(&request->list, &box->calls); |
mutex_unlock(&box->mutex); |
condvar_signal(&box->cv); |
spinlock_lock(&box->lock); |
list_append(&call->list, &box->calls); |
spinlock_unlock(&box->lock); |
waitq_wakeup(&box->wq, 0); |
} |
|
/** Forwards call from one answerbox to a new one |
* |
* @param request Request to be forwarded |
* @param newbox Target answerbox |
* @param oldbox Old answerbox |
*/ |
void ipc_forward(call_t *call, answerbox_t *newbox, answerbox_t *oldbox) |
{ |
spinlock_lock(&oldbox->lock); |
list_remove(&call->list); |
spinlock_unlock(&oldbox->lock); |
|
spinlock_lock(&newbox->lock); |
list_append(&call->list, &newbox->calls); |
spinlock_lock(&newbox->lock); |
waitq_wakeup(&newbox->wq, 0); |
} |
|
/** Answer message back to phone |
* |
* @param box Answerbox that is answering the message |
160,14 → 186,14 |
|
request->flags |= IPC_CALL_ANSWERED; |
|
mutex_lock(&box->mutex); |
spinlock_lock(&box->lock); |
list_remove(&request->list); |
mutex_unlock(&box->mutex); |
spinlock_unlock(&box->lock); |
|
mutex_lock(&callerbox->mutex); |
spinlock_lock(&callerbox->lock); |
list_append(&request->list, &callerbox->answers); |
mutex_unlock(&callerbox->mutex); |
condvar_signal(&callerbox->cv); |
spinlock_unlock(&callerbox->lock); |
waitq_wakeup(&callerbox->wq, 0); |
} |
|
/** Wait for phone call |
179,7 → 205,7 |
{ |
call_t *request; |
|
mutex_lock(&box->mutex); |
spinlock_lock(&box->lock); |
while (1) { |
if (!list_empty(&box->answers)) { |
/* Handle asynchronous answers */ |
194,7 → 220,9 |
} else { |
if (!(flags & IPC_WAIT_NONBLOCKING)) { |
/* Wait for event to appear */ |
condvar_wait(&box->cv, &box->mutex); |
spinlock_unlock(&box->lock); |
waitq_sleep(&box->wq); |
spinlock_lock(&box->lock); |
continue; |
} |
request = NULL; |
201,7 → 229,7 |
} |
break; |
} |
mutex_unlock(&box->mutex); |
spinlock_unlock(&box->lock); |
return request; |
} |
|