From 7876023a26f0908213d5d64d7eeab9054e0a082f Mon Sep 17 00:00:00 2001 From: Michael Hampton Date: Sun, 21 Mar 2004 17:14:46 +0000 Subject: [PATCH] * stress.c: Fixed. Now properly spawns threads and stresses out your favorite Citadel server by simulating large numbers of really active users. (It's configurable on the command line, too, to vary the stress level.) Don't use it against a production system! You've been warned! --- citadel/ChangeLog | 7 +++- citadel/citadel_ipc.c | 3 +- citadel/stress.c | 91 +++++++++++++++++++++++-------------------- 3 files changed, 57 insertions(+), 44 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 1bbe29a23..8f8749044 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,10 @@ $Log$ + Revision 614.89 2004/03/21 17:14:46 error + * stress.c: Fixed. Now properly spawns threads and stresses out your + favorite Citadel server by simulating large numbers of really active + users. (It's configurable on the command line, too, to vary the stress + level.) Don't use it against a production system! You've been warned! + Revision 614.88 2004/03/21 17:13:15 error * configure.ac: Fix for defines for pthreads not being included properly @@ -5559,4 +5565,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import - diff --git a/citadel/citadel_ipc.c b/citadel/citadel_ipc.c index 8e6c45c3d..9de6189f7 100644 --- a/citadel/citadel_ipc.c +++ b/citadel/citadel_ipc.c @@ -2855,8 +2855,9 @@ CtdlIPC* CtdlIPC_new(int argc, char **argv, char *hostbuf, char *portbuf) char cithost[SIZ]; char citport[SIZ]; char sockpath[SIZ]; + CtdlIPC* ipc; - CtdlIPC *ipc = ialloc(CtdlIPC); + ipc = ialloc(CtdlIPC); if (!ipc) { return 0; } diff --git a/citadel/stress.c b/citadel/stress.c index 4fd046191..f602b711d 100644 --- a/citadel/stress.c +++ b/citadel/stress.c @@ -88,13 +88,11 @@ static volatile int count = 0; /* Total count of messages posted */ static volatile int total = 0; /* Total messages to be posted */ static pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t arg_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t output_mutex = PTHREAD_MUTEX_INITIALIZER; static char username[12]; static char password[12]; -static char* hostname = NULL; -static char* portname = NULL; - /* * Mutex for the random number generator * We don't assume that rand_r() is present, so we have to @@ -109,17 +107,6 @@ static pthread_mutex_t rand_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t start_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t start_cond = PTHREAD_COND_INITIALIZER; -/* - * connection died; hang it up - */ -#if 0 -void connection_died(CtdlIPC* ipc, int using_ssl) -{ - CtdlIPC_delete(ipc); - pthread_exit(NULL); -} -#endif - /* * This is the worker thread. It logs in and creates the 1,000 messages @@ -134,31 +121,28 @@ void* worker(void* data) int c; /* Message count */ time_t start, end; /* Timestamps */ struct ctdlipcmessage msg; /* The message we will post */ - int* argc_; - char*** argv_; + int argc_; + char** argv_; + long tmin = LONG_MAX, trun = 0, tmax = LONG_MIN; args = (void*)data; - argc_ = (int*)args[0]; - argv_ = (char***)args[1]; - fprintf(stderr, "Set argc to %x\n", argc_); - fprintf(stderr, "Set argv to %x\n", argv_); + argc_ = (int)args[0]; + argv_ = (char**)args[1]; /* Setup the message we will be posting */ - msg.text = (char*)message; + msg.text = message; msg.anonymous = 0; msg.type = 1; strcpy(msg.recipient, ""); strcpy(msg.subject, "Test message; ignore"); strcpy(msg.author, username); - fprintf(stderr, "Trying to connect to Citadel\n"); pthread_mutex_lock(&arg_mutex); - ipc = CtdlIPC_new(*argc_, *argv_, "", ""); + ipc = CtdlIPC_new(argc_, argv_, NULL, NULL); pthread_mutex_unlock(&arg_mutex); if (!ipc) return NULL; /* oops, something happened... */ - fprintf(stderr, "Trying to login to Citadel\n"); CtdlIPC_chat_recv(ipc, aaa); if (aaa[0] != '2') { fprintf(stderr, "Citadel refused me: %s\n", &aaa[4]); @@ -200,7 +184,9 @@ void* worker(void* data) } /* Wait for the rest of the threads */ + pthread_mutex_lock(&start_mutex); pthread_cond_wait(&start_cond, &start_mutex); + pthread_mutex_unlock(&start_mutex); /* And now the fun begins! Send out a whole shitload of messages */ start = time(NULL); @@ -208,18 +194,35 @@ void* worker(void* data) int rm; char room[7]; struct ctdlipcroom *rret; + struct timeval tv; + long tstart, tend; + gettimeofday(&tv, NULL); + tstart = tv.tv_sec * 1000 + tv.tv_usec / 1000; /* cvt to msec */ /* Select the room to goto */ pthread_mutex_lock(&rand_mutex); /* See Numerical Recipes in C or Knuth vol. 2 ch. 3 */ - rm = (int)(99.0*rand()/(RAND_MAX+1.0)); + rm = (int)(100.0*rand()/(RAND_MAX+1.0)); /* range 0-99 */ pthread_mutex_unlock(&rand_mutex); /* Goto the selected room */ sprintf(room, "test%d", rm); + /* Create the room if not existing. Ignore the return */ + r = CtdlIPCCreateRoom(ipc, 1, room, 0, NULL, 0, aaa); + if (r / 100 != 2 && r != 574) { /* Already exists */ + fprintf(stderr, "Citadel refused room create: %s\n", aaa); + pthread_mutex_lock(&count_mutex); + total -= m - c; + pthread_mutex_unlock(&count_mutex); + CtdlIPC_delete_ptr(&ipc); + return NULL; + } r = CtdlIPCGotoRoom(ipc, room, "", &rret, aaa); if (r / 100 != 2) { fprintf(stderr, "Citadel refused room change: %s\n", aaa); + pthread_mutex_lock(&count_mutex); + total -= m - c; + pthread_mutex_unlock(&count_mutex); CtdlIPC_delete_ptr(&ipc); return NULL; } @@ -228,6 +231,9 @@ void* worker(void* data) r = CtdlIPCPostMessage(ipc, 1, &msg, aaa); if (r / 100 != 4) { fprintf(stderr, "Citadel refused message entry: %s\n", aaa); + pthread_mutex_lock(&count_mutex); + total -= m - c; + pthread_mutex_unlock(&count_mutex); CtdlIPC_delete_ptr(&ipc); return NULL; } @@ -237,16 +243,24 @@ void* worker(void* data) pthread_mutex_lock(&count_mutex); count++; pthread_mutex_unlock(&count_mutex); - if (!(count % 20)) - fprintf(stderr, "%d of %d - %d%% \r", - count, total, - (int)(100 * count / total)); + fprintf(stderr, "%d of %d - %d%% \r", + count, total, + (int)(100 * count / total)); } + gettimeofday(&tv, NULL); + tend = tv.tv_sec * 1000 + tv.tv_usec / 1000; /* cvt to msec */ + tend -= tstart; + if (tend < tmin) tmin = tend; + if (tend > tmax) tmax = tend; + trun += tend; + /* Wait for a while */ sleep(w); } end = time(NULL); - printf("%ld\n", end - start); + pthread_mutex_lock(&output_mutex); + printf("%ld %ld %ld %ld\n", end - start, tmin, trun / c, tmax); + pthread_mutex_unlock(&output_mutex); return (void*)(end - start); } @@ -271,13 +285,11 @@ int shift(int argc, char **argv, int start, int count) int main(int argc, char** argv) { void* data[2]; /* pass args to worker thread */ - pthread_t** threads; /* A shitload of threads */ + pthread_t* threads; /* A shitload of threads */ pthread_attr_t attr; /* Thread attributes (we use defaults) */ int i; /* Counters */ long runtime; /* Run time for each thread */ - setvbuf(stderr, NULL, _IONBF, 0); - /* Read argument list */ for (i = 0; i < argc; i++) { if (!strcmp(argv[i], "-n")) { @@ -300,9 +312,6 @@ int main(int argc, char** argv) data[0] = (void*)argc; /* pass args to worker thread */ data[1] = (void*)argv; /* pass args to worker thread */ - fprintf(stderr, "Set data[0] to %x\n", data[0]); - fprintf(stderr, "Set data[1] to %x\n", data[1]); - fprintf(stderr, "Data is at %x\n", data); /* This is how many total messages will be posted */ total = n * m; @@ -310,14 +319,13 @@ int main(int argc, char** argv) /* Pick a randomized username */ pthread_mutex_lock(&rand_mutex); /* See Numerical Recipes in C or Knuth vol. 2 ch. 3 */ - i = (int)(99.0*rand()/(RAND_MAX+1.0)); + i = (int)(100.0*rand()/(RAND_MAX+1.0)); /* range 0-99 */ pthread_mutex_unlock(&rand_mutex); sprintf(username, "testuser%d", i); strcpy(password, username); - fprintf(stderr, "Allocating threads\n"); /* First, memory for our shitload of threads */ - threads = calloc(n, sizeof(pthread_t*)); + threads = calloc(n, sizeof(pthread_t)); if (!threads) { perror("Not enough memory"); return 1; @@ -329,8 +337,7 @@ int main(int argc, char** argv) /* Then, create some threads */ for (i = 0; i < n; ++i) { - fprintf(stderr, "\rCreating thread %d", i); - pthread_create(threads[i], &attr, worker, (void*)data); + pthread_create(&threads[i], &attr, worker, (void*)data); } fprintf(stderr, "Starting in 10 seconds\r"); @@ -344,7 +351,7 @@ int main(int argc, char** argv) /* Then wait for them to exit */ for (i = 0; i < n; i++) { - pthread_join(*(threads[i]), (void*)&runtime); + pthread_join(threads[i], (void*)&runtime); /* We're ignoring this value for now... TODO */ } fprintf(stderr, "\r \r"); -- 2.39.2