[PATCH:xscope] Greatly reduce xscope's bss pages

Alan Coopersmith alan.coopersmith at oracle.com
Fri Feb 25 23:28:24 PST 2011


xscope had several static arrays of StaticMaxFD structures, which ended up
in .bss sections.   StaticMaxFD was initialized to FD_SETSIZE.

On 32-bit Solaris, the default value FD_SETSIZE is 1024.
On 64-bit Solaris, the FD_SETSIZE is 64k, due to the SPARCv9 ABI.

One of the structures allocated included the 32k data buffer for each FD.
This resulted in the highly excessive mapping of 2gb of .bss when building
64-bit binaries on Solaris, and 32mb for 32-bit binaries.

After this patch, only 52k of .bss is mapped.
(Actual RSS pages for xscope were barely changed.)

To reduce this, the static tables were replaced with callocs of MaxFD
tables, where MaxFD is now the smaller of StaticMaxFD or the current
fd limit.   StaticMaxFD is reduced by default to 256, since xscope is
rarely used with large numbers of clients (it can be recompiled with a
larger StaticMaxFD when needed).

Additionally, the 32k buffers are allocated only when FD's are opened to
use them, instead of for the maximum possible number of FD's.

Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
---
 common.c   |   16 ++++++++++++++++
 decode11.c |   11 +++--------
 fd.c       |   11 +++--------
 fd.h       |   14 +++++++++-----
 proto.h    |    1 +
 scope.c    |   16 ++++++++++++----
 scope.h    |    4 ++--
 server.c   |    2 +-
 table11.c  |    1 +
 x11.h      |    2 +-
 10 files changed, 49 insertions(+), 29 deletions(-)

diff --git a/common.c b/common.c
index 1d48530..7ac342c 100644
--- a/common.c
+++ b/common.c
@@ -93,6 +93,22 @@ Malloc (long    n)
   return(p);
 }
 
+void *
+CallocPerFD (long    n)
+{
+  void   *p;
+  p = calloc(MaxFD, n);
+  debug(64,(stderr, "%lx = calloc(%d, %ld)\n", (unsigned long) p, MaxFD, n));
+  if (p == NULL)
+    {
+      fprintf(stderr, "failed to allocate %d bytes for %d files\n",
+	      MaxFD * n, MaxFD);
+      panic("cannot continue");
+    }
+  return(p);
+}
+
+
 void 
 Free(void   *p)
 {
diff --git a/decode11.c b/decode11.c
index a9360ff..fb5cb73 100644
--- a/decode11.c
+++ b/decode11.c
@@ -133,19 +133,14 @@ struct QueueHeader
   struct QueueEntry  *Tail;
 };
 
-static struct QueueHeader  ReplyQ[StaticMaxFD];
+static struct QueueHeader  *ReplyQ;
 
 /* ************************************************************ */
 
 void
 InitReplyQ (void)
 {
-  short   i;
-  for (i = 0; i < StaticMaxFD; i++)
-    {
-      ReplyQ[i].Head = NULL;
-      ReplyQ[i].Tail = NULL;
-    }
+  ReplyQ = CallocPerFD(sizeof(struct QueueHeader));
 }
 
 void
@@ -209,7 +204,7 @@ SequencedReplyExpected (
 
   /* find the server associated with this client */
   fd = FDPair(fd);
-  if (fd < 0 || fd >= StaticMaxFD) return;
+  if (fd < 0 || fd >= MaxFD) return;
 
   /* attach the new queue entry to the end of the queue for the Server */
   if (ReplyQ[fd].Tail != NULL)
diff --git a/fd.c b/fd.c
index 5096e70..623e45f 100644
--- a/fd.c
+++ b/fd.c
@@ -84,7 +84,7 @@
 void
 InitializeFD(void)
 {
-  register short  i;
+  int  i;
 
   enterprocedure("InitializeFD");
   /* get the number of file descriptors the system will let us use */
@@ -100,17 +100,12 @@ InitializeFD(void)
   }
   if (MaxFD > StaticMaxFD)
     {
-      fprintf(stderr, "Recompile with larger StaticMaxFD value %d\n", MaxFD);
       MaxFD = StaticMaxFD;
     }
 
   /* allocate space for a File Descriptor (FD) Table */
-  FDD = (struct FDDescriptor *)
-    Malloc ((long)(MaxFD * sizeof (struct FDDescriptor)));
-  if (FDD == NULL) {
-      panic("Can't allocate memory!");
-  }
-  bzero(FDD, (MaxFD * sizeof (struct FDDescriptor)));
+  FDD = CallocPerFD(sizeof (struct FDDescriptor));
+  FDinfo = CallocPerFD(sizeof (struct fdinfo));
 
   /* be sure all fd's are closed and marked not busy */
   for (i = 0; i < MaxFD; i++)
diff --git a/fd.h b/fd.h
index 76a3e6e..a711359 100644
--- a/fd.h
+++ b/fd.h
@@ -78,17 +78,21 @@ struct FDDescriptor
 };
 
 extern struct FDDescriptor *FDD /* array of FD descriptors */ ;
-extern short   MaxFD /* maximum number of FD's possible */ ;
+extern int     MaxFD /* maximum number of FD's possible */ ;
 
-extern short   nFDsInUse /* number of FD's actually in use */ ;
+extern int     nFDsInUse /* number of FD's actually in use */ ;
 
 extern fd_set  ReadDescriptors /* bit map of FD's in use -- for select  */ ;
 extern fd_set  WriteDescriptors /* bit map of write blocked FD's -- for select */;
 extern fd_set  BlockedReadDescriptors /* bit map of FD's blocked from reading */;
