1 /*
2    Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #ifndef SB_COUNTER_H
20 #define SB_COUNTER_H
21 
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25 
26 #ifdef STDC_HEADERS
27 # include <inttypes.h>
28 #endif
29 
30 #include "sb_util.h"
31 #include "sb_ck_pr.h"
32 
33 /* Statistic counter types */
34 
35 typedef enum {
36   SB_CNT_OTHER,        /* unknown type of queries */
37   SB_CNT_READ,         /* reads */
38   SB_CNT_WRITE,        /* writes */
39   SB_CNT_EVENT,        /* events */
40   SB_CNT_ERROR,        /* errors */
41   SB_CNT_RECONNECT,    /* reconnects */
42   SB_CNT_MAX
43 } sb_counter_type_t;
44 
45 /*
46   sizeof(sb_counter_t) must be a multiple of CK_MD_CACHELINE to avoid cache
47   line sharing.
48 */
49 typedef uint64_t
50 sb_counters_t[SB_ALIGN(SB_CNT_MAX * sizeof(uint64_t), CK_MD_CACHELINE) /
51               sizeof(uint64_t)];
52 
53 extern sb_counters_t *sb_counters;
54 
55 int sb_counters_init(void);
56 
57 void sb_counters_done(void);
58 
59 /*
60   Cannot use C99 inline here, because CK atomic primitives use static inlines
61   which in turn leads to compiler warnings. So for performance reasons the
62   following functions are defined 'static inline' too everywhere except sb_lua.c
63   where they are declared and defined as external linkage functions to be
64   available from LuaJIT FFI.
65 */
66 #ifndef SB_LUA_EXPORT
67 # define SB_LUA_INLINE static inline
68 #else
69 # define SB_LUA_INLINE
70 uint64_t sb_counter_val(int thread_id, sb_counter_type_t type);
71 void sb_counter_inc(int thread_id, sb_counter_type_t type);
72 #endif
73 
74 /* Return the current value for a given counter */
75 SB_LUA_INLINE
sb_counter_val(int thread_id,sb_counter_type_t type)76 uint64_t sb_counter_val(int thread_id, sb_counter_type_t type)
77 {
78   return ck_pr_load_64(&sb_counters[thread_id][type]);
79 }
80 
81 /* Increment a given stat counter for a given thread  */
82 SB_LUA_INLINE
sb_counter_inc(int thread_id,sb_counter_type_t type)83 void sb_counter_inc(int thread_id, sb_counter_type_t type)
84 {
85   ck_pr_store_64(&sb_counters[thread_id][type],
86                  sb_counter_val(thread_id, type)+1);
87 }
88 
89 #undef SB_LUA_INLINE
90 
91 /*
92   Return aggregate counter values since the last intermediate report. This is
93   not thread-safe as it updates the global last report state, so it must be
94   called from a single thread.
95 */
96 void sb_counters_agg_intermediate(sb_counters_t val);
97 
98 /*
99   Return aggregate counter values since the last cumulative report. This is
100   not thread-safe as it updates the global last report state, so it must be
101   called from a single thread.
102 */
103 void sb_counters_agg_cumulative(sb_counters_t val);
104 
105 #endif
106