From: Art Cancro Date: Tue, 29 Aug 2023 02:02:51 +0000 (-0400) Subject: loadtest.c: multiple threadds X-Git-Tag: v989~27 X-Git-Url: https://code.citadel.org/?a=commitdiff_plain;h=43a301bbfbcffd7c88c5c050af1cc47b2e8c4097;p=citadel.git loadtest.c: multiple threadds --- diff --git a/citadel/server/citadel_defs.h b/citadel/server/citadel_defs.h index 04ab4e7cb..2e306a20e 100644 --- a/citadel/server/citadel_defs.h +++ b/citadel/server/citadel_defs.h @@ -11,8 +11,8 @@ // Suppress these compiler warnings #pragma GCC diagnostic ignored "-Wcast-qual" -// #pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" // this doesn't work on FreeBSD -// #pragma GCC diagnostic ignored "-Wformat-truncation" // nor does this +#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" // this doesn't work on FreeBSD +#pragma GCC diagnostic ignored "-Wformat-truncation" // nor does this #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #include "sysdep.h" diff --git a/citadel/utils/loadtest.c b/citadel/utils/loadtest.c index 0e6356a82..25dfd9e90 100644 --- a/citadel/utils/loadtest.c +++ b/citadel/utils/loadtest.c @@ -19,11 +19,14 @@ #include #include #include +#include #include "../server/citadel_defs.h" #include "../server/server.h" #include "../server/citadel_dirs.h" #include +char ctdldir[PATH_MAX]=CTDLDIR; + char *words[] = { "lorem","ipsum","dolor","sit","amet","consectetuer","adipiscing","elit","integer","in","mi","a","mauris", "ornare","sagittis","suspendisse","potenti","suspendisse","dapibus","dignissim","dolor","nam", @@ -113,7 +116,6 @@ char *words[] = { }; int nwords = sizeof(words) / sizeof(char *); -int serv_sock = (-1); int uds_connectsock(char *sockpath) { int s; @@ -140,7 +142,7 @@ int uds_connectsock(char *sockpath) { // input binary data from socket -void serv_read(char *buf, int bytes) { +void serv_read(int serv_sock, char *buf, int bytes) { int len, rlen; len = 0; @@ -155,7 +157,7 @@ void serv_read(char *buf, int bytes) { // send binary to server -void serv_write(char *buf, int nbytes) { +void serv_write(int serv_sock, char *buf, int nbytes) { int bytes_written = 0; int retval; while (bytes_written < nbytes) { @@ -169,12 +171,12 @@ void serv_write(char *buf, int nbytes) { // input string from socket - implemented in terms of serv_read() -void serv_gets(char *buf) { +void serv_gets(int serv_sock, char *buf) { int i; // Read one character at a time. for (i = 0;; i++) { - serv_read(&buf[i], 1); + serv_read(serv_sock, &buf[i], 1); if (buf[i] == '\n' || i == (SIZ-1)) break; } @@ -182,7 +184,7 @@ void serv_gets(char *buf) { // If we got a long line, discard characters until the newline. if (i == (SIZ-1)) { while (buf[i] != '\n') { - serv_read(&buf[i], 1); + serv_read(serv_sock, &buf[i], 1); } } @@ -192,9 +194,9 @@ void serv_gets(char *buf) { // send line to server - implemented in terms of serv_write() -void serv_puts(char *buf) { - serv_write(buf, strlen(buf)); - serv_write("\n", 1); +void serv_puts(int serv_sock, char *buf) { + serv_write(serv_sock, buf, strlen(buf)); + serv_write(serv_sock, "\n", 1); } @@ -210,7 +212,7 @@ int nrooms = sizeof(random_rooms) / sizeof(char *); char *test_user = "Load Test User"; -void perform_random_thing(void) { +void perform_random_thing(int serv_sock) { int op = random() % 3; char buf[SIZ]; int i; @@ -219,14 +221,14 @@ void perform_random_thing(void) { // Random operation 0 : change rooms if (op == 0) { snprintf(buf, sizeof(buf), "GOTO %s", random_rooms[random() % nrooms]); - serv_puts(buf); - serv_gets(buf); + serv_puts(serv_sock, buf); + serv_gets(serv_sock, buf); } // Random operation 1 : post a message if (op == 1) { - serv_puts("ENT0 1"); - serv_gets(buf); + serv_puts(serv_sock, "ENT0 1"); + serv_gets(serv_sock, buf); if (buf[0] == '4') { bigness = random() % 500; @@ -234,15 +236,15 @@ void perform_random_thing(void) { for (i=0; i 0)); } } -void do_stuff(void) { +void do_stuff(int serv_sock) { int i; char buf[SIZ]; snprintf(buf, sizeof buf, "CREU %s", test_user); - printf("< %s\n", buf); - serv_puts(buf); - serv_gets(buf); - printf("> %s\n", buf); + serv_puts(serv_sock, buf); + serv_gets(serv_sock, buf); snprintf(buf, sizeof buf, "ASUP %s|640k_enough_ne1|0|||6|", test_user); - printf("< %s\n", buf); - serv_puts(buf); - serv_gets(buf); - printf("> %s\n", buf); + serv_puts(serv_sock, buf); + serv_gets(serv_sock, buf); snprintf(buf, sizeof buf, "USER %s", test_user); - printf("< %s\n", buf); - serv_puts(buf); - serv_gets(buf); - printf("> %s\n", buf); + serv_puts(serv_sock, buf); + serv_gets(serv_sock, buf); snprintf(buf, sizeof buf, "PASS 640k_enough_ne1"); - printf("< %s\n", buf); - serv_puts(buf); - serv_gets(buf); - printf("> %s\n", buf); + serv_puts(serv_sock, buf); + serv_gets(serv_sock, buf); for (i=0; i %s\n", buf); + serv_puts(serv_sock, buf); + serv_gets(serv_sock, buf); } snprintf(buf, sizeof(buf), "GOTO %s", random_rooms[0]); - printf("< %s\n", buf); - serv_puts(buf); - serv_gets(buf); - printf("> %s\n", buf); + serv_puts(serv_sock, buf); + serv_gets(serv_sock, buf); + + printf("\033[%d;0H\033[33m%ld\033[0m", 7+serv_sock, serv_sock-3); long ops = 0; while(1) { alarm(30); - perform_random_thing(); - printf(" \033[32mOperations completed: \033[33m%ld\033[0m\r", ++ops); + perform_random_thing(serv_sock); + printf("\033[%d;5H\033[33m%8ld\033[0m", 7+serv_sock, ++ops); fflush(stdout); } } +void *loadtest(void *blah) { + char buf[SIZ]; + int serv_sock; + + serv_sock = uds_connectsock(file_citadel_admin_socket); + serv_gets(serv_sock, buf); + + do_stuff(serv_sock); + + close(serv_sock); +} // Main loop. Do things and have fun. int main(int argc, char **argv) { int a; - char buf[SIZ]; - char ctdldir[PATH_MAX]=CTDLDIR; + int nthreads = 3; + + fprintf(stderr, "\033[2J\033[H" + "\033[44m\033[33m\033[1m \033[K\033[0m\n" + "\033[44m\033[33m\033[1m Load testing utility for Citadel \033[K\033[0m\n" + "\033[44m\033[33m\033[1m Copyright (c) 2023 by citadel.org et al. \033[K\033[0m\n" + "\033[44m\033[33m\033[1m This program is open source software. Use, duplication, or disclosure \033[K\033[0m\n" + "\033[44m\033[33m\033[1m is subject to the terms of the GNU General Public license v3. \033[K\033[0m\n" + "\033[44m\033[33m\033[1m \033[K\033[0m\n"); // Parse command line - while ((a = getopt(argc, argv, "h:")) != EOF) { + while ((a = getopt(argc, argv, "h:n:")) != EOF) { switch (a) { case 'h': strncpy(ctdldir, optarg, sizeof ctdldir); break; + case 'n': + nthreads = atoi(optarg); + break; default: - fprintf(stderr, "loadtest: usage: %s [-h server_dir]\n", argv[0]); + fprintf(stderr, "loadtest: usage: %s [-h server_dir] [-n number_of_threads]\n", argv[0]); return(1); } } - fprintf(stderr, "loadtest: started (pid=%d) connecting to Citadel server with data directory %s\n", - (int) getpid(), - ctdldir - ); - fflush(stderr); - if (chdir(ctdldir) != 0) { fprintf(stderr, "loadtest: %s: %s\n", ctdldir, strerror(errno)); exit(errno); } - serv_sock = uds_connectsock(file_citadel_admin_socket); - serv_gets(buf); - printf("> %s\n", buf); + for (a=0; a<(nthreads-1); ++a) { + pthread_t thread; + pthread_attr_t attr; + int ret = 0; - do_stuff(); + ret = pthread_attr_init(&attr); + ret = pthread_attr_setstacksize(&attr, THREADSTACKSIZE); + ret = pthread_create(&thread, &attr, loadtest, NULL); + if (ret != 0) { + exit(ret); + } - close(serv_sock); + } + loadtest(NULL); return(0); }