Libtrap: Internal development docs  1.16.1
trap_internal.h
Go to the documentation of this file.
1 /**
2  * \file trap_internal.h
3  * \brief Internal functions and macros for libtrap
4  * Verbose and debug macros from libcommlbr
5  * \author Tomas Konir <Tomas.Konir@liberouter.org>
6  * \author Milan Kovacik <xkovaci1@fi.muni.cz>
7  * \author Vojtech Krmicek <xkrmicek@fi.muni.cz>
8  * \author Juraj Blaho <xblaho00@stud.fit.vutbr.cz>
9  * \author Tomas Cejka <cejkat@cesnet.cz>
10  * \author Tomas Jansky <janskto1@fit.cvut.cz>
11  * \date 2006-2018
12  *
13  * Copyright (C) 2006-2018 CESNET
14  *
15  *
16  * LICENSE TERMS
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions
20  * are met:
21  * 1. Redistributions of source code must retain the above copyright
22  * notice, this list of conditions and the following disclaimer.
23  * 2. Redistributions in binary form must reproduce the above copyright
24  * notice, this list of conditions and the following disclaimer in
25  * the documentation and/or other materials provided with the
26  * distribution.
27  * 3. Neither the name of the Company nor the names of its contributors
28  * may be used to endorse or promote products derived from this
29  * software without specific prior written permission.
30  *
31  * ALTERNATIVELY, provided that this notice is retained in full, this
32  * product may be distributed under the terms of the GNU General Public
33  * License (GPL) version 2 or later, in which case the provisions
34  * of the GPL apply INSTEAD OF those given above.
35  *
36  * This software is provided ``as is'', and any express or implied
37  * warranties, including, but not limited to, the implied warranties of
38  * merchantability and fitness for a particular purpose are disclaimed.
39  * In no event shall the company or contributors be liable for any
40  * direct, indirect, incidental, special, exemplary, or consequential
41  * damages (including, but not limited to, procurement of substitute
42  * goods or services; loss of use, data, or profits; or business
43  * interruption) however caused and on any theory of liability, whether
44  * in contract, strict liability, or tort (including negligence or
45  * otherwise) arising in any way out of the use of this software, even
46  * if advised of the possibility of such damage.
47  *
48  */
49 #ifndef _TRAP_INTERNAL_H
50 #define _TRAP_INTERNAL_H
51 #include <config.h>
52 #include <stdio.h>
53 #include <pthread.h>
54 #include "../include/libtrap/trap.h"
55 #include "trap_ifc.h"
56 
57 #define MAX_ERROR_MSG_BUFF_SIZE 1024
58 
59 /**
60  * Max length of line printed in help (used for line-breaks).
61  */
62 #define DEFAULT_MAX_TERMINAL_WIDTH 85
63 
64 /* Values of commands that supervisor wants module to perform. These values are sent in header via service interface. */
65 #define SERVICE_GET_COM 10 ///< Signaling a request for module statistics (interfaces stats - received messages and buffers, sent messages and buffers, autoflushes counter)
66 #define SERVICE_SET_COM 11 ///< Signaling a request to set some interface parameters (timeouts etc.)
67 #define SERVICE_OK_REPLY 12 ///< A value used as a reply signaling success
68 
69 /**
70  * \defgroup negotiationretvals Negotiation return values
71  * @{*/
72 
73 /* Input interface negotiation return values */
74 #define NEG_RES_CONT 111 ///< If the data format and data specifier of input and output interface are the same (input interface can receive the data for module right after the negotiation)
75 #define NEG_RES_RECEIVER_FMT_SUBSET 112 ///< If the data format of input and output interfaces is the same and data specifier of the input interface is subset of the output interface data specifier
76 #define NEG_RES_SENDER_FMT_SUBSET 116 ///< If the data format of input and output interfaces is the same and new data specifier of the output interface is subset of the old one (it is not first negotiation)
77 #define NEG_RES_FMT_MISMATCH 113 ///< If the data format or data specifier of input and output interfaces does not match
78 #define NEG_RES_FMT_CHANGED 117 ///< If the data format has changed (for JSON type, UNIREC type uses *SUBSET variants)
79 
80 /* Output interface negotiation return values */
81 #define NEG_RES_OK 116 ///< Signaling success (hello message successfully sent to input interface)
82 
83 /* Return values of input and output interface negotiations */
84 #define NEG_RES_FAILED 114 ///< If receiving the data from output interface fails or sending the data to input interface fails
85 #define NEG_RES_FMT_UNKNOWN 115 ///< If the output interface has not specified data format
86 /**@}*/
87 
88 /** @defgroup debug Macros for verbose and debug listings
89  * @{
90  */
91 
92 /*! control debug level */
93 extern int trap_debug;
94 /*! control verbose level */
95 extern int trap_verbose;
96 /*! buffer for verbose and debug messages */
97 extern char trap_err_msg[];
98 
100 
102 
103 /**
104  * Hello message header structure (used during the output and input interface negotiation).
105  * Contains data format and data specifier size of the output interface which is making the negotiation.
106  */
107 typedef struct hello_msg_header_s {
108  uint8_t data_type;
111 
112 
113 /*!
114 \brief VERBOSE/MSG levels
115 */
116 typedef enum trap_verbose_level {
117  CL_ERROR = -3, /*!< Inforamtion about error*/
118  CL_WARNING = -2, /*< Warining message */
119  CL_VERBOSE_OFF = -1,/*!< Verbose off / print even if VERBOSE is off*/
120  CL_VERBOSE_BASIC,/*!< Basic verbose information*/
121  CL_VERBOSE_ADVANCED,/*!< Advanced verbose information*/
122  CL_VERBOSE_LIBRARY/*!< Used for library functions verbose*/
124 
125 /**
126  * \name Timeouts handling
127  * @{*/
128 #define TRAP_NO_IFC_SLEEP 4 ///< seconds to sleep, when autoflushing is not active
129 #define TRAP_IFC_TIMEOUT 2000000 ///< size of default timeout on output interfaces in microseconds
130 /**@}*/
131 
132 #ifndef NDEBUG
133  /*! \brief Debug message macro if DEBUG macro is defined
134  *
135  * now 3 known DEBUG LEVELS
136  * - 0 normal debug messages
137  * - 1 extended debug (messages on enter and before exit important functions)
138  * - 2 flood developer with debug messages :-) (don't use)
139  *
140  * BE VERBOSE AND DEBUG ARE DIFFERENT OPTIONS !!!
141  */
142 # define MSG(level,format,args...) if (trap_debug >= level) {snprintf(trap_err_msg, 4095, format, ##args); debug_msg(level,trap_err_msg);}
143 
144  /*! \brief Debug message macro if DEBUG macro is defined - without new
145  * line */
146 # define MSG_NONL(level,format,args...) if (trap_debug >= level) {snprintf(trap_err_msg, 4095, format, ##args); debug_msg_nonl(trap_err_msg);}
147  /*! Prints line in source file if DEBUG macro is defined */
148 # define LINE() {fprintf(stderr, "file: %s, line: %i\n", __FILE__, __LINE__); fflush(stderr);}
149 
150 #define INLINE
151 #else
152 
153 # ifdef __GNUC__
154 static inline int __attribute__ ((format (printf, 2, 3))) MSG(int l, const char *fmt, ...)
155 {
156  (void)(l + fmt);
157  return 0;
158 }
159 # else
160 # define MSG(level,string,args...)
161 # endif
162 
163 # define LINE()
164 #define INLINE inline
165 #endif
166 
167 void trap_verbose_msg(int level, char *string);
168 
169 #ifndef NDEBUG
170 /*! Macro for verbose message */
171 #define VERBOSE(level,format,args...) if (trap_verbose>=level) { \
172  snprintf(trap_err_msg,4095,"%s:%d "format,__FILE__, __LINE__, ##args); \
173  trap_verbose_msg(level,trap_err_msg); \
174 }
175 #else
176 #define VERBOSE(level,format,args...) if (trap_verbose>=level) { \
177  snprintf(trap_err_msg,4095,format, ##args); \
178  trap_verbose_msg(level,trap_err_msg); \
179 }
180 #endif
181 
182 
183 #define DEBUG_IFC(X) if (TRAP_DEBUG_IFC) { \
184  X; \
185 }
186 
187 #define DEBUG_BUF(X) if (TRAP_DEBUG_BUFFERING) { \
188  X; \
189 }
190 
191 
192 /** @} */
193 
194 /**
195  * List of threads and their semaphores.
196  *
197  * It is used for multi-result reading when _get_data() is called
198  * with ifc_mask including more than one ifc.
199  */
201  pthread_t thr; /**< thread of reader */
202  sem_t sem; /**< semaphore used when thread is ought to sleep */
203 };
204 
205 /**
206  * \brief List of autoflush timeouts of output interfaces.
207  */
208 typedef struct autoflush_timeouts {
209  int idx; /**< Index of output interface. */
210  int64_t tm; /**< Autoflush timeout to be elapsed. */
211  int64_t tm_backup; /**< Backup value of the autoflush timeout. */
213 
214 /**
215  * Libtrap context structure.
216  *
217  * It contains the whole context of one instance of libtrap. The context
218  * contains arrays of communication interfaces (IFC), buffers, locks/mutexes.
219  */
221  /**
222  * Is libtrap initialized correctly? (0 ~ false)
223  */
225  /**
226  * Is libtrap terminated? (0 ~ false, should run)
227  */
228  volatile int terminated;
229 
230  /**
231  * Number of interface changes waiting to be applied.
232  */
233  volatile int ifc_change;
234 
235  /**
236  * Code of last error (one of the codes above)
237  */
239 
240  /**
241  * Human-readable message about last error
242  */
243  const char *trap_last_error_msg;
244 
245  /**
246  * Buffer for dynamically generated messages
247  */
249 
250  /**
251  * Array of input interfaces
252  */
254 
255  /**
256  * Arrays of output interfaces
257  */
259 
260  /**
261  * Number of input interfaces
262  */
263  uint32_t num_ifc_in;
264 
265  /**
266  * Number of output interfaces
267  */
268  uint32_t num_ifc_out;
269 
270  /**
271  * Timeout common to all readers for multiread feature
272  */
274 
275  /**
276  * Lock setting last error code and last error message.
277  */
278  pthread_mutex_t error_mtx;
279 
280  /**
281  * Timeouts for autoflush thread.
282  */
284 
285  /**
286  * Service thread that enables communication with module
287  */
288  pthread_t service_thread;
289 
290  /**
291  * Name of the service IFC socket, it is disabled when NULL.
292  */
294 
295  /**
296  * Indicator of initialized service thread
297  */
299 
300  /**
301  * \defgroup ctxifccounters IFC counters
302  *
303  * The counters are sent by service_thread_routine() via service IFC (e.g. to supervisor).
304  * @{
305  */
306  /**
307  * counter_send_message is incremented within trap_ctx_send().
308  */
310  /**
311  * counter_dropped_message is incremented within trap_ctx_send().
312  */
314  /**
315  * counter_recv_message is incremented within trap_ctx_recv().
316  */
318  /**
319  * counter_send_buffer is incremented within trap_store_into_buffer() after sending buffer.
320  */
322  /**
323  * counter_autoflush is incremented within trap_automatic_flush_thr() after flushing buffer.
324  */
325  uint64_t *counter_autoflush;
326  /**
327  * counter_recv_buffer is incremented within trap_read_from_buffer() after successful receiving buffer.
328  */
330  /**
331  * counter_recv_delay_last represents time interval between last two recv() calls (in microseconds).
332  */
334  /**
335  * counter_recv_delay_total represents total time spent outside of recv() function (in microseconds).
336  */
338  /**
339  * recv_delay_timestamp is used to determine the time that has elapsed between last two recv() calls
340  */
342  /**
343  * @}
344  */
345 };
346 
347 /**
348  * Number of counter types sf IN IFC stored #trap_ctx_priv_s used in service_thread_routine()
349  */
350 #define TRAP_IN_IFC_COUNTERS 1
351 /**
352  * Number of counter types sf OUT IFC stored #trap_ctx_priv_s used in service_thread_routine()
353  */
354 #define TRAP_OUT_IFC_COUNTERS 3
355 
359  uint32_t data_length; /**< size of data in the data unit */
360 #ifdef ENABLE_HEADER_TIMESTAMP
361  uint64_t timestamp;
362 #endif
363  uint8_t data[0];
364 } __attribute__ ((__packed__));
366 
367 #ifndef ATOMICOPS
368 _Bool __sync_bool_compare_and_swap_8(int64_t *ptr, int64_t oldvar, int64_t newval);
369 
370 uint64_t __sync_fetch_and_add_8(uint64_t *ptr, uint64_t value);
371 
372 uint64_t __sync_add_and_fetch_8(uint64_t *ptr, uint64_t value);
373 
374 uint64_t __sync_or_and_fetch_8(uint64_t *ptr, uint64_t value);
375 
376 uint64_t __sync_and_and_fetch_8(uint64_t *ptr, uint64_t value);
377 
378 #endif
379 
380 #endif
381 
#define MAX_ERROR_MSG_BUFF_SIZE
Definition: trap_internal.h:57
uint64_t __sync_and_and_fetch_8(uint64_t *ptr, uint64_t value)
uint64_t __sync_fetch_and_add_8(uint64_t *ptr, uint64_t value)
char error_msg_buffer[MAX_ERROR_MSG_BUFF_SIZE]
struct autoflush_timeouts ifc_autoflush_t
List of autoflush timeouts of output interfaces.
ifc_autoflush_t * ifc_autoflush_timeout
volatile int ifc_change
uint32_t num_ifc_in
int trap_debug
Definition: trap_internal.c:56
volatile int terminated
uint64_t * counter_dropped_message
trap_ctx_priv_t * trap_create_ctx_t()
Definition: trap.c:1251
uint32_t num_ifc_out
char trap_err_msg[]
Definition: trap_internal.c:58
pthread_t service_thread
int service_thread_initialized
uint64_t * counter_recv_message
_Bool __sync_bool_compare_and_swap_8(int64_t *ptr, int64_t oldvar, int64_t newval)
pthread_mutex_t error_mtx
trap_ctx_priv_t * trap_glob_ctx
Definition: trap.c:120
const char * trap_last_error_msg
uint64_t * recv_delay_timestamp
char * service_ifc_name
uint64_t * counter_recv_delay_total
struct trap_buffer_header_s __attribute__((__packed__))
int trap_verbose
Definition: trap_internal.c:57
trap_verbose_level
VERBOSE/MSG levels.
struct hello_msg_header_s hello_msg_header_t
uint64_t * counter_recv_buffer
uint64_t * counter_recv_delay_last
List of autoflush timeouts of output interfaces.
uint64_t * counter_autoflush
uint64_t __sync_or_and_fetch_8(uint64_t *ptr, uint64_t value)
uint32_t data_fmt_spec_size
uint64_t * counter_send_buffer
enum trap_verbose_level trap_verbose_level_t
VERBOSE/MSG levels.
trap_output_ifc_t * out_ifc_list
Interface of TRAP interfaces.
uint64_t * counter_send_message
#define MSG(level, format, args...)
Debug message macro if DEBUG macro is defined.
void trap_verbose_msg(int level, char *string)
send verbose message to stderr
uint64_t __sync_add_and_fetch_8(uint64_t *ptr, uint64_t value)
trap_input_ifc_t * in_ifc_list