~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/*
2
  Just a test application for threads.
3
  */
4
#include "azio.h"
383.1.44 by Monty Taylor
Renamed drizzle.h to libdrizzle.h.
5
#include <libdrizzle/libdrizzle.h>
212.5.21 by Monty Taylor
Moved my_getopt.h
6
#include <mysys/my_getopt.h>
1 by brian
clean slate
7
#include <stdio.h>
8
#include <stdlib.h>
9
#include <sys/types.h>
10
#include <sys/stat.h>
11
#include <sys/types.h>
12
#include <sys/mman.h>
13
#include <fcntl.h>
14
#include <sys/time.h>
15
#include <pthread.h>
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
16
#include <string.h>                             /* Pull in memset() */
1 by brian
clean slate
17
#ifndef __WIN__
18
#include <sys/wait.h>
19
#endif
20
21
#ifdef __WIN__
22
#define srandom  srand
23
#define random   rand
24
#define snprintf _snprintf
25
#endif
26
27
#include "azio.h"
28
29
#define DEFAULT_INITIAL_LOAD 10000
30
#define DEFAULT_EXECUTE_SECONDS 120
31
#define TEST_FILENAME "concurrency_test.az"
32
33
#define HUGE_STRING_LENGTH 8192
34
35
/* Global Thread counter */
36
unsigned int thread_counter;
37
pthread_mutex_t counter_mutex;
38
pthread_cond_t count_threshhold;
39
unsigned int master_wakeup;
40
pthread_mutex_t sleeper_mutex;
41
pthread_cond_t sleep_threshhold;
282 by Brian Aker
Modified blackhole and archive to remove my_bool.
42
static bool timer_alarm= false;
1 by brian
clean slate
43
pthread_mutex_t timer_alarm_mutex;
44
pthread_cond_t timer_alarm_threshold;
45
46
pthread_mutex_t row_lock;
47
48
/* Prototypes */
602 by Brian Aker
Merge in Monty's work for Solaris Sun Studio
49
void *run_concurrent_task(void *p);
1 by brian
clean slate
50
void *timer_thread(void *p);
51
void scheduler(az_method use_aio);
481.1.2 by Monty Taylor
Replaced all unsigned long long with uint64_t.
52
void create_data_file(azio_stream *write_handler, uint64_t rows);
1 by brian
clean slate
53
unsigned int write_row(azio_stream *s);
54
55
typedef struct thread_context_st thread_context_st;
56
struct thread_context_st {
57
  unsigned int how_often_to_write;
481.1.2 by Monty Taylor
Replaced all unsigned long long with uint64_t.
58
  uint64_t counter;
1 by brian
clean slate
59
  az_method use_aio;
60
  azio_stream *writer;
61
};
62
63
/* Use this for string generation */
64
static const char ALPHANUMERICS[]=
65
  "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstuvwxyz";
66
67
#define ALPHANUMERICS_SIZE (sizeof(ALPHANUMERICS)-1)
68
69
static void get_random_string(char *buffer, size_t size)
70
{
71
  char *buffer_ptr= buffer;
72
73
  while (--size)
74
    *buffer_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE];
75
  *buffer_ptr++= ALPHANUMERICS[random() % ALPHANUMERICS_SIZE];
