1/*
2 * Copyright (c) 2014, ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#ifndef __FLOUNDER_TXQUEUE_H
11#define __FLOUNDER_TXQUEUE_H
12
13#include <barrelfish/waitset.h>
14
15//#define FLOUNDER_TXQUEUE_DEBUG 1
16
17#ifdef FLOUNDER_TXQUEUE_DEBUG
18#define TXQ_DEBUG(x...) debug_printf("[TXQ]" x);
19#define TXQ_ASSERT(x) assert(x)
20#define TXQ_OP(x) x
21#else
22#define TXQ_DEBUG(x...)
23#define TXQ_ASSERT(x)
24#define TXQ_OP(x)
25#endif
26
27struct tx_queue;
28struct txq_msg_st;
29
30/// Utility macro to construct a continuation structure (handler & arg)
31#define TXQCONT(a) MKCLOSURE(txq_sent_cb,a)
32
33/// typedef for the send handler function. argument is struct txq_msg_st*
34typedef errval_t (*txq_send_fn_t)(struct txq_msg_st *st);
35
36/// typedef for cleanup function. argument is struct txq_msg_st*
37typedef void (*txq_cleanup_fn_t)(struct txq_msg_st *st);
38
39typedef errval_t (*txq_register_fn_t)(void *binding,
40                                      struct waitset *ws,
41                                      struct event_closure _continuation);
42
43struct tx_queue
44{
45    void *binding;                   ///< binding
46    txq_register_fn_t register_send; ///< function to register sending
47    struct waitset *waitset;         ///< waitset to use
48    struct txq_msg_st *head;         ///< head of the queue
49    struct txq_msg_st *tail;         ///< tail of the queue
50    struct txq_msg_st *free;         ///< free list of message states
51    uint32_t msg_st_size;            ///< size of the message state
52#ifdef FLOUNDER_TXQUEUE_DEBUG
53    uint32_t free_count;
54    uint32_t alloc_count;
55    uint32_t queue_count;
56#endif
57};
58
59struct txq_msg_st
60{
61    struct txq_msg_st *next;         ///< pointer to the next message in the queue
62    struct tx_queue *queue;          ///< queue this element belongs to
63    txq_send_fn_t send;              ///< send handler function
64    txq_cleanup_fn_t cleanup;        ///< cleanup function to be called
65    errval_t err;                    ///< error error status
66    /* user state follows */
67};
68
69
70/**
71 * \brief initializes a tx_queue to be used for a Flounder binding
72 *
73 * \param queue         TX queue to be initialized
74 * \param binding       Flounder binding
75 * \param waitset       the waitset to be used
76 * \param register_send register send function of the binding
77 * \param can_send      can send function of the binding
78 * \param msg_st_size   size of the message state elements of this queue
79 */
80void txq_init(struct tx_queue *queue,
81              void *binding,
82              struct waitset *waitset,
83              txq_register_fn_t register_send,
84              uint32_t msg_st_size);
85
86/**
87 * \brief allocates new message state for an outgoing flounder message
88 *
89 * \param txq   TX queue to allocate from
90 *
91 * \returns mx_mst_st on success
92 *          NULL on failure
93 */
94struct txq_msg_st *txq_msg_st_alloc(struct tx_queue *txq);
95
96/**
97 * \brief frees up an unused message state
98 *
99 * \param st    txq message state to be freed
100 */
101void txq_msg_st_free(struct txq_msg_st *st);
102
103/**
104 * \brief handler to be called when the message was sent successfully
105 *
106 * \param arg    TX queue message state
107 */
108void txq_sent_cb(void *arg);
109
110/**
111 * \brief sends the Flounder message
112 *
113 * \param st    txq message state of the message
114 */
115void txq_send(struct txq_msg_st *st);
116
117#endif // __FLOUNDER_TXQUEUE_H
118