All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 547aeabd authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan

First draft of ipc done.

Abandoned many-to-many.
parent 173b9e47
......@@ -274,20 +274,9 @@ static inline int __lcd_cnode_is_sync_ep(struct cnode *cnode)
struct sync_endpoint {
struct list_head senders;
struct list_head receivers;
struct list_head proxies;
struct mutex lock;
};
struct sync_endpoint_proxy {
struct lcd *parent;
struct sync_endpoint *endpoint;
struct list_head lcd_active_list;
struct list_head endpoint_active_list;
struct list_head proxies;
};
/**
* Create a synchronous end point, and install it in lcd's cspace
* at location cptr.
......
......@@ -49,15 +49,8 @@ static void copy_call_endpoint(struct lcd *from, struct lcd *to)
return;
}
static void transfer_msg(struct sync_endpoint_proxy *from_proxy,
struct sync_endpoint_proxy *to_proxy,
int making_call)
static void transfer_msg(struct lcd *from, struct lcd *to, int making_call)
{
struct lcd *from;
struct lcd *to;
from = from_proxy->parent;
to = to_proxy->parent;
/*
* Copy valid regs
*/
......@@ -72,18 +65,16 @@ static void transfer_msg(struct sync_endpoint_proxy *from_proxy,
return;
}
static int lcd_do_send(struct lcd *lcd, cptr_t c, int making_call)
static int lcd_do_send(struct lcd *from, cptr_t c, int making_call)
{
int ret;
struct sync_endpoint_proxy *from_proxy;
struct sync_endpoing_proxy *to_proxy;
struct sync_endpoint *e;
struct lcd *to;
struct cnode *cnode;
/*
* Lookup cnode
*/
ret = __lcd_lookup_cnode(lcd->cspace, c, &cnode);
ret = __lcd_lookup_cnode(from->cspace, c, &cnode);
if (ret)
goto fail1;
/*
......@@ -94,10 +85,9 @@ static int lcd_do_send(struct lcd *lcd, cptr_t c, int making_call)
goto fail1;
}
/*
* Get synch end point proxy and end point
* Get synch end point
*/
from_proxy = __lcd_cnode_object(cnode);
e = from_proxy->endpoint;
e = __lcd_cnode_object(cnode);
/*
* Check if any recvr waiting, and do immediate send, wake up
* recvr
......@@ -108,20 +98,17 @@ static int lcd_do_send(struct lcd *lcd, cptr_t c, int making_call)
mutex_lock(&e->lock);
if (list_empty(&e->receivers)) {
/*
* No one receiving; put myself in e's sender list and lcd's
* sending eps list.
*
* XXX: maybe we want per-lcd lock?
* No one receiving; put myself in e's sender list
*/
list_add_tail(&from_proxy->lcd_proxy_list, &lcd->sending_eps);
list_add_tail(&from_proxy->endpoint_proxy_list, &e->senders);
list_add_tail(&from->senders, &e->senders);
/*
* Mark myself as making a call, if necessary, so that recvr
* knows it needs to copy reply rendezvous point cap.
*/
lcd->making_call = making_call;
from->making_call = making_call;
/*
* IMPORTANT: Must unlock cap before going to sleep.
* IMPORTANT: Must unlock cap and e's lock before going to
* sleep.
*/
mutex_unlock(&e->unlock());
lcd_cap_unlock();
......@@ -135,7 +122,7 @@ static int lcd_do_send(struct lcd *lcd, cptr_t c, int making_call)
*
* Reset making_call var.
*/
lcd->making_call = 0;
from->making_call = 0;
lcd_cap_lock();
return 0;
......@@ -145,10 +132,8 @@ static int lcd_do_send(struct lcd *lcd, cptr_t c, int making_call)
* Otherwise, someone waiting to receive. Remove from
* receiving queue.
*/
to_proxy = list_first_entry(&e->receivers, struct sync_endpoint_proxy,
endpoint_proxy_list);
list_del_init(&to_proxy->endpoint_proxy_list);
list_del_init(&to_proxy->lcd_proxy_list);
to = list_first_entry(&e->receivers, struct lcd, receivers);
list_del_init(&to->receivers);
mutex_unlock(&e->lock);
/*
......@@ -160,11 +145,11 @@ static int lcd_do_send(struct lcd *lcd, cptr_t c, int making_call)
/*
* Send message, and wake up lcd
*/
transfer_msg(from_proxy, to_proxy, making_call);
transfer_msg(from, to, making_call);
lcd_cap_lock();
wake_up_process(to_proxy->parent->parent);
wake_up_process(to->parent);
return 0;
fail1:
......@@ -191,18 +176,17 @@ int __lcd_send(struct lcd *lcd, cptr_t c)
return ret;
}
static int lcd_do_recv(struct lcd *lcd, cptr_t c)
static int lcd_do_recv(struct lcd *to, cptr_t c)
{
int ret;
struct sync_endpoint_proxy *from_proxy;
struct sync_endpoing_proxy *to_proxy;
struct lcd *from;
struct sync_endpoint *e;
struct cnode *cnode;
/*
* Lookup cnode
*/
ret = __lcd_lookup_cnode(lcd->cspace, c, &cnode);
ret = __lcd_lookup_cnode(to->cspace, c, &cnode);
if (ret)
goto fail1;
/*
......@@ -215,8 +199,7 @@ static int lcd_do_recv(struct lcd *lcd, cptr_t c)
/*
* Get synch end point proxy and end point
*/
to_proxy = __lcd_cnode_object(cnode);
e = to_proxy->endpoint;
e = __lcd_cnode_object(cnode);
/*
* Check if any sender waiting, and do immediate recv, wake up
* sender
......@@ -232,8 +215,7 @@ static int lcd_do_recv(struct lcd *lcd, cptr_t c)
*
* XXX: maybe we want per-lcd lock?
*/
list_add_tail(&to_proxy->lcd_proxy_list, &lcd->recving_eps);
list_add_tail(&to_proxy->endpoint_proxy_list, &e->receivers);
list_add_tail(&to->receivers, &e->receivers);
/*
*
* IMPORTANT: Must unlock cap before going to sleep.
......@@ -256,10 +238,8 @@ static int lcd_do_recv(struct lcd *lcd, cptr_t c)
* Otherwise, someone waiting to receive. Remove from
* sending queue.
*/
from_proxy = list_first_entry(&e->senders, struct sync_endpoint_proxy,
endpoint_proxy_list);
list_del_init(&from_proxy->endpoint_proxy_list);
list_del_init(&from_proxy->lcd_proxy_list);
from = list_first_entry(&e->senders, struct lcd, senders);
list_del_init(&from->senders);
mutex_unlock(&e->lock);
/*
......@@ -271,11 +251,11 @@ static int lcd_do_recv(struct lcd *lcd, cptr_t c)
/*
* Send message, and wake up lcd
*/
transfer_msg(from_proxy, to_proxy, from_proxy->parent->making_call);
transfer_msg(from, to, from->making_call);
lcd_cap_lock();
wake_up_process(to_proxy->parent->parent);
wake_up_process(from->parent);
return 0;
fail1:
......@@ -342,12 +322,6 @@ int __lcd_reply(struct lcd *lcd)
return ret;
}
int __lcd_select(struct task_struct *from, cptr_t *cs, int cs_count,
cptr_t *c_out)
{
return -ENOSYS;
}
int lcd_mk_sync_endpoint(struct lcd *lcd, cptr_t c)
{
struct sync_endpoint *e;
......@@ -505,29 +479,3 @@ int lcd_rm_sync_endpoint(struct lcd *lcd, cptr_t cptr)
lcd_cap_unlock();
return ret;
}
int ipc_reply(capability_t cap, struct message_info *msg)
{
return ipc_send(cap, msg);
}
EXPORT_SYMBOL(ipc_reply);
int ipc_call(capability_t cap, struct message_info *msg)
{
int ret;
// The last capability register is expected to
// have the reply capability
if (msg->valid_cap_regs == 0)
return -EINVAL;
ret = ipc_send(cap, msg);
if (ret)
return ret;
// The last capability register is expected to
// have the reply capability
ret = ipc_recv(msg->cap_regs[msg->valid_cap_regs - 1], msg);
return ret;
}
EXPORT_SYMBOL(ipc_call);
......@@ -13,7 +13,6 @@
struct cspace;
typedef u64 cptr_t;
struct sync_endpoint;
struct lcd {
/*
......@@ -22,8 +21,9 @@ struct lcd {
struct task_struct *parent;
u64 badge;
struct cspace *cspace;
struct list_head sending_eps;
struct list_head recving_eps;
struct list_head senders;
struct list_head receivers;
int making_call;
/*
* Accessible in lcd
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment