15 /* this tests tdb by doing lots of ops from several simultaneous
16 writers - that stresses the locking code. Build with TDB_DEBUG=1
21 #define REOPEN_PROB 30
25 #define LOCKSTORE_PROB 0
26 #define TRAVERSE_PROB 20
32 static TDB_CONTEXT
*db
;
34 static void tdb_log(TDB_CONTEXT
*tdb
, int level
, const char *format
, ...)
39 vfprintf(stdout
, format
, ap
);
45 asprintf(&ptr
,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid());
52 static void fatal(char *why
)
58 static char *randbuf(int len
)
62 buf
= (char *)malloc(len
+1);
65 buf
[i
] = 'a' + (rand() % 26);
71 static int cull_traverse(TDB_CONTEXT
*tdb
, TDB_DATA key
, TDB_DATA dbuf
,
74 if (random() % CULL_PROB
== 0) {
80 static void addrec_db(void)
84 TDB_DATA key
, data
, lockkey
;
86 klen
= 1 + (rand() % KEYLEN
);
87 dlen
= 1 + (rand() % DATALEN
);
88 slen
= 1 + (rand() % LOCKLEN
);
101 lockkey
.dsize
= slen
+1;
104 if (random() % REOPEN_PROB
== 0) {
111 if (random() % DELETE_PROB
== 0) {
118 if (random() % STORE_PROB
== 0) {
119 if (tdb_store(db
, key
, data
, TDB_REPLACE
) != 0) {
120 fatal("tdb_store failed");
127 if (random() % APPEND_PROB
== 0) {
128 if (tdb_append(db
, key
, data
) != 0) {
129 fatal("tdb_append failed");
136 if (random() % LOCKSTORE_PROB
== 0) {
137 tdb_chainlock(db
, lockkey
);
138 data
= tdb_fetch(db
, key
);
139 if (tdb_store(db
, key
, data
, TDB_REPLACE
) != 0) {
140 fatal("tdb_store failed");
142 if (data
.dptr
) free(data
.dptr
);
143 tdb_chainunlock(db
, lockkey
);
149 if (random() % TRAVERSE_PROB
== 0) {
150 tdb_traverse(db
, cull_traverse
, NULL
);
155 data
= tdb_fetch(db
, key
);
156 if (data
.dptr
) free(data
.dptr
);
164 static int traverse_fn(TDB_CONTEXT
*tdb
, TDB_DATA key
, TDB_DATA dbuf
,
167 tdb_delete(tdb
, key
);
176 #define NLOOPS 200000
179 int main(int argc
, char *argv
[])
187 for (i
=0;i
<NPROC
-1;i
++) {
188 if ((pids
[i
+1]=fork()) == 0) break;
191 db
= tdb_open("torture.tdb", 2, TDB_CLEAR_IF_FIRST
,
192 O_RDWR
| O_CREAT
, 0600);
194 fatal("db open failed");
196 tdb_logging_function(db
, tdb_log
);
198 srand(seed
+ getpid());
199 srandom(seed
+ getpid() + time(NULL
));
200 for (i
=0;i
<loops
;i
++) addrec_db();
202 tdb_traverse(db
, NULL
, NULL
);
203 tdb_traverse(db
, traverse_fn
, NULL
);
204 tdb_traverse(db
, traverse_fn
, NULL
);
208 if (getpid() == pids
[0]) {
209 for (i
=0;i
<NPROC
-1;i
++) {
211 if (waitpid(pids
[i
+1], &status
, 0) != pids
[i
+1]) {
212 printf("failed to wait for %d\n",
216 if (WEXITSTATUS(status
) != 0) {
217 printf("child %d exited with status %d\n",
218 (int)pids
[i
+1], WEXITSTATUS(status
));