1
/* Copyright (C) 2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
#include <my_global.h>
20
#include <my_atomic.h>
23
#include "../trnman.h"
25
pthread_mutex_t rt_mutex;
28
#define STACK_SIZE (((int)stacksize-2048)*STACK_DIRECTION)
34
create and end (commit or rollback) transactions randomly
37
pthread_handler_t test_trnman(void *arg)
41
pthread_mutex_t mutexes[MAX_ITER];
42
pthread_cond_t conds[MAX_ITER];
45
for (i= 0; i < MAX_ITER; i++)
47
pthread_mutex_init(&mutexes[i], MY_MUTEX_INIT_FAST);
48
pthread_cond_init(&conds[i], 0);
51
for (x= ((int)(intptr)(&m)); m > 0; )
53
y= x= (x*LL(3628273133) + LL(1500450271)) % LL(9576890767); /* three prime numbers */
55
for (i= 0; i < n; i++)
57
trn[i]= trnman_new_trn(&mutexes[i], &conds[i], &m + STACK_SIZE);
60
diag("trnman_new_trn() failed");
64
for (i= 0; i < n; i++)
67
trnman_end_trn(trn[i], y & 1);
70
for (i= 0; i < MAX_ITER; i++)
72
pthread_mutex_destroy(&mutexes[i]);
73
pthread_cond_destroy(&conds[i]);
75
pthread_mutex_lock(&rt_mutex);
77
pthread_mutex_unlock(&rt_mutex);
83
void run_test(const char *test, pthread_handler handler, int n, int m)
86
ulonglong now= my_getsystime();
91
threads= (pthread_t *)my_malloc(sizeof(void *)*n, MYF(0));
94
diag("Out of memory");
98
diag("Testing %s with %d threads, %d iterations... ", test, n, m);
100
for (i= 0; i < n ; i++)
101
if (pthread_create(threads+i, &attr, handler, &m))
103
diag("Could not create thread");
106
for (i= 0 ; i < n ; i++)
107
pthread_join(threads[i], 0);
108
now= my_getsystime()-now;
109
ok(litmus == 0, "Tested %s in %g secs (%d)", test, ((double)now)/1e7, litmus);
110
my_free((void*)threads, MYF(0));
113
#define ok_read_from(T1, T2, RES) \
114
i= trnman_can_read_from(trn[T1], trid[T2]); \
115
ok(i == RES, "trn" #T1 " %s read from trn" #T2, i ? "can" : "cannot")
116
#define start_transaction(T) \
117
trn[T]= trnman_new_trn(&mutexes[T], &conds[T], &i + STACK_SIZE); \
118
trid[T]= trn[T]->trid
119
#define commit(T) trnman_commit_trn(trn[T])
120
#define abort(T) trnman_abort_trn(trn[T])
123
void test_trnman_read_from()
127
pthread_mutex_t mutexes[Ntrns];
128
pthread_cond_t conds[Ntrns];
131
for (i= 0; i < Ntrns; i++)
133
pthread_mutex_init(&mutexes[i], MY_MUTEX_INIT_FAST);
134
pthread_cond_init(&conds[i], 0);
137
start_transaction(0); /* start trn1 */
138
start_transaction(1); /* start trn2 */
139
ok_read_from(1, 0, 0);
140
commit(0); /* commit trn1 */
141
start_transaction(2); /* start trn4 */
142
abort(2); /* abort trn4 */
143
start_transaction(3); /* start trn5 */
144
ok_read_from(3, 0, 1);
145
ok_read_from(3, 1, 0);
146
ok_read_from(3, 2, 0);
147
ok_read_from(3, 3, 1);
148
commit(1); /* commit trn2 */
149
ok_read_from(3, 1, 0);
150
commit(3); /* commit trn5 */
152
for (i= 0; i < Ntrns; i++)
154
pthread_mutex_destroy(&mutexes[i]);
155
pthread_cond_destroy(&conds[i]);
159
int main(int argc __attribute__((unused)), char **argv)
166
if (my_atomic_initialize())
167
return exit_status();
169
pthread_mutex_init(&rt_mutex, 0);
170
pthread_attr_init(&attr);
171
#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
172
pthread_attr_getstacksize(&attr, &stacksize);
175
stacksize= PTHREAD_STACK_MIN;
182
test_trnman_read_from();
183
run_test("trnman", test_trnman, THREADS, CYCLES);
185
diag("mallocs: %d", trnman_allocated_transactions);
187
ulonglong now= my_getsystime();
189
now= my_getsystime()-now;
190
diag("trnman_destroy: %g", ((double)now)/1e7);
193
pthread_mutex_destroy(&rt_mutex);
195
return exit_status();
198
#include "../ma_check_standalone.h"