Added a new command line option to citserver "-s" takes a numerical parameter.
authorDave West <davew@uncensored.citadel.org>
Mon, 2 Nov 2009 13:15:52 +0000 (13:15 +0000)
committerDave West <davew@uncensored.citadel.org>
Mon, 2 Nov 2009 13:15:52 +0000 (13:15 +0000)
When this is specified with a number greater than 0 the server will start
almost as normal except it will not start any workers or module related
threads.
Instead it will create the specified number of simulation threads and time
how long it takes for them to be created, create a context, delete the
context and get cleaned up. A message is written to the log stating how long
it took and then the server will exit normally.

This is to help tune the client connection code and thread creation stuff.

citadel/server_main.c
citadel/threads.c
citadel/threads.h

index 5d73d7a523ceb3899839e031bafb80e8c653365f..66093245cb933332acf6f1a2c30c67a9ec41960c 100644 (file)
@@ -121,6 +121,11 @@ int main(int argc, char **argv)
                        running_as_daemon = 1;
                }
 
+               /* run a few stats if -s was specified */
+               else if (!strncmp(argv[a], "-s", 2)) {
+                       statcount = atoi(&argv[a][2]);
+               }
+
                /* -x specifies the desired logging level */
                else if (!strncmp(argv[a], "-x", 2)) {
                        verbosity = atoi(&argv[a][2]);
@@ -155,7 +160,7 @@ int main(int argc, char **argv)
                        CtdlLogPrintf(CTDL_EMERG,       "citserver: usage: "
                                        "citserver "
                                        "[-lLogFacility] "
-                                       "[-d] [-D] "
+                                       "[-d] [-D] [-s]"
                                        " [-tTraceFile]"
                                        " [-xLogLevel] [-hHomeDir]\n");
                        exit(1);
index 9782d05fc005c5bf9a3f0567cb1c32dd5db65e90..aa6636e0aa3c720a2a7d173ed57884a455c4c33e 100644 (file)
@@ -60,6 +60,8 @@
 
 static int num_threads = 0;                    /* Current number of threads */
 static int num_workers = 0;                    /* Current number of worker threads */
+long statcount = 0;            /* are we doing a stats check? */
+static long stats_done = 0;
 
 CtdlThreadNode *CtdlThreadList = NULL;
 CtdlThreadNode *CtdlThreadSchedList = NULL;
@@ -1232,11 +1234,38 @@ void *new_worker_thread(void *arg);
 extern void close_masters (void);
 
 
+void *simulation_worker (void*arg) {
+       struct CitContext *this;
+
+       this = CreateNewContext();
+       this->kill_me = 1;
+       this->state = CON_IDLE;
+       dead_session_purge(1);
+       begin_critical_section(S_SESSION_TABLE);
+       stats_done++;
+       end_critical_section(S_SESSION_TABLE);
+       return NULL;
+}
+
+
+void *simulation_thread (void *arg)
+{
+       long stats = statcount;
+
+       while(stats) {
+               CtdlThreadCreate("Connection simulation worker", CTDLTHREAD_BIGSTACK, simulation_worker, NULL);
+               stats--;
+       }
+       CtdlThreadStopAll();
+       return NULL;
+}
 
 void go_threading(void)
 {
        int i;
        CtdlThreadNode *last_worker;
+       struct timeval start, now, result;
+       double last_duration;
        
        /*
         * Initialise the thread system
@@ -1244,7 +1273,14 @@ void go_threading(void)
        ctdl_thread_internal_init();
 
        /* Second call to module init functions now that threading is up */
-       initialise_modules(1);
+       if (!statcount)
+               initialise_modules(1);
+       else {
+               CtdlLogPrintf(CTDL_EMERG, "Running connection simulation stats\n");
+               gettimeofday(&start, NULL);
+               CtdlThreadCreate("Connection simulation master", CTDLTHREAD_BIGSTACK, simulation_thread, NULL);
+       }
+
 
        /*
         * This thread is now used for garbage collection of other threads in the thread list
@@ -1314,6 +1350,7 @@ void go_threading(void)
                /* FIXME: come up with a better way to dynamically alter the number of threads
                 * based on the system load
                 */
+               if (!statcount) {
 #ifdef NEW_WORKER
                if ((((CtdlThreadGetWorkers() < config.c_max_workers) && (CtdlThreadGetWorkers() <= num_sessions) ) || CtdlThreadGetWorkers() < config.c_min_workers) && (CT->state > CTDL_THREAD_STOP_REQ))
 #else
@@ -1341,7 +1378,8 @@ void go_threading(void)
                        else
                                CtdlLogPrintf (CTDL_WARNING, "Server strangled due to machine load average too high.\n");
                }
-               
+               }
+
                CtdlThreadGC();
 
                if (CtdlThreadGetCount() <= 1) // Shutting down clean up the garbage collector
@@ -1352,7 +1390,7 @@ void go_threading(void)
 #ifdef THREADS_USESIGNALS
                if (CtdlThreadGetCount() && CT->state > CTDL_THREAD_STOP_REQ)
 #else
-               if (CtdlThreadGetCount())
+               if (CtdlThreadGetCount() && !statcount)
 #endif
                        CtdlThreadSleep(1);
        }
@@ -1360,6 +1398,13 @@ void go_threading(void)
         * If the above loop exits we must be shutting down since we obviously have no threads
         */
        ctdl_thread_internal_cleanup();
+
+       if (statcount) {
+               gettimeofday(&now, NULL);
+               timersub(&now, &start, &result);
+               last_duration = (double)result.tv_sec + ((double)result.tv_usec / (double) 1000000);
+               CtdlLogPrintf(CTDL_EMERG, "Simulated %ld connections in %f seconds\n", stats_done, last_duration);
+       }
 }
 
 
index 9efebbbbd8f37546c49f34e299851cb14711d76f..4f4830639fd8d3fb05940521d17283a82cbedc07 100644 (file)
@@ -126,6 +126,7 @@ struct ThreadTSD {
 
 extern double CtdlThreadLoadAvg;
 extern double CtdlThreadWorkerAvg;
+extern long statcount;         /* are we doing a stats check? */
 extern citthread_key_t ThreadKey;
 
 void ctdl_thread_internal_init_tsd(void);