Author: Bleep <helveytw@home.com>
authorBleep <twhelvey1@home.com>
Wed, 13 Sep 2000 07:55:56 +0000 (07:55 +0000)
committerBleep <twhelvey1@home.com>
Wed, 13 Sep 2000 07:55:56 +0000 (07:55 +0000)
Log message:
Put clients, slinks, and memberships in free lists

git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@285 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
ircd/channel.c
ircd/ircd.c
ircd/list.c
ircd/s_bsd.c

index df8951c72ee4cd99a6a3c5fb4beb8c9a21f9e42a..b3bf71fc11ec2e9648e5df8d3c3561c8ecc24e69 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2000-09-13  Thomas Helvey <helveytw@home.com>
+       * ircd/list.c: put Clients in free lists, pre-allocate MAXCONNECTIONS
+       local clients.
+       * ircd/list.c: put SLinks in free lists
+       * ircd/channel.c: put Memberships in free lists
+       * ircd/ircd.c: rearrange initializations a bit in main
+       Note: With these changes, ircd NEVER frees Clients, SLinks or
+       Memberships. It will also rarely need to allocate new
+       ones during net bursts and other disruptions. This should
+       cut down on memory fragmentation a bit as well.
+
 2000-08-30  Kevin L. Mitchell  <klmitch@mit.edu>
 
        * ircd/m_names.c (do_names): pull-up from do_names fix in
 #
 # ChangeLog for ircu2.10.11
 #
-# $Id: ChangeLog,v 1.159 2000-08-30 15:58:53 kev Exp $
+# $Id: ChangeLog,v 1.160 2000-09-13 07:55:55 bleep Exp $
 #
 # Insert new changes at beginning of the change list.
 #
index 76a20e8e1d0cdffec7a931a2182714cd969b47d6..c785dc3723f6bd5d7769b0d82c89be0d0bceca44 100644 (file)
@@ -53,6 +53,9 @@
 
 struct Channel* GlobalChannelList = 0;
 
+static unsigned int membershipAllocCount;
+static struct Membership* membershipFreeList;
+
 static struct SLink *next_overlapped_ban(void);
 static int del_banid(struct Channel *, char *, int);
 void del_invite(struct Client *, struct Channel *);
