16 /* this tests tdb by doing lots of ops from several simultaneous
17 writers - that stresses the locking code. Build with TDB_DEBUG=1
22 #define REOPEN_PROB 30
26 #define LOCKSTORE_PROB 0
27 #define TRAVERSE_PROB 20
33 static TDB_CONTEXT
*db
;
35 static void tdb_log(TDB_CONTEXT
*tdb
, int level
, const char *format
, ...)
40 vfprintf(stdout
, format
, ap
);
46 asprintf(&ptr
,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid());
53 static void fatal(char *why
)
59 static char *randbuf(int len
)
63 buf
= (char *)malloc(len
+1);
66 buf
[i
] = 'a' + (rand() % 26);
72 static int cull_traverse(TDB_CONTEXT
*tdb
, TDB_DATA key
, TDB_DATA dbuf
,
75 if (random() % CULL_PROB
== 0) {
81 static void addrec_db(void)
85 TDB_DATA key
, data
, lockkey
;
87 klen
= 1 + (rand() % KEYLEN
);
88 dlen
= 1 + (rand() % DATALEN
);
89 slen
= 1 + (rand() % LOCKLEN
);
102 lockkey
.dsize
= slen
+1;
105 if (random() % REOPEN_PROB
== 0) {
112 if (random() % DELETE_PROB
== 0) {
119 if (random() % STORE_PROB
== 0) {
120 if (tdb_store(db
, key
, data
, TDB_REPLACE
) != 0) {
121 fatal("tdb_store failed");
128 if (random() % APPEND_PROB
== 0) {
129 if (tdb_append(db
, key
, data
) != 0) {
130 fatal("tdb_append failed");
137 if (random() % LOCKSTORE_PROB
== 0) {
138 tdb_chainlock(db
, lockkey
);
139 data
= tdb_fetch(db
, key
);
140 if (tdb_store(db
, key
, data
, TDB_REPLACE
) != 0) {
141 fatal("tdb_store failed");
143 if (data
.dptr
) free(data
.dptr
);
144 tdb_chainunlock(db
, lockkey
);
150 if (random() % TRAVERSE_PROB
== 0) {
151 tdb_traverse(db
, cull_traverse
, NULL
);
156 data
= tdb_fetch(db
, key
);
157 if (data
.dptr
) free(data
.dptr
);
165 static int traverse_fn(TDB_CONTEXT
*tdb
, TDB_DATA key
, TDB_DATA dbuf
,
168 tdb_delete(tdb
, key
);
177 #define NLOOPS 200000
180 int main(int argc
, char *argv
[])
188 for (i
=0;i
<NPROC
-1;i
++) {
189 if ((pids
[i
+1]=fork()) == 0) break;
192 db
= tdb_open("torture.tdb", 2, TDB_CLEAR_IF_FIRST
,
193 O_RDWR
| O_CREAT
, 0600);
195 fatal("db open failed");
197 tdb_logging_function(db
, tdb_log
);
199 srand(seed
+ getpid());
200 srandom(seed
+ getpid() + time(NULL
));
201 for (i
=0;i
<loops
;i
++) addrec_db();
203 tdb_traverse(db
, NULL
, NULL
);
204 tdb_traverse(db
, traverse_fn
, NULL
);
205 tdb_traverse(db
, traverse_fn
, NULL
);
209 if (getpid() == pids
[0]) {
210 for (i
=0;i
<NPROC
-1;i
++) {
212 if (waitpid(pids
[i
+1], &status
, 0) != pids
[i
+1]) {
213 printf("failed to wait for %d\n",
217 if (WEXITSTATUS(status
) != 0) {
218 printf("child %d exited with status %d\n",
219 (int)pids
[i
+1], WEXITSTATUS(status
));