76
}
77
78
int main(int argc, char *argv[])
79
{
80
81
  az_method method;
82
  my_init();
83
84
  MY_INIT(argv[0]);
85
86
  if (argc > 1)
87
    exit(1);
88
89
  srandom(time(NULL));
90
91
  pthread_mutex_init(&counter_mutex, NULL);
92
  pthread_cond_init(&count_threshhold, NULL);
93
  pthread_mutex_init(&sleeper_mutex, NULL);
94
  pthread_cond_init(&sleep_threshhold, NULL);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
95
  pthread_mutex_init(&timer_alarm_mutex, NULL);
96
  pthread_cond_init(&timer_alarm_threshold, NULL);
97
  pthread_mutex_init(&row_lock, NULL);
1 by brian
clean slate
98
99
  for (method= AZ_METHOD_BLOCK; method < AZ_METHOD_MAX; method++)
100
    scheduler(method);
101
102
  (void)pthread_mutex_destroy(&counter_mutex);
103
  (void)pthread_cond_destroy(&count_threshhold);
104
  (void)pthread_mutex_destroy(&sleeper_mutex);
105
  (void)pthread_cond_destroy(&sleep_threshhold);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
106
  pthread_mutex_destroy(&timer_alarm_mutex);
107
  pthread_cond_destroy(&timer_alarm_threshold);
108
  pthread_mutex_destroy(&row_lock);
1 by brian
clean slate
109
110
  return 0;
111
}
112
113
void scheduler(az_method use_aio)
114
{
115
  unsigned int x;
481.1.2 by Monty Taylor
Replaced all unsigned long long with uint64_t.
116
  uint64_t total;
1 by brian
clean slate
117
  azio_stream writer_handle;
118
  thread_context_st *context;
119
  pthread_t mainthread;            /* Thread descriptor */
120
  pthread_attr_t attr;          /* Thread attributes */
121
122
  pthread_attr_init(&attr);
123
  pthread_attr_setdetachstate(&attr,
124
                              PTHREAD_CREATE_DETACHED);
125
126
  pthread_mutex_lock(&counter_mutex);
127
  thread_counter= 0;
128
129
  create_data_file(&writer_handle, DEFAULT_INITIAL_LOAD);
130
131
  pthread_mutex_lock(&sleeper_mutex);
132
  master_wakeup= 1;
133
  pthread_mutex_unlock(&sleeper_mutex);
134
135
  context= (thread_context_st *)malloc(sizeof(thread_context_st) * DEFAULT_CONCURRENCY);
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
136
  memset(context, 0, sizeof(thread_context_st) * DEFAULT_CONCURRENCY);
1 by brian
clean slate
137
138
  if (!context)
139
  {
140
    fprintf(stderr, "Could not allocate memory for context\n");
141
    exit(1);
142
  }
143
144
  for (x= 0; x < DEFAULT_CONCURRENCY; x++)
145
  {
146
147
    context[x].how_often_to_write= random()%1000;
148
    context[x].writer= &writer_handle;
149
    context[x].counter= 0;
150
    context[x].use_aio= use_aio;
151
152
    /* now you create the thread */
602 by Brian Aker
Merge in Monty's work for Solaris Sun Studio
153
    if (pthread_create(&mainthread, &attr, run_concurrent_task,
1 by brian
clean slate
154
                       (void *)context) != 0)
155
    {
156
      fprintf(stderr,"Could not create thread\n");
157
      exit(1);
158
    }
159
    thread_counter++;
160
  }
161
162
  if (DEFAULT_EXECUTE_SECONDS)
163
  {
164
    time_t opt_timer_length= DEFAULT_EXECUTE_SECONDS;
165
    pthread_mutex_lock(&timer_alarm_mutex);
163 by Brian Aker
Merge Monty's code.
166
    timer_alarm= true;
1 by brian
clean slate
167
    pthread_mutex_unlock(&timer_alarm_mutex);
168
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
169
    if (pthread_create(&mainthread, &attr, timer_thread,
1 by brian
clean slate
170
                       (void *)&opt_timer_length) != 0)
171
    {
172
      fprintf(stderr,"%s: Could not create timer thread\n", my_progname);
173
      exit(1);
174
    }
175
  }
176
177
  pthread_mutex_unlock(&counter_mutex);
178
  pthread_attr_destroy(&attr);
179
180
  pthread_mutex_lock(&sleeper_mutex);
181
  master_wakeup= 0;
182
  pthread_mutex_unlock(&sleeper_mutex);
183
  pthread_cond_broadcast(&sleep_threshhold);
184
185
  /*
186
    We loop until we know that all children have cleaned up.
187
  */
188
  pthread_mutex_lock(&counter_mutex);
189
  while (thread_counter)
190
  {
191
    struct timespec abstime;
192
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
193
    memset(&abstime, 0, sizeof(struct timespec));
1 by brian
clean slate
194
    abstime.tv_sec= 1;
195
196
    pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
197
  }
198
  pthread_mutex_unlock(&counter_mutex);
199
200
  for (total= x= 0; x < DEFAULT_CONCURRENCY; x++)
201
    total+= context[x].counter;
202
203
  free(context);
204
  azclose(&writer_handle);
205
481.1.2 by Monty Taylor
Replaced all unsigned long long with uint64_t.
206
  printf("Read %"PRIu64" rows\n", total);
1 by brian
clean slate
207
}
208
209
void *timer_thread(void *p)
210
{
211
  time_t *timer_length= (time_t *)p;
212
  struct timespec abstime;
213
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
214
  /*
215
    We lock around the initial call in case were we in a loop. This
1 by brian
clean slate
216
    also keeps the value properly syncronized across call threads.
217
  */
218
  pthread_mutex_lock(&sleeper_mutex);
219
  while (master_wakeup)
220
  {
221
    pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
222
  }
223
  pthread_mutex_unlock(&sleeper_mutex);
224
225
  set_timespec(abstime, *timer_length);
226
227
  pthread_mutex_lock(&timer_alarm_mutex);
228
  pthread_cond_timedwait(&timer_alarm_threshold, &timer_alarm_mutex, &abstime);
229
  pthread_mutex_unlock(&timer_alarm_mutex);
230
231
  pthread_mutex_lock(&timer_alarm_mutex);
163 by Brian Aker
Merge Monty's code.
232
  timer_alarm= false;
1 by brian
clean slate
233
  pthread_mutex_unlock(&timer_alarm_mutex);
234
235
  return 0;
236
}
237
602 by Brian Aker
Merge in Monty's work for Solaris Sun Studio
238
void *run_concurrent_task(void *p)
1 by brian
clean slate
239
{
240
  thread_context_st *context= (thread_context_st *)p;
481.1.2 by Monty Taylor
Replaced all unsigned long long with uint64_t.
241
  uint64_t count;
1 by brian
clean slate
242
  int ret;
243
  int error;
244
  azio_stream reader_handle;
245
492.1.14 by Monty Taylor
Removed O_BINARY and FILE_BINARY.
246
  if (!(ret= azopen(&reader_handle, TEST_FILENAME, O_RDONLY,
1 by brian
clean slate
247
                    context->use_aio)))
248
  {
249
    printf("Could not open test file\n");
250
    return 0;
251
  }
252
253
  pthread_mutex_lock(&sleeper_mutex);
254
  while (master_wakeup)
255
  {
256
    pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
257
  }
1 by brian
clean slate
258
  pthread_mutex_unlock(&sleeper_mutex);
259
260
  /* Do Stuff */
261
  count= 0;
262
  while (1)
263
  {
264
    azread_init(&reader_handle);
265
    while ((ret= azread_row(&reader_handle, &error)))
266
      context->counter++;
267
268
    if (count % context->how_often_to_write)
269
    {
270
      write_row(context->writer);
271
    }
272
273
    /* If the timer is set, and the alarm is not active then end */
163 by Brian Aker
Merge Monty's code.
274
    if (timer_alarm == false)
1 by brian
clean slate
275
      break;
276
  }
277
278
  pthread_mutex_lock(&counter_mutex);
279
  thread_counter--;
280
  pthread_cond_signal(&count_threshhold);
281
  pthread_mutex_unlock(&counter_mutex);
282
  azclose(&reader_handle);
283
284
  return NULL;
285
}
286
481.1.2 by Monty Taylor
Replaced all unsigned long long with uint64_t.
287
void create_data_file(azio_stream *write_handler, uint64_t rows)
1 by brian
clean slate
288
{
289
  int ret;
481.1.2 by Monty Taylor
Replaced all unsigned long long with uint64_t.
290
  uint64_t x;
1 by brian
clean slate
291
492.1.14 by Monty Taylor
Removed O_BINARY and FILE_BINARY.
292
  if (!(ret= azopen(write_handler, TEST_FILENAME, O_CREAT|O_RDWR|O_TRUNC,
1 by brian
clean slate
293
                    AZ_METHOD_BLOCK)))
294
  {
295
    printf("Could not create test file\n");
296
    exit(1);
297
  }
298
299
  for (x= 0; x < rows; x++)
300
    write_row(write_handler);
301
302
  azflush(write_handler, Z_SYNC_FLUSH);
303
}
304
305
unsigned int write_row(azio_stream *s)
306
{
307
  size_t length;
308
  char buffer[HUGE_STRING_LENGTH];
309
310
  length= random() % HUGE_STRING_LENGTH;
311
312
  /* Avoid zero length strings */
313
  length++;
314
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
315
  get_random_string(buffer, length);
1 by brian
clean slate
316
  pthread_mutex_lock(&row_lock);
317
  azwrite_row(s, buffer, length);
318
  pthread_mutex_unlock(&row_lock);
319
320
  return 0;
321
}