📄 tdbtorture.c
字号:
#include <stdlib.h>#include <time.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <fcntl.h>#include <stdarg.h>#include <sys/mman.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/wait.h>#include "tdb.h"/* this tests tdb by doing lots of ops from several simultaneous writers - that stresses the locking code. Build with TDB_DEBUG=1 for best effect */#define REOPEN_PROB 30#define DELETE_PROB 8#define STORE_PROB 4#define LOCKSTORE_PROB 0#define TRAVERSE_PROB 20#define CULL_PROB 100#define KEYLEN 3#define DATALEN 100#define LOCKLEN 20static TDB_CONTEXT *db;static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...){ va_list ap; va_start(ap, format); vfprintf(stdout, format, ap); va_end(ap); fflush(stdout);#if 0 { char *ptr; asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); system(ptr); free(ptr); }#endif }static void fatal(char *why){ perror(why); exit(1);}static char *randbuf(int len){ char *buf; int i; buf = (char *)malloc(len+1); for (i=0;i<len;i++) { buf[i] = 'a' + (rand() % 26); } buf[i] = 0; return buf;}static int cull_traverse(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, void *state){ if (random() % CULL_PROB == 0) { tdb_delete(db, key); } return 0;}static void addrec_db(void){ int klen, dlen, slen; char *k, *d, *s; TDB_DATA key, data, lockkey; klen = 1 + (rand() % KEYLEN); dlen = 1 + (rand() % DATALEN); slen = 1 + (rand() % LOCKLEN); k = randbuf(klen); d = randbuf(dlen); s = randbuf(slen); key.dptr = k; key.dsize = klen+1; data.dptr = d; data.dsize = dlen+1; lockkey.dptr = s; lockkey.dsize = slen+1;#if REOPEN_PROB if (random() % REOPEN_PROB == 0) { tdb_reopen_all(); goto next; } #endif#if DELETE_PROB if (random() % DELETE_PROB == 0) { tdb_delete(db, key); goto next; }#endif#if STORE_PROB if (random() % STORE_PROB == 0) { if (tdb_store(db, key, data, TDB_REPLACE) != 0) { fatal("tdb_store failed"); } goto next; }#endif#if LOCKSTORE_PROB if (random() % LOCKSTORE_PROB == 0) { tdb_chainlock(db, lockkey); data = tdb_fetch(db, key); if (tdb_store(db, key, data, TDB_REPLACE) != 0) { fatal("tdb_store failed"); } if (data.dptr) free(data.dptr); tdb_chainunlock(db, lockkey); goto next; } #endif#if TRAVERSE_PROB if (random() % TRAVERSE_PROB == 0) { tdb_traverse(db, cull_traverse, NULL); goto next; }#endif data = tdb_fetch(db, key); if (data.dptr) free(data.dptr);next: free(k); free(d); free(s);}static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, void *state){ tdb_delete(db, key); return 0;}#ifndef NPROC#define NPROC 6#endif#ifndef NLOOPS#define NLOOPS 200000#endifint main(int argc, char *argv[]){ int i, seed=0; int loops = NLOOPS; pid_t pids[NPROC]; pids[0] = getpid(); for (i=0;i<NPROC-1;i++) { if ((pids[i+1]=fork()) == 0) break; } db = tdb_open("torture.tdb", 2, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0600); if (!db) { fatal("db open failed"); } tdb_logging_function(db, tdb_log); srand(seed + getpid()); srandom(seed + getpid() + time(NULL)); for (i=0;i<loops;i++) addrec_db(); tdb_traverse(db, NULL, NULL); tdb_traverse(db, traverse_fn, NULL); tdb_traverse(db, traverse_fn, NULL); tdb_close(db); if (getpid() == pids[0]) { for (i=0;i<NPROC-1;i++) { int status; if (waitpid(pids[i+1], &status, 0) != pids[i+1]) { printf("failed to wait for %d\n", (int)pids[i+1]); exit(1); } if (WEXITSTATUS(status) != 0) { printf("child %d exited with status %d\n", (int)pids[i+1], WEXITSTATUS(status)); exit(1); } } printf("OK\n"); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -