~ubuntu-branches/ubuntu/precise/apr-util/precise

« back to all changes in this revision

Viewing changes to test/testqueue.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Fritsch
  • Date: 2008-01-12 10:17:09 UTC
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20080112101709-svfgyi40u41za6v2
ImportĀ upstreamĀ versionĀ 1.2.12+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
2
 
 * applicable.
3
 
 *
4
 
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 
 * you may not use this file except in compliance with the License.
6
 
 * You may obtain a copy of the License at
 
1
/* Licensed to the Apache Software Foundation (ASF) under one or more
 
2
 * contributor license agreements.  See the NOTICE file distributed with
 
3
 * this work for additional information regarding copyright ownership.
 
4
 * The ASF licenses this file to You under the Apache License, Version 2.0
 
5
 * (the "License"); you may not use this file except in compliance with
 
6
 * the License.  You may obtain a copy of the License at
7
7
 *
8
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
9
 *
14
14
 * limitations under the License.
15
15
 */
16
16
 
17
 
#include <apr_thread_proc.h>
18
 
#include <apr_errno.h>
19
 
#include <apr_general.h>
20
 
#include <apr_getopt.h>
21
 
#include <apr_strings.h>
22
 
#include "errno.h"
23
 
#include <stdio.h>
24
 
#include <stdlib.h>
25
 
#include <apr_time.h>
26
 
#if APR_HAVE_UNISTD_H
27
 
#include <unistd.h>
28
 
#endif
29
 
#include <apr_portable.h>
 
17
#include "apu.h"
30
18
#include "apr_queue.h"
31
 
 
32
 
#if !APR_HAS_THREADS
33
 
int main(void)
34
 
{
35
 
    fprintf(stderr,
36
 
            "This program won't work on this platform because there is no "
37
 
            "support for threads.\n");
38
 
    return 0;
39
 
}
40
 
#else /* !APR_HAS_THREADS */
41
 
 
42
 
apr_pool_t *context;
43
 
int consumer_activity=400;
44
 
int producer_activity=300;
45
 
int verbose=0;
46
 
static void * APR_THREAD_FUNC consumer(apr_thread_t *thd, void *data);
47
 
static void * APR_THREAD_FUNC producer(apr_thread_t *thd, void *data);
48
 
static void usage(void);
 
19
#include "apr_thread_proc.h"
 
20
#include "apr_time.h"
 
21
#include "abts.h"
 
22
#include "testutil.h"
 
23
 
 
24
#if APR_HAS_THREADS
 
25
 
 
26
#define NUMBER_CONSUMERS    3
 
27
#define CONSUMER_ACTIVITY   4
 
28
#define NUMBER_PRODUCERS    4
 
29
#define PRODUCER_ACTIVITY   5
 
30
#define QUEUE_SIZE          100
 
31
 
 
32
static apr_queue_t *queue;
49
33
 
