codes-callback.h 2.36 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
 * Copyright (C) 2015 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
*/

#ifndef CODES_CALLBACK_H
#define CODES_CALLBACK_H

#include <assert.h>
#include "codes/lp-msg.h"

/* This header defines the following conventions for callback-based event
 * processing (i.e., RPC-like event flow where the callee sends a "return
 * event" to the caller)
 *
 * callers:
 * - give the caller event size (for sanity checking)
 * - use the msg_header convention (lp-msg.h)
 * - specify an integer tag to identify which call the callee return event
 *   corresponds to, in the case of multiple pending callbacks
 * - specify an offset to the return structure, which is defined by the callees
 *
 * callees:
 * - use the resulting set of offsets to write and issue the callback
 *
 * The recommended calling convention for these types of event flows is:
28
29
 * void event_func(<params...>,
 *         msg_header const * h, int tag, struct codes_cb_info const * cb);
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 */

struct codes_cb_info {
    int event_size;
    int header_offset;
    int tag_offset;
    int cb_ret_offset;
};

/* helper struct for callees - wrap up the typical inputs */
struct codes_cb_params {
    struct codes_cb_info info;
    msg_header h;
    int tag;
};

/* function-like sugar for initializing a codes_cb_info */
#define INIT_CODES_CB_INFO(_cb_info_ptr, _event_type, _header_field, _tag_field, _cb_ret_field) \
    do { \
        (_cb_info_ptr)->event_size    = sizeof(_event_type); \
        (_cb_info_ptr)->header_offset = offsetof(_event_type, _header_field); \
        (_cb_info_ptr)->tag_offset    = offsetof(_event_type, _tag_field); \
        (_cb_info_ptr)->cb_ret_offset = offsetof(_event_type, _cb_ret_field); \
    } while (0)

#define SANITY_CHECK_CB(_cb_info_ptr, _ret_type) \
    do { \
        int _total_size = sizeof(_ret_type) + sizeof(int) + sizeof(msg_header);\
        int _esize = (_cb_info_ptr)->event_size; \
        assert(_esize >= _total_size); \
        assert(_esize >= (_cb_info_ptr)->header_offset + sizeof(msg_header)); \
        assert(_esize >= (_cb_info_ptr)->tag_offset + sizeof(int)); \
        assert(_esize >= (_cb_info_ptr)->cb_ret_offset + sizeof(_ret_type)); \
    } while (0)

#endif /* end of include guard: CODES_CALLBACK_H */

/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 *  indent-tabs-mode: nil
 * End:
 *
 * vim: ft=c ts=8 sts=4 sw=4 expandtab
 */