Complete unification of thread_loop/peerd_loop
[archipelago] / xseg / peers / user / peer.h
1 /*
2  * Copyright 2012 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *   2. Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials
14  *      provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * The views and conclusions contained in the software and
30  * documentation are those of the authors and should not be
31  * interpreted as representing official policies, either expressed
32  * or implied, of GRNET S.A.
33  */
34
35 #include <stddef.h>
36 #include <xseg/xseg.h>
37
38 #ifdef ST_THREADS
39 #include <st.h>
40 #endif
41
42
43 #define BEGIN_READ_ARGS(__ac, __av)                                     \
44         int __argc = __ac;                                              \
45         char **__argv = __av;                                           \
46         int __i;                                                        \
47         for (__i = 0; __i < __argc; __i++) {
48
49 #define END_READ_ARGS()                                                 \
50         }
51
52 #define READ_ARG_ULONG(__name, __var)                                   \
53         if (!strcmp(__argv[__i], __name) && __i + 1 < __argc){  \
54                 __var = strtoul(__argv[__i+1], NULL, 10);               \
55                 __i += 1;                                               \
56                 continue;                                               \
57         }
58
59 #define READ_ARG_STRING(__name, __var, __max_len)                       \
60         if (!strcmp(__argv[__i], __name) && __i + 1 < __argc){  \
61                 strncpy(__var, __argv[__i+1], __max_len);               \
62                 __var[__max_len] = 0;                           \
63                 __i += 1;                                               \
64                 continue;                                               \
65         }
66
67 #define READ_ARG_BOOL(__name, __var)                                    \
68         if (!strcmp(__argv[__i], __name)){                              \
69                 __var = 1;                                              \
70                 continue;                                               \
71         }
72
73
74
75
76 /* main peer structs */
77 struct peer_req {
78         struct peerd *peer;
79         struct xseg_request *req;
80         ssize_t retval;
81         xport portno;
82         void *priv;
83 #ifdef ST_THREADS
84         st_cond_t cond;
85 #endif
86 };
87
88 struct peerd {
89         struct xseg *xseg;
90         xport portno_start;
91         xport portno_end;
92         long nr_ops;
93         xport defer_portno;
94         struct peer_req *peer_reqs;
95         struct xq free_reqs;
96         int (*peerd_loop)(void *arg);
97         void *priv;
98 #ifdef MT
99         uint32_t nr_threads;
100         struct thread *thread;
101         struct xq threads;
102         void (*interactive_func)(void);
103 #endif
104 };
105
106 enum dispatch_reason {
107         dispatch_accept = 0,
108         dispatch_receive = 1,
109         dispatch_internal = 2
110 };
111
112 void fail(struct peerd *peer, struct peer_req *pr);
113 void complete(struct peerd *peer, struct peer_req *pr);
114 int defer_request(struct peerd *peer, struct peer_req *pr);
115 void pending(struct peerd *peer, struct peer_req *req);
116 void log_pr(char *msg, struct peer_req *pr);
117 int canDefer(struct peerd *peer);
118 int submit_peer_req(struct peerd *peer, struct peer_req *pr);
119 struct peer_req *alloc_peer_req(struct peerd *peer);
120 void free_peer_req(struct peerd *peer, struct peer_req *pr);
121 void get_submits_stats();
122 void get_responds_stats();
123 void usage();
124 void print_req(struct xseg *xseg, struct xseg_request *req);
125 int isTerminate();
126 int check_ports(struct peerd *peer);
127
128 #ifdef MT
129 int thread_execute(struct peerd *peer, void (*func)(void *arg), void *arg);
130 #endif
131
132 static inline struct peerd * __get_peerd(void * custom_peerd)
133 {
134         return (struct peerd *) ((unsigned long) custom_peerd  - offsetof(struct peerd, priv));
135 }
136
137
138
139 /* decration of "common" variables */
140 extern volatile unsigned int terminated;
141 extern struct log_ctx lc;
142 #ifdef ST_THREADS
143 extern uint32_t ta;
144 #endif
145
146 inline int isTerminate(void)
147 {
148         return terminated;
149 }
150
151 /********************************
152  *   mandatory peer functions   *
153  ********************************/
154
155 /* peer main function */
156 int custom_peer_init(struct peerd *peer, int argc, char *argv[]);
157 void custom_peer_finalize(struct peerd *peer);
158
159 /* dispatch function */
160 int dispatch(struct peerd *peer, struct peer_req *pr, struct xseg_request *req,
161                 enum dispatch_reason reason);
162
163 void custom_peer_usage();