14 /* this tests tdb by doing lots of ops from several simultaneous
15 writers - that stresses the locking code. Build with TDB_DEBUG=1
20 #define DELETE_PROB 10
22 #define TRAVERSE_PROB 8
27 static TDB_CONTEXT
*db
;
29 static void tdb_log(TDB_CONTEXT
*tdb
, int level
, const char *format
, ...)
34 vfprintf(stdout
, format
, ap
);
39 asprintf(&ptr
,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid());
46 static void fatal(char *why
)
52 static char *randbuf(int len
)
56 buf
= (char *)malloc(len
+1);
59 buf
[i
] = 'a' + (rand() % 26);
65 static int cull_traverse(TDB_CONTEXT
*db
, TDB_DATA key
, TDB_DATA dbuf
,
68 if (random() % CULL_PROB
== 0) {
74 static void addrec_db(void)
80 klen
= 1 + (rand() % KEYLEN
);
81 dlen
= 1 + (rand() % DATALEN
);
92 if (random() % DELETE_PROB
== 0) {
94 } else if (random() % STORE_PROB
== 0) {
95 if (tdb_store(db
, key
, data
, TDB_REPLACE
) != 0) {
96 fatal("tdb_store failed");
98 } else if (random() % TRAVERSE_PROB
== 0) {
99 tdb_traverse(db
, cull_traverse
, NULL
);
101 data
= tdb_fetch(db
, key
);
102 if (data
.dptr
) free(data
.dptr
);
109 static int traverse_fn(TDB_CONTEXT
*db
, TDB_DATA key
, TDB_DATA dbuf
,
121 #define NLOOPS 200000
124 int main(int argc
, char *argv
[])
132 for (i
=0;i
<NPROC
-1;i
++) {
133 if ((pids
[i
+1]=fork()) == 0) break;
136 db
= tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST
,
137 O_RDWR
| O_CREAT
, 0600);
139 fatal("db open failed");
141 tdb_logging_function(db
, tdb_log
);
143 srand(seed
+ getpid());
144 srandom(seed
+ getpid() + time(NULL
));
145 for (i
=0;i
<loops
;i
++) addrec_db();
147 tdb_traverse(db
, NULL
, NULL
);
148 tdb_traverse(db
, traverse_fn
, NULL
);
149 tdb_traverse(db
, traverse_fn
, NULL
);
153 if (getpid() == pids
[0]) {
154 for (i
=0;i
<NPROC
-1;i
++) {
156 if (waitpid(pids
[i
+1], &status
, 0) != pids
[i
+1]) {
157 printf("failed to wait for %d\n",
161 if (WEXITSTATUS(status
) != 0) {
162 printf("child %d exited with status %d\n",
163 (int)pids
[i
+1], WEXITSTATUS(status
));