The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
atomic_queue_test.c
Go to the documentation of this file.
1 /*
2  * atomic_queue_test.c Tests for atomic queues
3  *
4  * Version: $Id: 3884f1b2cdc916dc85c485aed9a5aa3c4dab76f8 $
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * @copyright 2016 Alan DeKok (aland@freeradius.org)
21  */
22 
23 RCSID("$Id: 3884f1b2cdc916dc85c485aed9a5aa3c4dab76f8 $")
24 
25 #include <freeradius-devel/io/atomic_queue.h>
26 #include <freeradius-devel/util/debug.h>
27 #include <freeradius-devel/util/talloc.h>
28 #include <stdint.h>
29 #include <string.h>
30 #include <sys/time.h>
31 
32 #ifdef HAVE_GETOPT_H
33 # include <getopt.h>
34 #endif
35 
36 #define OFFSET (1024)
37 
38 static int debug_lvl = 0;
39 
40 
41 /**********************************************************************/
42 typedef struct request_s request_t;
43 void request_verify(UNUSED char const *file, UNUSED int line, UNUSED request_t *request);
44 
45 void request_verify(UNUSED char const *file, UNUSED int line, UNUSED request_t *request)
46 {
47 }
48 /**********************************************************************/
49 
50 
51 static NEVER_RETURNS void usage(void)
52 {
53  fprintf(stderr, "usage: atomic_queue_test [OPTS]\n");
54  fprintf(stderr, " -s size set queue size.\n");
55  fprintf(stderr, " -x Debugging mode.\n");
56 
57  fr_exit_now(EXIT_SUCCESS);
58 }
59 
60 int main(int argc, char *argv[])
61 {
62  int c, i, ret = 0;
63  int size;
64  intptr_t val;
65  void *data;
67  TALLOC_CTX *autofree = talloc_autofree_context();
68 
69  size = 4;
70 
71  while ((c = getopt(argc, argv, "hs:tx")) != -1) switch (c) {
72  case 's':
73  size = atoi(optarg);
74  break;
75 
76  case 'x':
77  debug_lvl++;
78  break;
79 
80  case 'h':
81  default:
82  usage();
83  }
84 #if 0
85  argc -= (optind - 1);
86  argv += (optind - 1);
87 #endif
88 
90 
91 #ifndef NDEBUG
92  if (debug_lvl) {
93  printf("Start\n");
94  fr_atomic_queue_debug(aq, stdout);
95 
96  if (debug_lvl > 1) printf("Filling with %d\n", size);
97  }
98 
99 #endif
100 
101 
102  for (i = 0; i < size; i++) {
103  val = i + OFFSET;
104  data = (void *) val;
105 
106  if (!fr_atomic_queue_push(aq, data)) {
107  fprintf(stderr, "Failed pushing at %d\n", i);
108  fr_exit_now(EXIT_FAILURE);
109  }
110 
111 #ifndef NDEBUG
112  if (debug_lvl > 1) {
113  printf("iteration %d\n", i);
114  fr_atomic_queue_debug(aq, stdout);
115  }
116 #endif
117  }
118 
119  val = size + OFFSET;
120  data = (void *) val;
121 
122  /*
123  * Queue is full. No more pushes are allowed.
124  */
125  if (fr_atomic_queue_push(aq, data)) {
126  fprintf(stderr, "Pushed an entry past the end of the queue.");
127  fr_exit_now(EXIT_FAILURE);
128  }
129 
130 #ifndef NDEBUG
131  if (debug_lvl) {
132  printf("Full\n");
133  fr_atomic_queue_debug(aq, stdout);
134 
135  if (debug_lvl > 1) printf("Emptying\n");
136  }
137 #endif
138 
139  /*
140  * And now pop them all.
141  */
142  for (i = 0; i < size; i++) {
143  if (!fr_atomic_queue_pop(aq, &data)) {
144  fprintf(stderr, "Failed popping at %d\n", i);
145  fr_exit_now(EXIT_FAILURE);
146  }
147 
148  val = (intptr_t) data;
149  if (val != (i + OFFSET)) {
150  fprintf(stderr, "Pop expected %d, got %d\n",
151  i + OFFSET, (int) val);
152  fr_exit_now(EXIT_FAILURE);
153  }
154 
155 #ifndef NDEBUG
156  if (debug_lvl > 1) {
157  printf("iteration %d\n", i);
158  fr_atomic_queue_debug(aq, stdout);
159  }
160 #endif
161  }
162 
163  /*
164  * Queue is empty. No more pops are allowed.
165  */
166  if (fr_atomic_queue_pop(aq, &data)) {
167  fprintf(stderr, "Popped an entry past the end of the queue.");
168  fr_exit_now(EXIT_FAILURE);
169  }
170 
171 #ifndef NDEBUG
172  if (debug_lvl) {
173  printf("Empty\n");
174  fr_atomic_queue_debug(aq, stdout);
175  }
176 #endif
177 
178  return ret;
179 }
180 
int const char * file
Definition: acutest.h:702
int const char int line
Definition: acutest.h:702
bool fr_atomic_queue_pop(fr_atomic_queue_t *aq, void **p_data)
Pop a pointer from the atomic queue.
Definition: atomic_queue.c:215
fr_atomic_queue_t * fr_atomic_queue_alloc(TALLOC_CTX *ctx, size_t size)
Create fixed-size atomic queue.
Definition: atomic_queue.c:80
bool fr_atomic_queue_push(fr_atomic_queue_t *aq, void *data)
Push a pointer into the atomic queue.
Definition: atomic_queue.c:148
void fr_atomic_queue_debug(fr_atomic_queue_t *aq, FILE *fp)
Dump an atomic queue.
Definition: atomic_queue.c:301
Structure to hold the atomic queue.
Definition: atomic_queue.c:54
int main(int argc, char *argv[])
#define OFFSET
static NEVER_RETURNS void usage(void)
void request_verify(UNUSED char const *file, UNUSED int line, UNUSED request_t *request)
static int debug_lvl
#define RCSID(id)
Definition: build.h:481
#define NEVER_RETURNS
Should be placed before the function return type.
Definition: build.h:311
#define UNUSED
Definition: build.h:313
static fr_atomic_queue_t * aq
Definition: control_test.c:47
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition: debug.h:234
static TALLOC_CTX * autofree
Definition: radclient-ng.c:107
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition: talloc.h:51
static fr_slen_t data
Definition: value.h:1265