* sysdep.c: worker_thread(): Make scheduling a little more fair to higher
authorMichael Hampton <io_error@uncensored.citadel.org>
Mon, 22 Mar 2004 19:37:29 +0000 (19:37 +0000)
committerMichael Hampton <io_error@uncensored.citadel.org>
Mon, 22 Mar 2004 19:37:29 +0000 (19:37 +0000)
  sessions
* sysdep.c: lprintf(): Enable microsecond display in trace file
* stress.c: worker(): Sleep for random amount of time as per specification

citadel/ChangeLog
citadel/server.h
citadel/stress.c
citadel/sysdep.c
citadel/user_ops.c

index fbf3a91572a75cb119f6a1d5bb7586c73c70201e..6c2a64e8fda34eacf1578d07e6bec6d12dc77daf 100644 (file)
@@ -1,4 +1,10 @@
  $Log$
+ Revision 614.94  2004/03/22 19:37:28  error
+ * sysdep.c: worker_thread(): Make scheduling a little more fair to higher
+   sessions
+ * sysdep.c: lprintf(): Enable microsecond display in trace file
+ * stress.c: worker(): Sleep for random amount of time as per specification
+
  Revision 614.93  2004/03/21 22:51:54  error
  * Fix a few remaining lprintf(9, ...) to lprintf(CTDL_DEBUG, ...)
 
@@ -5580,3 +5586,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
+
index 8c42ec21c95eb35fd08ac4710fde0fef9f53feb2..cc28f21515b24ce0603f1f1fd0533f01a7cb018b 100644 (file)
@@ -156,7 +156,8 @@ typedef struct CitContext t_context;
 /* Values for CitContext.state */
 enum {
        CON_IDLE,               /* This context is doing nothing */
-       CON_EXECUTING           /* This context is bound to a thread */
+       CON_READY,              /* This context is ready-to-run */
+       CON_EXECUTING,          /* This context is bound to a thread */
 };
 
 
index ba141d0b91dabb6848ab021601daf8183cd1e457..90d4951578de3218bf88c9082f8f6fc62d0bee2c 100644 (file)
@@ -196,9 +196,15 @@ void* worker(void* data)
                struct ctdlipcroom *rret;
                struct timeval tv;
                long tstart, tend;
+               int wait;
 
                /* Wait for a while */
-               sleep(w);
+               pthread_mutex_lock(&rand_mutex);
+               /* See Numerical Recipes in C or Knuth vol. 2 ch. 3 */
+               /* Randomize between w/3 to w*3 (yes, it's complicated) */
+               wait = (int)((1.0+2.7*(float)w)*rand()/(RAND_MAX+(float)w/3.0)); /* range 0-99 */
+               pthread_mutex_unlock(&rand_mutex);
+               sleep(wait);
 
                gettimeofday(&tv, NULL);
                tstart = tv.tv_sec * 1000 + tv.tv_usec / 1000; /* cvt to msec */
index 061b9fee7937d751bf09f7cb758645ab9e7bfc35..95fe7068c6476c86a1fa3ec5d244274fc1b74c7a 100644 (file)
@@ -135,18 +135,37 @@ void lprintf(enum LogLevel loglevel, const char *format, ...) {
                 * %03ld to %06ld and remove " / 1000" after tv.tv_usec.
                 */
                if (CC && CC->cs_pid) {
+#if 0
+                       /* Millisecond display */
                        fprintf(stderr,
                                "%04d/%02d/%02d %2d:%02d:%02d.%03ld [%3d] %s",
                                tim->tm_year + 1900, tim->tm_mon + 1,
                                tim->tm_mday, tim->tm_hour, tim->tm_min,
                                tim->tm_sec, (long)tv.tv_usec / 1000,
                                CC->cs_pid, buf);
+#endif
+                       /* Microsecond display */
+                       fprintf(stderr,
+                               "%04d/%02d/%02d %2d:%02d:%02d.%06ld [%3d] %s",
+                               tim->tm_year + 1900, tim->tm_mon + 1,
+                               tim->tm_mday, tim->tm_hour, tim->tm_min,
+                               tim->tm_sec, (long)tv.tv_usec,
+                               CC->cs_pid, buf);
                } else {
+#if 0
+                       /* Millisecond display */
                        fprintf(stderr,
                                "%04d/%02d/%02d %2d:%02d:%02d.%03ld %s",
                                tim->tm_year + 1900, tim->tm_mon + 1,
                                tim->tm_mday, tim->tm_hour, tim->tm_min,
                                tim->tm_sec, (long)tv.tv_usec / 1000, buf);
+#endif
+                       /* Microsecond display */
+                       fprintf(stderr,
+                               "%04d/%02d/%02d %2d:%02d:%02d.%06ld %s",
+                               tim->tm_year + 1900, tim->tm_mon + 1,
+                               tim->tm_mday, tim->tm_hour, tim->tm_min,
+                               tim->tm_sec, (long)tv.tv_usec, buf);
                }
                fflush(stderr);
        }
@@ -980,6 +999,8 @@ void *worker_thread(void *arg) {
        int i;
        char junk;
        int highest;
+       /* This is synchronized below; it helps implement round robin mode */
+       static struct CitContext* next_session = NULL;
        struct CitContext *ptr;
        struct CitContext *bind_me = NULL;
        fd_set readfds;
@@ -1115,7 +1136,16 @@ SETUP_FD:        memcpy(&readfds, &masterfds, sizeof masterfds);
                else {
                        bind_me = NULL;
                        begin_critical_section(S_SESSION_TABLE);
-                       for (ptr = ContextList;
+                       /*
+                        * We start where we left off.  If we get to the end
+                        * we'll start from the beginning again, then give up
+                        * if we still don't find anything.  This ensures
+                        * that all contexts get a more-or-less equal chance
+                        * to run. And yes, I did add a goto to the code. -IO
+                        */
+find_session:          if (next_session == NULL)
+                               next_session = ContextList;
+                       for (ptr = next_session;
                            ( (ptr != NULL) && (bind_me == NULL) );
                            ptr = ptr->next) {
                                if ( (FD_ISSET(ptr->client_socket, &readfds))
@@ -1128,6 +1158,13 @@ SETUP_FD:        memcpy(&readfds, &masterfds, sizeof masterfds);
                                 * letting anyone else touch the context list.
                                 */
                                bind_me->state = CON_EXECUTING;
+                               next_session = bind_me->next;
+                       } else if (next_session == ContextList) {
+                               next_session = NULL;
+                       }
+                       if (bind_me == NULL && next_session != NULL) {
+                               next_session = NULL;
+                               goto find_session;
                        }
 
                        end_critical_section(S_SESSION_TABLE);
index 92f51c2b0aafbbcdaa925f5c07014d790d9158d4..56559a05ef23ef41daa3376ff56b84b151de6999 100644 (file)
@@ -438,6 +438,7 @@ void cmd_user(char *cmdbuf)
        case login_not_found:
                cprintf("%d %s not found.\n", ERROR + NO_SUCH_USER, username);
                return;
+       default:
                cprintf("%d Internal error\n", ERROR + INTERNAL_ERROR);
        }
 }