-extern short   HighestFD /* highest FD in use -- for select */ ;
+extern int     HighestFD /* highest FD in use -- for select */ ;
 
-/* need to change the MaxFD to allow larger number of fd's */
-#define StaticMaxFD FD_SETSIZE
+/* cap the number of file descriptors to a reasonable size as long as
+   we're preallocating structs for every one
+ */
+#ifndef StaticMaxFD
+# define StaticMaxFD 256
+#endif
 
 extern void InitializeFD(void);
 extern void UsingFD(FD fd, void (*Handler)(int), void (*FlushHandler)(int),
diff --git a/proto.h b/proto.h
index d7dfaec..268e212 100644
--- a/proto.h
+++ b/proto.h
@@ -5,6 +5,7 @@ extern void enterprocedure (char *s);
 extern void warn (char *s);
 extern void panic (char *s);
 extern void *Malloc (long n);
+extern void *CallocPerFD (long n);
 extern void Free (void *p);
 extern void SetSignalHandling (void);
 extern void SetUpConnectionSocket (int iport, void (*connectionFunc) (int));
diff --git a/scope.c b/scope.c
index 6f9df76..17e7061 100644
--- a/scope.c
+++ b/scope.c
@@ -93,12 +93,12 @@ char	TerminateClose = 0;
 int	Interrupt = 0;
 
 struct FDDescriptor *FDD = NULL;
-short MaxFD = 0;
-short nFDsInUse = 0;
+int MaxFD = 0;
+int nFDsInUse = 0;
 fd_set ReadDescriptors;
 fd_set WriteDescriptors;
 fd_set BlockedReadDescriptors;
-short HighestFD;
+int HighestFD;
 
 short	debuglevel = 0;
 short	Verbose = 0;
@@ -933,7 +933,7 @@ SetUpStdin (void)
 */
 
 static long clientNumber = 0;
-struct fdinfo   FDinfo[StaticMaxFD];
+struct fdinfo   *FDinfo;
 
 void
 SetUpPair(
@@ -946,6 +946,8 @@ SetUpPair(
       FDinfo[client].Server = false;
       FDinfo[client].pair = server;
       FDinfo[client].ClientNumber = clientNumber;
+      if (FDinfo[client].buffer == NULL)
+	  FDinfo[client].buffer = Malloc(BUFFER_SIZE);
       FDinfo[client].bufcount = 0;
       FDinfo[client].buflimit = -1;
       FDinfo[client].bufdelivered = 0;
@@ -954,6 +956,8 @@ SetUpPair(
 	  FDinfo[server].Server = true;
 	  FDinfo[server].pair = client;
 	  FDinfo[server].ClientNumber = FDinfo[client].ClientNumber;
+	  if (FDinfo[server].buffer == NULL)
+	      FDinfo[server].buffer = Malloc(BUFFER_SIZE);
 	  FDinfo[server].bufcount = 0;
 	  FDinfo[server].buflimit = -1;
 	  FDinfo[server].bufdelivered = 0;
@@ -973,12 +977,16 @@ ResetPair (
 {
   if (client >= 0)
   {
+    Free(FDinfo[client].buffer);
+    FDinfo[client].buffer = NULL;
     FDinfo[client].bufcount = 0;
     FDinfo[client].buflimit = -1;
     FDinfo[client].bufdelivered = 0;
   }
   if (server >= 0)
   {
+    Free(FDinfo[server].buffer);
+    FDinfo[server].buffer = NULL;
     FDinfo[server].bufcount = 0;
     FDinfo[server].buflimit = -1;
     FDinfo[server].bufdelivered = 0;
diff --git a/scope.h b/scope.h
index d440130..d14cfed 100644
--- a/scope.h
+++ b/scope.h
@@ -109,7 +109,7 @@ struct fdinfo
   Boolean Server;
   long    ClientNumber;
   FD	  pair;
-  unsigned char	  buffer[BUFFER_SIZE];
+  unsigned char	  *buffer;
   int	  bufcount;
   int	  bufstart;
   int	  buflimit;	/* limited writes */
@@ -117,7 +117,7 @@ struct fdinfo
   Boolean writeblocked;
 };
 
-extern struct fdinfo   FDinfo[StaticMaxFD];
+extern struct fdinfo   *FDinfo;
 extern int littleEndian;
 extern char HandleSIGUSR1;
 extern char Leader[];
diff --git a/server.c b/server.c
index e9c1d9e..29691f3 100644
--- a/server.c
+++ b/server.c
@@ -53,7 +53,7 @@
 struct TypeDef  TD[MaxTypes];
 unsigned char    RBf[2];
 unsigned char    SBf[4];
-struct ConnState    CS[StaticMaxFD];
+struct ConnState    *CS;
 
 /* ************************************************************ */
 /*								*/
diff --git a/table11.c b/table11.c
index bfcef73..05d454d 100644
--- a/table11.c
+++ b/table11.c
@@ -107,6 +107,7 @@ static int PrintVISUALTYPE(const unsigned char *buf);
 void
 InitializeX11 (void)
 {
+  CS = CallocPerFD(sizeof(struct ConnState));
   InitReplyQ();
 
   InitBuiltInTypes();
diff --git a/x11.h b/x11.h
index 7303e1d..90f0e33 100644
--- a/x11.h
+++ b/x11.h
@@ -508,7 +508,7 @@ struct ConnState
     long    SequenceNumber;
 };
 
-extern struct ConnState    CS[StaticMaxFD];
+extern struct ConnState    *CS;
 
 typedef struct _Value {
     struct _Value   *next;
-- 
1.7.3.2



More information about the xorg-devel mailing list