@@ -530,8 +533,15 @@ void add_user_to_channel(struct Channel* chptr, struct Client* who,
   assert(0 != who);
 
   if (who->user) {
-    struct Membership* member = 
-            (struct Membership*) MyMalloc(sizeof(struct Membership));
+   
+    struct Membership* member = membershipFreeList;
+    if (member)
+      membershipFreeList = member->next_member;
+    else {
+      member = (struct Membership*) MyMalloc(sizeof(struct Membership));
+      ++membershipAllocCount;
+    }
+
     assert(0 != member);
     member->user         = who;
     member->channel      = chptr;
@@ -580,7 +590,9 @@ static int remove_member_from_channel(struct Membership* member)
     member->user->user->channel = member->next_channel;
 
   --member->user->user->joined;
-  MyFree(member);
+
+  member->next_member = membershipFreeList;
+  membershipFreeList = member;
 
   return sub1_from_channel(chptr);
 }
index 8de11424d9f8814f52b3b5a827e23daa40e6f95c..ef4e7f127100d741924c27be8c95574bacff2f2d 100644 (file)
@@ -366,6 +366,8 @@ static time_t check_pings(void) {
 
 /*----------------------------------------------------------------------------
  * parse_command_line
+ * Side Effects: changes GLOBALS me, thisServer, dpath, configfile, debuglevel
+ * debugmode
  *--------------------------------------------------------------------------*/
 static void parse_command_line(int argc, char** argv) {
   const char *options = "d:f:h:ntvx:";
@@ -612,9 +614,6 @@ int main(int argc, char **argv) {
   memset(&me, 0, sizeof(me));
   me.fd = -1;
 
-  setup_signals();
-  initload();
-
   parse_command_line(argc, argv);
 
   if (chdir(dpath)) {
@@ -637,6 +636,15 @@ int main(int argc, char **argv) {
     exit(5);
 #endif
 
+  debug_init(thisServer.bootopt & BOOT_TTY);
+  daemon_init(thisServer.bootopt & BOOT_TTY);
+
+  setup_signals();
+  open_log(*argv);
+
+  set_nomem_handler(outofmemory);
+
+  initload();
   init_list();
   hash_init();
   initclass();
@@ -644,22 +652,15 @@ int main(int argc, char **argv) {
   initmsgtree();
   initstats();
 
-  debug_init(thisServer.bootopt & BOOT_TTY);
-  daemon_init(thisServer.bootopt & BOOT_TTY);
-
-  set_nomem_handler(outofmemory);
   init_resolver();
 
-  open_log(*argv);
-
   if (!conf_init()) {
-    Debug((DEBUG_FATAL, "Failed to read configuration file %s", configfile));
-    printf("Couldn't open configuration file %s\n", configfile);
+    ircd_log(L_CRIT, "Failed to read configuration file %s", configfile);
     exit(6);
   }
 
   if (!init_server_identity()) {
-    Debug((DEBUG_FATAL, "Failed to initialize server identity"));
+    ircd_log(L_CRIT, "Failed to initialize server identity");
     exit(7);
   }
 
@@ -669,9 +670,9 @@ int main(int argc, char **argv) {
   rmotd       = read_motd(RPATH);
   motd        = read_motd(MPATH);
   CurrentTime = time(NULL);
-  me.from     = &me;
 
   SetMe(&me);
+  me.from = &me;
   make_server(&me);
 
   me.serv->timestamp = TStime();  /* Abuse own link timestamp as start TS */
index af65ddeb5e2e7b4549aca0d315eb3dd405286ba9..aaee36113140dfd2dd34e672c94b4e9645d16605 100644 (file)
@@ -53,8 +53,29 @@ static struct liststats {
 } cloc, crem, users, servs, links, classs;
 #endif
 
+static unsigned int localClientAllocCount;
+static struct Client* localClientFreeList;
+
+static unsigned int remoteClientAllocCount;
+static struct Client* remoteClientFreeList;
+
+static unsigned int slinkAllocCount;
+static struct SLink* slinkFreeList;
+
 void init_list(void)
 {
+  struct Client* cptr;
+  int i;
+  /*
+   * pre-allocate MAXCONNECTIONS local clients
+   */
+  for (i = 0; i < MAXCONNECTIONS; ++i) {
+    cptr = (struct Client*) MyMalloc(CLIENT_LOCAL_SIZE);
+    cptr->next = localClientFreeList;
+    localClientFreeList = cptr;
+    ++localClientAllocCount;
+  }
+
 #ifdef DEBUGMODE
   memset(&cloc, 0, sizeof(cloc));
   memset(&crem, 0, sizeof(crem));
@@ -76,38 +97,45 @@ void init_list(void)
  */
 struct Client* make_client(struct Client *from, int status)
 {
-  struct Client *cptr = NULL;
-  size_t size = CLIENT_REMOTE_SIZE;
-
+  struct Client* cptr = 0;
   /*
    * Check freelists first to see if we can grab a client without
    * having to call malloc.
    */
-  if (!from)
-    size = CLIENT_LOCAL_SIZE;
-
-  cptr = (struct Client*) MyMalloc(size);
-  assert(0 != cptr);
-  /*
-   * NOTE: Do not remove this, a lot of code depends on the entire
-   * structure being zeroed out
-   */
-  memset(cptr, 0, size);        /* All variables are 0 by default */
-
-#ifdef  DEBUGMODE
-  if (size == CLIENT_LOCAL_SIZE)
-    cloc.inuse++;
-  else
-    crem.inuse++;
-#endif
-
-  /* Note: structure is zero (memset) */
-  cptr->from = from ? from : cptr;      /* 'from' of local client is self! */
-  cptr->status = status;
-  cptr->hnext = cptr;
-  strcpy(cptr->username, "unknown");
-
-  if (CLIENT_LOCAL_SIZE == size) {
+  if (from) {
+    /*
+     * remote client
+     */
+    if ((cptr = remoteClientFreeList))
+      remoteClientFreeList = cptr->next;
+    else {
+      cptr = (struct Client*) MyMalloc(CLIENT_REMOTE_SIZE);
+      ++remoteClientAllocCount;
+    }
+    assert(0 != cptr);
+    /*
+     * NOTE: Do not remove this, a lot of code depends on the entire
+     * structure being zeroed out
+     */
+    memset(cptr, 0, CLIENT_REMOTE_SIZE);        /* All variables are 0 by default */
+    cptr->from = from;
+  }
+  else {
+    /*
+     * local client
+     */
+    if ((cptr = localClientFreeList))
+      localClientFreeList = cptr->next;
+    else {
+      cptr = (struct Client*) MyMalloc(CLIENT_LOCAL_SIZE);
+      ++localClientAllocCount;
+    }
+    assert(0 != cptr);
+    /*
+     * NOTE: Do not remove this, a lot of code depends on the entire
+     * structure being zeroed out
+     */
+    memset(cptr, 0, CLIENT_LOCAL_SIZE);        /* All variables are 0 by default */
     cptr->fd = -1;
     cptr->local = 1;
     cptr->since = cptr->lasttime = cptr->firsttime = CurrentTime;
@@ -115,13 +143,39 @@ struct Client* make_client(struct Client *from, int status)
     cptr->nextnick = CurrentTime - NICK_DELAY;
     cptr->nexttarget = CurrentTime - (TARGET_DELAY * (STARTTARGETS - 1));
     cptr->handler = UNREGISTERED_HANDLER;
+    cptr->from = cptr;      /* 'from' of local client is self! */
   }
+  cptr->status = status;
+  cptr->hnext = cptr;
+  strcpy(cptr->username, "unknown");
+
+#ifdef  DEBUGMODE
+  if (from)
+    crem.inuse++;
+  else
+    cloc.inuse++;
+#endif
+
   return cptr;
 }
 
-void free_client(struct Client *cptr)
+void free_client(struct Clientcptr)
 {
-  if (cptr && cptr->local) {
+  if (!cptr)
+    return;
+  /*
+   * forget to remove the client from the hash table?
+   */
+  assert(cptr->hnext == cptr);
+
+#ifdef  DEBUGMODE
+  if (cptr->local)
+    --cloc.inuse;
+  else
+    --crem.inuse;
+#endif
+
+  if (cptr->local) {
     /*
      * make sure we have cleaned up local resources
      */
@@ -135,13 +189,13 @@ void free_client(struct Client *cptr)
     DBufClear(&cptr->recvQ);
     if (cptr->listener)
       release_listener(cptr->listener);
+    cptr->next = localClientFreeList;
+    localClientFreeList = cptr;
   }    
-  /*
-   * forget to remove the client from the hash table?
-   */
-  assert(cptr->hnext == cptr);
-
-  MyFree(cptr);
+  else {
+    cptr->next = remoteClientFreeList;
+    remoteClientFreeList = cptr;
+  }
 }
 
 struct Server *make_server(struct Client *cptr)
@@ -203,12 +257,6 @@ void remove_client_from_list(struct Client *cptr)
     --servs.inuse;
 #endif
   }
-#ifdef  DEBUGMODE
-  if (cptr->local)
-    --cloc.inuse;
-  else
-    --crem.inuse;
-#endif
   free_client(cptr);
 }
 
@@ -237,21 +285,25 @@ void add_client_to_list(struct Client *cptr)
  */
 struct SLink *find_user_link(struct SLink *lp, struct Client *ptr)
 {
-  if (ptr)
-    while (lp)
-    {
+  if (ptr) {
+    while (lp) {
       if (lp->value.cptr == ptr)
         return (lp);
       lp = lp->next;
     }
+  }
   return NULL;
 }
 
-struct SLink *make_link(void)
+struct SLinkmake_link(void)
 {
-  struct SLink *lp;
-
-  lp = (struct SLink*) MyMalloc(sizeof(struct SLink));
+  struct SLink* lp = slinkFreeList;
+  if (lp)
+    slinkFreeList = lp->next;
+  else {
+    lp = (struct SLink*) MyMalloc(sizeof(struct SLink));
+    ++slinkAllocCount;
+  }
   assert(0 != lp);
 #ifdef  DEBUGMODE
   links.inuse++;
@@ -259,9 +311,12 @@ struct SLink *make_link(void)
   return lp;
 }
 
-void free_link(struct SLink *lp)
+void free_link(struct SLinklp)
 {
-  MyFree(lp);
+  if (lp) {
+    lp->next = slinkFreeList;
+    slinkFreeList = lp;
+  }
 #ifdef  DEBUGMODE
   links.inuse--;
 #endif
index f5c8aebe167dbb6d4670d49b673f6bb1a21ed0d0..64a251f8ca87e2a18409bfca7aa8eb64857a1588 100644 (file)
@@ -345,6 +345,10 @@ unsigned int deliver_it(struct Client *cptr, const char *str, unsigned int len)
       me.sendK += (me.sendB >> 10);
       me.sendB &= 0x03ff;
     }
+    /*
+     * XXX - hrmm.. set blocked here? the socket didn't
+     * say it was blocked
+     */
     if (bytes_written < len)
       cptr->flags |= FLAGS_BLOCKED;
     break;