50
34
static void * APR_THREAD_FUNC consumer(apr_thread_t *thd, void *data)
51
35
{
52
36
    long sleeprate;
53
 
    apr_queue_t *q = (apr_queue_t*)data;
 
37
    abts_case *tc = data;
54
38
    apr_status_t rv;
55
 
    int val;
56
39
    void *v;
57
 
    char current_thread_str[30];
58
 
    apr_os_thread_t current_thread = apr_os_thread_current();
59
 
 
60
 
    apr_snprintf(current_thread_str, sizeof current_thread_str,
61
 
                 "%pT", &current_thread);
62
 
 
63
 
    sleeprate = 1000000/consumer_activity;
 
40
 
 
41
    sleeprate = 1000000/CONSUMER_ACTIVITY;
64
42
    apr_sleep( (rand() % 4 ) * 1000000 ); /* sleep random seconds */
65
 
    while (1) {
66
 
        do {
67
 
            rv = apr_queue_pop(q, &v);
68
 
            if (rv == APR_EINTR) {
69
 
                fprintf(stderr, "%s\tconsumer intr\n", current_thread_str);
70
 
            }
71
 
 
72
 
        } while (rv == APR_EINTR) ;
73
 
        if (rv != APR_SUCCESS) {
74
 
            if (rv == APR_EOF) {
75
 
                fprintf(stderr, "%s\tconsumer:queue terminated APR_EOF\n", current_thread_str);
76
 
                rv=APR_SUCCESS;
77
 
            }
78
 
            else 
79
 
                fprintf(stderr, "%s\tconsumer thread exit rv %d\n", current_thread_str, rv);
80
 
            apr_thread_exit(thd, rv);
81
 
            return NULL;
82
 
        }
83
 
        val = *(int*)v;
84
 
        if (verbose)
85
 
            fprintf(stderr,  "%s\tpop %d\n", current_thread_str, val);
 
43
 
 
44
    while (1)
 
45
    {
 
46
        rv = apr_queue_pop(queue, &v);
 
47
 
 
48
        if (rv == APR_EINTR)
 
49
            continue;
 
50
 
 
51
        if (rv == APR_EOF)
 
52
            break;
 
53
        
 
54
        ABTS_TRUE(tc, v == NULL);
 
55
        ABTS_TRUE(tc, rv == APR_SUCCESS);
 
56
 
86
57
        apr_sleep( sleeprate ); /* sleep this long to acheive our rate */
87
58
    }
 
59
 
 
60
    apr_thread_exit(thd, rv);
 
61
 
88
62
    /* not reached */
89
63
    return NULL;
90
64
91
65
 
92
66
static void * APR_THREAD_FUNC producer(apr_thread_t *thd, void *data)
93
67
{
94
 
    int i=0;
95
68
    long sleeprate;
96
 
    apr_queue_t *q = (apr_queue_t*)data;
 
69
    abts_case *tc = data;
97
70
    apr_status_t rv;
98
 
    int *val;
99
 
    char current_thread_str[30];
100
 
    apr_os_thread_t current_thread = apr_os_thread_current();
101
 
 
102
 
    apr_snprintf(current_thread_str, sizeof current_thread_str,
103
 
                 "%pT", &current_thread);
104
 
 
105
 
    sleeprate = 1000000/producer_activity;
 
71
 
 
72
    sleeprate = 1000000/PRODUCER_ACTIVITY;
106
73
    apr_sleep( (rand() % 4 ) * 1000000 ); /* sleep random seconds */
 
74
 
 
75
    while (1)        
 
76
    {
 
77
        rv = apr_queue_push(queue, NULL);
 
78
 
 
79
        if (rv == APR_EINTR)
 
80
            continue;
107
81
        
108
 
    while(1) {
109
 
        val = apr_palloc(context, sizeof(int));
110
 
        *val=i;
111
 
        if (verbose)
112
 
            fprintf(stderr,  "%s\tpush %d\n", current_thread_str, *val);
113
 
        do {
114
 
            rv = apr_queue_push(q, val);
115
 
            if (rv == APR_EINTR) 
116
 
                fprintf(stderr, "%s\tproducer intr\n", current_thread_str);
117
 
        } while (rv == APR_EINTR);
118
 
 
119
 
        if (rv != APR_SUCCESS) {
120
 
            if (rv == APR_EOF) {
121
 
                fprintf(stderr, "%s\tproducer: queue terminated APR_EOF\n", current_thread_str);
122
 
                rv = APR_SUCCESS;
123
 
            }
124
 
            else
125
 
                fprintf(stderr, "%s\tproducer thread exit rv %d\n", current_thread_str, rv);
126
 
            apr_thread_exit(thd, rv);
127
 
            return NULL;
128
 
        }
129
 
        i++;
 
82
        if (rv == APR_EOF)
 
83
            break;
 
84
 
 
85
        ABTS_TRUE(tc, rv == APR_SUCCESS);
 
86
 
130
87
        apr_sleep( sleeprate ); /* sleep this long to acheive our rate */
131
88
    }
132
 
   /* not reached */
 
89
 
 
90
    apr_thread_exit(thd, rv);
 
91
 
 
92
    /* not reached */
133
93
    return NULL;
134
94
135
95
 
136
 
static void usage(void)
137
 
{
138
 
    fprintf(stderr,"usage: testqueue -p n -P n -c n -C n -q n -s n\n");
139
 
    fprintf(stderr,"-c # of consumer\n");
140
 
    fprintf(stderr,"-C amount they consumer before dying\n");
141
 
    fprintf(stderr,"-p # of producers\n");
142
 
    fprintf(stderr,"-P amount they produce before dying\n");
143
 
    fprintf(stderr,"-q queue size\n");
144
 
    fprintf(stderr,"-s amount of time to sleep before killing it\n");
145
 
    fprintf(stderr,"-v verbose\n");
146
 
}
147
 
 
148
 
int main(int argc, const char* const argv[])
149
 
{
 
96
static void test_queue_producer_consumer(abts_case *tc, void *data)
 
97
{
 
98
    unsigned int i;
 
99
    apr_status_t rv;
150
100
    apr_thread_t **t;
151
 
    apr_queue_t *queue;
152
 
    int i;
153
 
    apr_status_t rv;
154
 
    apr_getopt_t *opt;
155
 
    const char *optarg;
156
 
    char c;
157
 
    int numconsumers=3;
158
 
    int numproducers=4;
159
 
    int queuesize=100;
160
 
    int sleeptime=30;
161
 
    char errorbuf[200];
162
101
 
163
 
    apr_initialize();
 
102
    /* XXX: non-portable */
164
103
    srand((unsigned int)apr_time_now());
165
 
    printf("APR Queue Test\n======================\n\n");
166
104
    
167
 
    printf("%-60s", "Initializing the context"); 
168
 
    if (apr_pool_create(&context, NULL) != APR_SUCCESS) {
169
 
        fflush(stdout);
170
 
        fprintf(stderr, "Failed.\nCould not initialize\n");
171
 
        exit(-1);
172
 
    }
173
 
    printf("OK\n");
174
 
 
175
 
    apr_getopt_init(&opt, context, argc, argv);
176
 
    while ((rv = apr_getopt(opt, "p:c:P:C:q:s:v", &c, &optarg))
177
 
            == APR_SUCCESS) {
178
 
        switch (c)  {
179
 
        case 'c':
180
 
            numconsumers = atoi( optarg);
181
 
            break;
182
 
        case 'p':
183
 
            numproducers = atoi( optarg);
184
 
            break;
185
 
        case 'C':
186
 
            consumer_activity = atoi( optarg);
187
 
            break;
188
 
        case 'P':
189
 
            producer_activity = atoi( optarg);
190
 
            break;
191
 
        case 's':
192
 
            sleeptime= atoi(optarg);
193
 
            break;
194
 
        case 'q':
195
 
            queuesize = atoi(optarg);
196
 
            break;
197
 
        case 'v':
198
 
            verbose= 1;
199
 
            break;
200
 
        default:
201
 
            usage();
202
 
            exit(-1);
203
 
        }
204
 
    }
205
 
    /* bad cmdline option?  then we die */
206
 
    if (rv != APR_EOF || opt->ind < opt->argc) {
207
 
        usage();
208
 
        exit(-1);
209
 
    }
210
 
 
211
 
 
212
 
 
213
 
    printf("test stats %d consumers (rate %d/sec) %d producers (rate %d/sec) queue size %d sleep %d\n",
214
 
            numconsumers,consumer_activity, numproducers, producer_activity, queuesize,sleeptime); 
215
 
    printf("%-60s", "Initializing the queue"); 
216
 
    rv  = apr_queue_create(&queue, queuesize, context);
217
 
 
218
 
    if (rv != APR_SUCCESS) {
219
 
        fflush(stdout);
220
 
        fprintf(stderr, "Failed\nCould not create queue %d\n",rv);
221
 
        apr_strerror(rv, errorbuf,200);
222
 
        fprintf(stderr,"%s\n",errorbuf);
223
 
        exit(-1);
224
 
    }
225
 
    printf("OK\n");
226
 
 
227
 
    t = apr_palloc( context, sizeof(apr_thread_t*) * (numconsumers+numproducers));
228
 
    printf("%-60s", "Starting consumers"); 
229
 
    for (i=0;i<numconsumers;i++) {
230
 
        rv = apr_thread_create(&t[i], NULL, consumer, queue, context);
231
 
        if (rv != APR_SUCCESS) {
232
 
            apr_strerror(rv, errorbuf,200);
233
 
            fprintf(stderr, "Failed\nError starting consumer thread (%d) rv=%d:%s\n",i, rv,errorbuf);
234
 
            exit(-1);
235
 
 
236
 
        }
237
 
    }
238
 
    for (i=numconsumers;i<(numconsumers+numproducers);i++) {
239
 
        rv = apr_thread_create(&t[i], NULL, producer, queue, context);
240
 
        if (rv != APR_SUCCESS) {
241
 
            apr_strerror(rv, errorbuf,200);
242
 
            fprintf(stderr, "Failed\nError starting producer thread (%d) rv=%d:%s\n",i, rv,errorbuf);
243
 
            exit(-1);
244
 
 
245
 
        }
246
 
    }
247
 
 
248
 
    printf("OK\n");
249
 
    printf("%-60s", "Sleeping\n"); 
250
 
    apr_sleep( sleeptime * 1000000 ); /* sleep 10 seconds */
251
 
    printf("OK\n");
252
 
 
253
 
    printf("%-60s", "Terminating queue"); 
 
105
    rv = apr_queue_create(&queue, QUEUE_SIZE, p);
 
106
    ABTS_INT_EQUAL(tc, rv, APR_SUCCESS);
 
107
 
 
108
    t = apr_palloc(p, sizeof(apr_thread_t*) * (NUMBER_CONSUMERS 
 
109
                                             + NUMBER_PRODUCERS));
 
110
    for (i = 0; i < NUMBER_CONSUMERS; ++i) {
 
111
        rv = apr_thread_create(&t[i], NULL, consumer, tc, p);
 
112
        ABTS_INT_EQUAL(tc, rv, APR_SUCCESS);
 
113
    }
 
114
    for (i = NUMBER_CONSUMERS; i < NUMBER_CONSUMERS + NUMBER_PRODUCERS; ++i) {
 
115
        rv = apr_thread_create(&t[i], NULL, producer, tc, p);
 
116
        ABTS_INT_EQUAL(tc, rv, APR_SUCCESS);
 
117
    }
 
118
 
 
119
    apr_sleep(5000000); /* sleep 5 seconds */
 
120
 
254
121
    rv = apr_queue_term(queue);
255
 
    if (rv != APR_SUCCESS) {
256
 
        apr_strerror(rv, errorbuf,200);
257
 
        fprintf( stderr, "apr_queue_term failed  %d:%s\n",rv,errorbuf);
258
 
    }
259
 
    printf("OK\n");
260
 
 
261
 
 
262
 
    printf("%-60s", "Waiting for threads to exit\n");
263
 
    fflush(stdout);
264
 
    for (i=0;i<numconsumers+numproducers;i++) {
 
122
    ABTS_INT_EQUAL(tc, rv, APR_SUCCESS);
 
123
 
 
124
    for (i = 0; i < NUMBER_CONSUMERS + NUMBER_PRODUCERS; ++i) {
265
125
        apr_thread_join(&rv, t[i]);
266
 
        if (rv != 0 ) {
267
 
            apr_strerror(rv, errorbuf,200);
268
 
            if (i<numconsumers) 
269
 
                fprintf( stderr, "consumer thread %d failed rv %d:%s\n",i,rv,errorbuf);
270
 
            else
271
 
                fprintf( stderr, "producer thread %d failed rv %d:%s\n",i,rv,errorbuf);
272
 
        }
 
126
        ABTS_INT_EQUAL(tc, rv, APR_EOF);
273
127
    }
274
 
 
275
 
    printf("OK\n");
276
 
 
277
 
    apr_terminate();
278
 
 
279
 
    return 0;
280
 
}
281
 
 
282
 
#endif /* !APR_HAS_THREADS */
 
128
}
 
129
 
 
130
#endif /* APR_HAS_THREADS */
 
131
 
 
132
abts_suite *testqueue(abts_suite *suite)
 
133
{
 
134
    suite = ADD_SUITE(suite);
 
135
 
 
136
#if APR_HAS_THREADS
 
137
    abts_run_test(suite, test_queue_producer_consumer, NULL);
 
138
#endif /* APR_HAS_THREADS */
 
139
 
 
140
    return suite;
 
141
}