~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/archive/concurrency_test.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2009 Sun Microsystems
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; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
1
/*
21
2
  Just a test application for threads.
22
3
  */
23
 
 
24
 
#include "config.h"
25
 
 
26
4
#include "azio.h"
 
5
#include <mysql.h>
 
6
#include <my_getopt.h>
 
7
#include <mysql_version.h>
27
8
#include <stdio.h>
28
9
#include <stdlib.h>
29
10
#include <sys/types.h>
33
14
#include <fcntl.h>
34
15
#include <sys/time.h>
35
16
#include <pthread.h>
36
 
#include <string.h>                             /* Pull in memset() */
 
17
#include <strings.h>
37
18
#ifndef __WIN__
38
19
#include <sys/wait.h>
39
20
#endif
40
 
#include <memory>
41
21
 
42
22
#ifdef __WIN__
43
23
#define srandom  srand
45
25
#define snprintf _snprintf
46
26
#endif
47
27
 
48
 
#include <boost/scoped_ptr.hpp>
49
 
 
50
28
#include "azio.h"
51
29
 
52
30
#define DEFAULT_INITIAL_LOAD 10000
53
31
#define DEFAULT_EXECUTE_SECONDS 120
 
32
#define DEFAULT_CONCURRENCY 8
54
33
#define TEST_FILENAME "concurrency_test.az"
55
34
 
56
35
#define HUGE_STRING_LENGTH 8192
62
41
unsigned int master_wakeup;
63
42
pthread_mutex_t sleeper_mutex;
64
43
pthread_cond_t sleep_threshhold;
65
 
static bool timer_alarm= false;
 
44
static my_bool timer_alarm= FALSE;
66
45
pthread_mutex_t timer_alarm_mutex;
67
46
pthread_cond_t timer_alarm_threshold;
68
47
 
69
48
pthread_mutex_t row_lock;
70
49
 
71
50
/* Prototypes */
72
 
extern "C" {
73
 
  void *run_concurrent_task(void *p);
74
 
  void *timer_thread(void *p);
75
 
}
 
51
void *run_task(void *p);
 
52
void *timer_thread(void *p);
76
53
void scheduler(az_method use_aio);
77
 
void create_data_file(azio_stream *write_handler, uint64_t rows);
 
54
void create_data_file(azio_stream *write_handler, unsigned long long rows);
78
55
unsigned int write_row(azio_stream *s);
79
56
 
80
57
typedef struct thread_context_st thread_context_st;
81
58
struct thread_context_st {
82
59
  unsigned int how_often_to_write;
83
 
