1/** 2 * \file 3 * \brief Bidirectional UMP channel 4 */ 5 6/* 7 * Copyright (c) 2009, 2010, 2011, 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#ifndef BARRELFISH_UMP_CHAN_H 16#define BARRELFISH_UMP_CHAN_H 17 18#include <sys/cdefs.h> 19 20#include <barrelfish/ump_endpoint.h> 21#include <barrelfish/monitor_client.h> 22 23__BEGIN_DECLS 24 25struct ump_chan; 26struct monitor_binding; 27 28struct ump_bind_continuation { 29 /** 30 * \brief Handler which runs when a binding succeeds or fails 31 * \param st State pointer set in closure 32 * \param err Success/failure of binding 33 * \param uc On success, contains pointer to channel 34 * \param notify On success, contains (optional) notification capability 35 */ 36 void (*handler)(void *st, errval_t err, struct ump_chan *uc, 37 struct capref notify); 38 void *st; 39}; 40 41/// A bidirectional UMP channel 42struct ump_chan { 43 struct monitor_cap_handlers cap_handlers; /* XXX: must be first */ 44 45 struct ump_chan_state send_chan; ///< Outgoing UMP channel state 46 struct ump_endpoint endpoint; ///< Incoming UMP endpoint 47 struct waitset_chanstate send_waitset; 48 struct ump_chan *next, *prev; 49 50 /// connection state 51 enum {UMP_DISCONNECTED, ///< Disconnected 52 UMP_BIND_WAIT, ///< Waiting for bind reply 53 UMP_CONNECTED, ///< Connection established 54 } connstate; 55 56 struct capref frame; ///< Cap to shared frame 57 struct vregion *vregion; ///< VRegion for shared frame 58 ump_index_t max_send_msgs; ///< Number of messages that fit in the send channel 59 ump_index_t max_recv_msgs; ///< Number of messages that fit in the recv channel 60 uintptr_t monitor_id; ///< Local monitor's connection ID for this channel 61 struct monitor_binding *monitor_binding; ///< Monitor binding used for cap xfer 62 63 uintptr_t sendid; ///< id for tracing 64 uintptr_t recvid; ///< id for tracing 65 66 /* Arguments for an ongoing bind attempt */ 67 iref_t iref; ///< IREF to which we bound 68 size_t inchanlen, outchanlen; 69 struct capref notify_cap; 70 struct ump_bind_continuation bind_continuation; ///< Continuation for bind 71}; 72 73struct event_queue_node; 74 75errval_t ump_chan_init(struct ump_chan *uc, 76 volatile void *inbuf, size_t inbufsize, 77 volatile void *outbuf, size_t outbufsize); 78errval_t ump_chan_bind(struct ump_chan *uc, struct ump_bind_continuation cont, 79 struct event_queue_node *qnode, iref_t iref, 80 struct monitor_binding *monitor_binding, 81 size_t inchanlen, size_t outchanlen, 82 struct capref notify_cap); 83errval_t ump_chan_accept(struct ump_chan *uc, uintptr_t mon_id, 84 struct capref frame, size_t inchanlen, size_t outchanlen); 85errval_t ump_chan_register_send(struct ump_chan *uc, struct waitset *ws, 86 struct event_closure closure); 87void ump_channels_retry_send_disabled(dispatcher_handle_t handle); 88void ump_chan_send_bind_reply(struct monitor_binding *mb, 89 struct ump_chan *uc, errval_t err, 90 uintptr_t monitor_id, struct capref notify_cap); 91void ump_chan_destroy(struct ump_chan *uc); 92void ump_init(void); 93 94/** 95 * \brief Register an event handler to be notified when messages can be received 96 * 97 * In the future, call the closure on the given waitset when it is likely that 98 * a message can be received on the channel. A channel may only be registered 99 * with a single receive event handler on a single waitset at any one time. 100 * 101 * \param uc UMP channel 102 * \param ws Waitset 103 * \param closure Event handler 104 */ 105static inline errval_t ump_chan_register_recv(struct ump_chan *uc, 106 struct waitset *ws, 107 struct event_closure closure) 108{ 109 return ump_endpoint_register(&uc->endpoint, ws, closure); 110} 111 112/** 113 * \brief Cancel an event registration made with ump_chan_register_recv() 114 * 115 * \param uc UMP channel 116 */ 117static inline errval_t ump_chan_deregister_recv(struct ump_chan *uc) 118{ 119 return ump_endpoint_deregister(&uc->endpoint); 120} 121 122static inline errval_t ump_chan_recv(struct ump_chan *uc, 123 volatile struct ump_message **msg) 124{ 125 assert(msg != NULL); 126 assert(uc != NULL); 127 return ump_endpoint_recv(&uc->endpoint, msg); 128} 129 130static inline errval_t ump_chan_can_recv(struct ump_chan *uc) 131{ 132 assert(uc != NULL); 133 return ump_endpoint_can_recv(&uc->endpoint); 134} 135 136static inline volatile struct ump_message *ump_chan_get_next( 137 struct ump_chan *uc, struct ump_control *ctrl) 138{ 139 return ump_impl_get_next(&uc->send_chan, ctrl); 140} 141 142static inline bool ump_chan_can_send(struct ump_chan *uc) 143{ 144 assert(uc != NULL); 145 return ump_impl_can_send(&uc->send_chan); 146} 147 148static inline void ump_chan_free_message(volatile struct ump_message *msg) 149{ 150 ump_impl_free_message(msg); 151} 152 153/** 154 * \brief Migrate an event registration made with 155 * ump_chan_register_recv() to a new waitset 156 * 157 * \param lc LMP channel 158 * \param ws New waitset 159 */ 160static inline void ump_chan_migrate_recv(struct ump_chan *lc, 161 struct waitset *ws) 162{ 163 ump_endpoint_migrate(&lc->endpoint, ws); 164} 165 166static inline struct waitset_chanstate * ump_chan_get_receiving_channel(struct ump_chan *chan) 167{ 168 return &chan->endpoint.waitset_state; 169} 170 171struct waitset_chanstate * monitor_bind_get_receiving_chanstate(struct monitor_binding *b); 172 173__END_DECLS 174 175#endif // BARRELFISH_UMP_CHAN_H 176