+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.
#
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 *);
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;
member->user->user->channel = member->next_channel;
--member->user->user->joined;
- MyFree(member);
+
+ member->next_member = membershipFreeList;
+ membershipFreeList = member;
return sub1_from_channel(chptr);
}
/*----------------------------------------------------------------------------
* 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:";
memset(&me, 0, sizeof(me));
me.fd = -1;
- setup_signals();
- initload();
-
parse_command_line(argc, argv);
if (chdir(dpath)) {
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();
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);
}
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 */
} 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));
*/
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;
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 Client* cptr)
{
- 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
*/
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)
--servs.inuse;
#endif
}
-#ifdef DEBUGMODE
- if (cptr->local)
- --cloc.inuse;
- else
- --crem.inuse;
-#endif
free_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 SLink* make_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++;
return lp;
}
-void free_link(struct SLink *lp)
+void free_link(struct SLink* lp)
{
- MyFree(lp);
+ if (lp) {
+ lp->next = slinkFreeList;
+ slinkFreeList = lp;
+ }
#ifdef DEBUGMODE
links.inuse--;
#endif