  uint64_t counter;
 
60
  unsigned long long counter;
84
61
  az_method use_aio;
85
62
  azio_stream *writer;
86
63
};
103
80
int main(int argc, char *argv[])
104
81
{
105
82
 
106
 
  unsigned int method;
107
 
  drizzled::internal::my_init();
 
83
  az_method method;
 
84
  my_init();
108
85
 
109
86
  MY_INIT(argv[0]);
110
87
 
111
88
  if (argc > 1)
112
89
    exit(1);
113
90
 
 
91
  if (!(mysql_thread_safe()))
 
92
      fprintf(stderr, "This application was compiled incorrectly. Please recompile with thread support.\n");
 
93
 
114
94
  srandom(time(NULL));
115
95
 
116
96
  pthread_mutex_init(&counter_mutex, NULL);
117
97
  pthread_cond_init(&count_threshhold, NULL);
118
98
  pthread_mutex_init(&sleeper_mutex, NULL);
119
99
  pthread_cond_init(&sleep_threshhold, NULL);
120
 
  pthread_mutex_init(&timer_alarm_mutex, NULL);
121
 
  pthread_cond_init(&timer_alarm_threshold, NULL);
122
 
  pthread_mutex_init(&row_lock, NULL);
 
100
  VOID(pthread_mutex_init(&timer_alarm_mutex, NULL));
 
101
  VOID(pthread_cond_init(&timer_alarm_threshold, NULL));
 
102
  VOID(pthread_mutex_init(&row_lock, NULL));
123
103
 
124
104
  for (method= AZ_METHOD_BLOCK; method < AZ_METHOD_MAX; method++)
125
 
    scheduler((az_method)method);
 
105
    scheduler(method);
126
106
 
127
107
  (void)pthread_mutex_destroy(&counter_mutex);
128
108
  (void)pthread_cond_destroy(&count_threshhold);
129
109
  (void)pthread_mutex_destroy(&sleeper_mutex);
130
110
  (void)pthread_cond_destroy(&sleep_threshhold);
131
 
  pthread_mutex_destroy(&timer_alarm_mutex);
132
 
  pthread_cond_destroy(&timer_alarm_threshold);
133
 
  pthread_mutex_destroy(&row_lock);
 
111
  VOID(pthread_mutex_destroy(&timer_alarm_mutex));
 
112
  VOID(pthread_cond_destroy(&timer_alarm_threshold));
 
113
  VOID(pthread_mutex_destroy(&row_lock));
134
114
 
135
115
  return 0;
136
116
}
138
118
void scheduler(az_method use_aio)
139
119
{
140
120
  unsigned int x;
141
 
  uint64_t total;
142
 
  boost::scoped_ptr<azio_stream> writer_handle_ap(new azio_stream);
143
 
  azio_stream &writer_handle= *writer_handle_ap.get();
 
121
  unsigned long long total;
 
122
  azio_stream writer_handle;
144
123
  thread_context_st *context;
145
124
  pthread_t mainthread;            /* Thread descriptor */
146
125
  pthread_attr_t attr;          /* Thread attributes */
159
138
  pthread_mutex_unlock(&sleeper_mutex);
160
139
 
161
140
  context= (thread_context_st *)malloc(sizeof(thread_context_st) * DEFAULT_CONCURRENCY);
162
 
  memset(context, 0, sizeof(thread_context_st) * DEFAULT_CONCURRENCY);
 
141
  bzero(context, sizeof(thread_context_st) * DEFAULT_CONCURRENCY);
163
142
 
164
143
  if (!context)
165
144
  {
176
155
    context[x].use_aio= use_aio;
177
156
 
178
157
    /* now you create the thread */
179
 
    if (pthread_create(&mainthread, &attr, run_concurrent_task,
 
158
    if (pthread_create(&mainthread, &attr, run_task,
180
159
                       (void *)context) != 0)
181
160
    {
182
161
      fprintf(stderr,"Could not create thread\n");
189
168
  {
190
169
    time_t opt_timer_length= DEFAULT_EXECUTE_SECONDS;
191
170
    pthread_mutex_lock(&timer_alarm_mutex);
192
 
    timer_alarm= true;
 
171
    timer_alarm= TRUE;
193
172
    pthread_mutex_unlock(&timer_alarm_mutex);
194
173
 
195
 
    if (pthread_create(&mainthread, &attr, timer_thread,
 
174
    if (pthread_create(&mainthread, &attr, timer_thread, 
196
175
                       (void *)&opt_timer_length) != 0)
197
176
    {
198
 
      fprintf(stderr,"%s: Could not create timer thread\n", drizzled::internal::my_progname);
 
177
      fprintf(stderr,"%s: Could not create timer thread\n", my_progname);
199
178
      exit(1);
200
179
    }
201
180
  }
216
195
  {
217
196
    struct timespec abstime;
218
197
 
219
 
    memset(&abstime, 0, sizeof(struct timespec));
 
198
    bzero(&abstime, sizeof(struct timespec));
220
199
    abstime.tv_sec= 1;
221
200
 
222
201
    pthread_cond_timedwait(&count_threshhold, &counter_mutex, &abstime);
229
208
  free(context);
230
209
  azclose(&writer_handle);
231
210
 
232
 
  printf("Read %"PRIu64" rows\n", total);
 
211
  printf("Read %llu rows\n", total);
233
212
}
234
213
 
235
214
void *timer_thread(void *p)
237
216
  time_t *timer_length= (time_t *)p;
238
217
  struct timespec abstime;
239
218
 
240
 
  /*
241
 
    We lock around the initial call in case were we in a loop. This
 
219
  if (mysql_thread_init())
 
220
  {
 
221
    fprintf(stderr,"%s: mysql_thread_init() failed.\n",
 
222
            my_progname);
 
223
    exit(1);
 
224
  }
 
225
 
 
226
  /* 
 
227
    We lock around the initial call in case were we in a loop. This 
242
228
    also keeps the value properly syncronized across call threads.
243
229
  */
244
230
  pthread_mutex_lock(&sleeper_mutex);
255
241
  pthread_mutex_unlock(&timer_alarm_mutex);
256
242
 
257
243
  pthread_mutex_lock(&timer_alarm_mutex);
258
 
  timer_alarm= false;
 
244
  timer_alarm= FALSE;
259
245
  pthread_mutex_unlock(&timer_alarm_mutex);
260
246
 
 
247
  mysql_thread_end();
 
248
 
261
249
  return 0;
262
250
}
263
251
 
264
 
void *run_concurrent_task(void *p)
 
252
void *run_task(void *p)
265
253
{
266
254
  thread_context_st *context= (thread_context_st *)p;
267
 
  uint64_t count;
 
255
  unsigned long long count;
268
256
  int ret;
269
257
  int error;
270
 
  boost::scoped_ptr<azio_stream> reader_handle_ap(new azio_stream);
271
 
  azio_stream &reader_handle= *reader_handle_ap.get();
272
 
 
273
 
  if (!(ret= azopen(&reader_handle, TEST_FILENAME, O_RDONLY,
 
258
  azio_stream reader_handle;
 
259
 
 
260
  if (mysql_thread_init())
 
261
  {
 
262
    fprintf(stderr,"%s: mysql_thread_init() failed.\n", my_progname);
 
263
    exit(1);
 
264
  }
 
265
 
 
266
  if (!(ret= azopen(&reader_handle, TEST_FILENAME, O_RDONLY|O_BINARY,
274
267
                    context->use_aio)))
275
268
  {
276
269
    printf("Could not open test file\n");
281
274
  while (master_wakeup)
282
275
  {
283
276
    pthread_cond_wait(&sleep_threshhold, &sleeper_mutex);
284
 
  }
 
277
  } 
285
278
  pthread_mutex_unlock(&sleeper_mutex);
286
279
 
287
280
  /* Do Stuff */
298
291
    }
299
292
 
300
293
    /* If the timer is set, and the alarm is not active then end */
301
 
    if (timer_alarm == false)
 
294
    if (timer_alarm == FALSE)
302
295
      break;
303
296
  }
304
297
 
308
301
  pthread_mutex_unlock(&counter_mutex);
309
302
  azclose(&reader_handle);
310
303
 
 
304
  mysql_thread_end();
 
305
 
311
306
  return NULL;
312
307
}
313
308
 
314
 
void create_data_file(azio_stream *write_handler, uint64_t rows)
 
309
void create_data_file(azio_stream *write_handler, unsigned long long rows)
315
310
{
316
311
  int ret;
317
 
  uint64_t x;
 
312
  unsigned long long x;
318
313
 
319
 
  if (!(ret= azopen(write_handler, TEST_FILENAME, O_CREAT|O_RDWR|O_TRUNC,
 
314
  if (!(ret= azopen(write_handler, TEST_FILENAME, O_CREAT|O_RDWR|O_TRUNC|O_BINARY,
320
315
                    AZ_METHOD_BLOCK)))
321
316
  {
322
317
    printf("Could not create test file\n");
339
334
  /* Avoid zero length strings */
340
335
  length++;
341
336
 
342
 
  get_random_string(buffer, length);
 
337
  get_random_string(buffer, length); 
343
338
  pthread_mutex_lock(&row_lock);
344
339
  azwrite_row(s, buffer, length);
345
340
  pthread_mutex_unlock(&row_lock);