mt-waitset: adding masking of channels so a thread won't handle two messages at the...
[barrelfish] / lib / barrelfish / ump_endpoint.c
1 /**
2  * \file
3  * \brief Incoming UMP endpoints
4  */
5
6 /*
7  * Copyright (c) 2009, 2011, 2012, ETH Zurich.
8  * All rights reserved.
9  *
10  * This file is distributed under the terms in the attached LICENSE file.
11  * If you do not find this file, copies can be found by writing to:
12  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13  */
14
15 #include <barrelfish/barrelfish.h>
16 #include <barrelfish/ump_endpoint.h>
17 #include <barrelfish/ump_impl.h>
18 #include <barrelfish/waitset.h>
19 #include <barrelfish/waitset_chan.h>
20 #include "waitset_chan_priv.h"
21
22 /**
23  * \brief Initialise a new UMP endpoint
24  *
25  * \param ep Storage for endpoint state
26  * \param buf Pointer to incoming message buffer
27  * \param bufsize Size of buf in bytes (must be multiple of UMP message size)
28  */
29 errval_t ump_endpoint_init(struct ump_endpoint *ep, volatile void *buf,
30                            size_t bufsize)
31 {
32     errval_t err = ump_chan_state_init(&ep->chan, buf, bufsize, UMP_INCOMING);
33     if (err_is_fail(err)) {
34         return err;
35     }
36
37     waitset_chanstate_init(&ep->waitset_state, CHANTYPE_UMP_IN);
38     return SYS_ERR_OK;
39 }
40
41 /**
42  * \brief Destroy the local state associated with a given UMP endpoint
43  */
44 void ump_endpoint_destroy(struct ump_endpoint *ep)
45 {
46     waitset_chanstate_destroy(&ep->waitset_state);
47 }
48
49 /**
50  * \brief Register an event handler to be notified when messages can be received
51  *
52  * In the future, call the closure on the given waitset when it is likely that
53  * a message can be received on the endpoint. An endpoint may only be registered
54  * with a single event handler on a single waitset at any one time.
55  *
56  * \param ep UMP endpoint
57  * \param ws Waitset
58  * \param closure Event handler
59  */
60 errval_t ump_endpoint_register(struct ump_endpoint *ep, struct waitset *ws,
61                                 struct event_closure closure)
62 {
63     bool wd;
64     dispatcher_handle_t handle = disp_try_disable(&wd);
65     errval_t err;
66
67     assert(ep != NULL);
68     assert(ws != NULL);
69
70     if (ump_endpoint_poll(&ep->waitset_state)) { // trigger event immediately
71         err = waitset_chan_trigger_closure_disabled(ws, &ep->waitset_state, closure, handle);
72     } else {
73         err = waitset_chan_register_polled_disabled(ws, &ep->waitset_state, closure, handle);
74     }
75     if (wd)
76         disp_enable(handle);
77     return err;
78 }
79
80 /**
81  * \brief Cancel an event registration made with ump_endpoint_register()
82  *
83  * \param ep UMP Endpoint
84  */
85 errval_t ump_endpoint_deregister(struct ump_endpoint *ep)
86 {
87     assert(ep);
88     return waitset_chan_deregister(&ep->waitset_state);
89 }
90
91 #include <stdio.h>
92 /**
93  * \brief Migrate an event registration made with ump_endpoint_register() to a new waitset.
94  *
95  * \param ep LMP Endpoint
96  * \param ws New waitset
97  */
98 void ump_endpoint_migrate(struct ump_endpoint *ep, struct waitset *ws)
99 {
100     printf("ump_endpoint_migrate\n");
101     waitset_chan_migrate(&ep->waitset_state, ws);
102 }