home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / fonts / server / os / utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-21  |  11.9 KB  |  541 lines

  1. /* $XConsortium: utils.c,v 1.9 92/01/31 17:45:40 eswu Exp $ */
  2. /*
  3.  * misc os utilities
  4.  */
  5. /*
  6.  * Copyright 1990, 1991 Network Computing Devices;
  7.  * Portions Copyright 1987 by Digital Equipment Corporation and the
  8.  * Massachusetts Institute of Technology
  9.  *
  10.  * Permission to use, copy, modify, and distribute this protoype software
  11.  * and its documentation to Members and Affiliates of the MIT X Consortium
  12.  * any purpose and without fee is hereby granted, provided
  13.  * that the above copyright notice appear in all copies and that both that
  14.  * copyright notice and this permission notice appear in supporting
  15.  * documentation, and that the names of Network Computing Devices, Digital or
  16.  * MIT not be used in advertising or publicity pertaining to distribution of
  17.  * the software without specific, written prior permission.
  18.  *
  19.  * NETWORK COMPUTING DEVICES, DIGITAL AND MIT DISCLAIM ALL WARRANTIES WITH
  20.  * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  21.  * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, DIGITAL OR MIT BE
  22.  * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  23.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  24.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  25.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  26.  *
  27.  * $NCDId: @(#)utils.c,v 4.9 1991/07/09 14:08:13 lemke Exp $
  28.  *
  29.  */
  30.  
  31. #include    <stdio.h>
  32. #include    <X11/Xos.h>
  33. #include    "misc.h"
  34. #include    "globals.h"
  35. #include    <signal.h>
  36.  
  37. #ifndef X_NOT_POSIX
  38. #ifdef _POSIX_SOURCE
  39. #include <limits.h>
  40. #else
  41. #define _POSIX_SOURCE
  42. #include <limits.h>
  43. #undef _POSIX_SOURCE
  44. #endif
  45. #endif /* X_NOT_POSIX */
  46. #ifndef PATH_MAX
  47. #include <sys/param.h>
  48. #ifndef PATH_MAX
  49. #ifdef MAXPATHLEN
  50. #define PATH_MAX MAXPATHLEN
  51. #else
  52. #define PATH_MAX 1024
  53. #endif
  54. #endif
  55. #endif /* PATH_MAX */
  56.  
  57. #ifdef SIGNALRETURNSINT
  58. #define SIGVAL int
  59. #else
  60. #define SIGVAL void
  61. #endif
  62.  
  63. extern char *configfilename;
  64. char       *progname;
  65. Bool        CloneSelf;
  66. int         ListenSock = -1;
  67. extern int  ListenPort;
  68.  
  69. SIGVAL
  70. AutoResetServer()
  71. {
  72.  
  73. #ifdef DEBUG
  74.     fprintf(stderr, "got a reset signal\n");
  75. #endif
  76.  
  77.     dispatchException |= DE_RESET;
  78.     isItTimeToYield = TRUE;
  79.  
  80. #ifdef SYSV
  81.     signal(SIGHUP, AutoResetServer);
  82. #endif
  83. }
  84.  
  85. SIGVAL
  86. GiveUp()
  87. {
  88.  
  89. #ifdef DEBUG
  90.     fprintf(stderr, "got a TERM signal\n");
  91. #endif
  92.  
  93.     dispatchException |= DE_TERMINATE;
  94.     isItTimeToYield = TRUE;
  95. }
  96.  
  97. SIGVAL
  98. ServerReconfig()
  99. {
  100.  
  101. #ifdef DEBUG
  102.     fprintf(stderr, "got a re-config signal\n");
  103. #endif
  104.  
  105.     dispatchException |= DE_RECONFIG;
  106.     isItTimeToYield = TRUE;
  107.  
  108. #ifdef SYSV
  109.     signal(SIGUSR1, ServerReconfig);
  110. #endif
  111. }
  112.  
  113. SIGVAL
  114. ServerCacheFlush()
  115. {
  116.  
  117. #ifdef DEBUG
  118.     fprintf(stderr, "got a flush signal\n");
  119. #endif
  120.  
  121.     dispatchException |= DE_FLUSH;
  122.     isItTimeToYield = TRUE;
  123.  
  124. #ifdef SYSV
  125.     signal(SIGUSR2, ServerCacheFlush);
  126. #endif
  127. }
  128.  
  129. long
  130. GetTimeInMillis()
  131. {
  132.     struct timeval tp;
  133.  
  134.     gettimeofday(&tp, 0);
  135.     return ((tp.tv_sec * 1000) + (tp.tv_usec / 1000));
  136. }
  137.  
  138. static void
  139. usage()
  140. {
  141.     fprintf(stderr, "%s: [-cf config-file] [-p tcp_port] [-s server_number]\n", progname);
  142.     exit(-1);
  143. }
  144.  
  145. /* ARGSUSED */
  146. void
  147. ProcessCmdLine(argc, argv)
  148.     int         argc;
  149.     char      **argv;
  150. {
  151.     int         i;
  152.  
  153. #ifdef MEMBUG
  154.     {
  155.     extern pointer MemoryAllocationBase;
  156.  
  157.     if (!MemoryAllocationBase)
  158. #ifndef AIXV3
  159.         MemoryAllocationBase = (pointer) sbrk(0);
  160. #else
  161.         MemoryAllocationBase = (pointer) 0x20000000;
  162. #endif
  163.     }
  164. #endif
  165.  
  166.     progname = argv[0];
  167.     for (i = 1; i < argc; i++) {
  168.     if (!strcmp(argv[i], "-port")) {
  169.         if (argv[i + 1])
  170.         ListenPort = atoi(argv[++i]);
  171.         else
  172.         usage();
  173.     } else if (!strcmp(argv[i], "-ls")) {
  174.         if (argv[i + 1])
  175.         ListenSock = atoi(argv[++i]);
  176.         else
  177.         usage();
  178.     } else if (!strcmp(argv[i], "-cf") || !strcmp(argv[i], "-config")) {
  179.         if (argv[i + 1])
  180.         configfilename = argv[++i];
  181.         else
  182.         usage();
  183.     }
  184. #ifdef MEMBUG
  185.     else if ( strcmp( argv[i], "-alloc") == 0)
  186.     {
  187.         extern unsigned long    MemoryFail;
  188.         if(++i < argc)
  189.             MemoryFail = atoi(argv[i]);
  190.         else
  191.         usage ();
  192.     }
  193.     else if ( strcmp ( argv[i], "validateMemory") == 0)
  194.     {
  195.         extern unsigned long MemoryValidate;
  196.         MemoryValidate = 1;
  197.     }
  198.     else if ( strcmp ( argv[i], "neverFreeMemory") == 0)
  199.     {
  200.         extern unsigned long MemoryNeverFree;
  201.         MemoryNeverFree = 1;
  202.     }
  203. #endif
  204.     else
  205.         usage();
  206.     }
  207. }
  208.  
  209.  
  210. #ifndef SPECIAL_MALLOC
  211.  
  212. unsigned long    Must_have_memory;
  213.  
  214. #ifdef MEMBUG
  215. #define FIRSTMAGIC 0x11aaaa11
  216. #define SECONDMAGIC 0x22aaaa22
  217. #define FREEDMAGIC  0x33aaaa33
  218. #define BLANKMAGIC  0x44aaaa44
  219. #define ALLOCMAGIC  0x55aaaa55
  220. #define MEM_FAIL_SCALE    100000
  221.  
  222. typedef struct _MallocHeader    *MallocHeaderPtr;
  223.  
  224. typedef struct _MallocHeader {
  225.     unsigned long    amount;
  226.     unsigned long    time;
  227.     MallocHeaderPtr    prev;
  228.     MallocHeaderPtr    next;
  229.     unsigned long    magic;
  230. } MallocHeaderRec;
  231.  
  232. typedef struct _MallocTrailer {
  233.     unsigned long    magic;
  234. } MallocTrailerRec, *MallocTrailerPtr;
  235.  
  236. unsigned long    MemoryAllocTime;
  237. unsigned long    MemoryAllocBreakpoint = ~0;
  238. unsigned long    MemoryFreeBreakpoint = ~0;
  239. unsigned long    MemoryActive = 0;
  240. unsigned long    MemoryValidate;
  241. unsigned long    MemoryNeverFree;
  242. unsigned long    MemoryFail;
  243. pointer        MemoryAllocationBase = NULL;
  244.  
  245. static void    CheckNode ();
  246.  
  247. MallocHeaderPtr    MemoryInUse;
  248. MallocHeaderPtr    MemoryFreed;
  249.  
  250. #define request(amount)    ((amount) + sizeof (MallocHeaderRec) + sizeof (MallocTrailerRec))
  251. #define Header(ptr)    ((MallocHeaderPtr) (((char *) ptr) - sizeof (MallocHeaderRec)))
  252. #define Trailer(ptr)    ((MallocTrailerPtr) (((char *) ptr) + Header(ptr)->amount))
  253.  
  254. static unsigned long *
  255. SetupBlock(ptr, amount)
  256.     unsigned long   *ptr;
  257. {
  258.     MallocHeaderPtr    head = (MallocHeaderPtr) ptr;
  259.     MallocTrailerPtr    tail = (MallocTrailerPtr) (((char *) ptr) + amount + sizeof (MallocHeaderRec));
  260.  
  261.     MemoryActive += amount;
  262.     head->magic = FIRSTMAGIC;
  263.     head->amount = amount;
  264.     if (MemoryAllocTime == MemoryAllocBreakpoint)
  265.     head->amount = amount;
  266.     head->time = MemoryAllocTime++;
  267.     head->next = MemoryInUse;
  268.     head->prev = 0;
  269.     if (MemoryInUse)
  270.     MemoryInUse->prev = head;
  271.     MemoryInUse = head;
  272.  
  273.     tail->magic = SECONDMAGIC;
  274.     
  275.     return (unsigned long *)(((char *) ptr) + sizeof (MallocHeaderRec));
  276. }
  277.  
  278. ValidateAllActiveMemory ()
  279. {
  280.     MallocHeaderPtr    head;
  281.     MallocTrailerPtr    tail;
  282.  
  283.     for (head = MemoryInUse; head; head = head->next)
  284.     {
  285.     tail = (MallocTrailerPtr) (((char *) (head + 1)) + head->amount);
  286.         if (head->magic == FREEDMAGIC)
  287.         FatalError("Free data on active list");
  288.         if(head->magic != FIRSTMAGIC || tail->magic != SECONDMAGIC)
  289.         FatalError("Garbage object on active list");
  290.     }
  291.     for (head = MemoryFreed; head; head = head->next)
  292.     {
  293.     tail = (MallocTrailerPtr) (((char *) (head + 1)) + head->amount);
  294.     if (head->magic != FREEDMAGIC || tail->magic != FREEDMAGIC)
  295.         FatalError("Non free data on free list");
  296.     if (!CheckMemoryContents (head, BLANKMAGIC))
  297.         FatalError("Freed data reused");
  298.     }
  299. }
  300.  
  301. FillMemoryContents (head, value)
  302.     MallocHeaderPtr head;
  303.     long        value;
  304. {
  305.     int            count;
  306.     long        *store;
  307.  
  308.     count = head->amount / sizeof (long);
  309.     store = (long *) (head + 1);
  310.     while (count--)
  311.     *store++ = value;
  312. }
  313.  
  314. CheckMemoryContents (head, value)
  315.     MallocHeaderPtr head;
  316.     long        value;
  317. {
  318.     int            count;
  319.     long        *check;
  320.  
  321.     count = head->amount / sizeof (long);
  322.     check = (long *) (head + 1);
  323.     while (count--)
  324.     if (*check++ != value)
  325.         return FALSE;
  326.     return TRUE;
  327. }
  328.  
  329. #endif
  330.  
  331. /* FSalloc -- FS's internal memory allocator.  Why does it return unsigned
  332.  * int * instead of the more common char *?  Well, if you read K&R you'll
  333.  * see they say that alloc must return a pointer "suitable for conversion"
  334.  * to whatever type you really want.  In a full-blown generic allocator
  335.  * there's no way to solve the alignment problems without potentially
  336.  * wasting lots of space.  But we have a more limited problem. We know
  337.  * we're only ever returning pointers to structures which will have to
  338.  * be long word aligned.  So we are making a stronger guarantee.  It might
  339.  * have made sense to make FSalloc return char * to conform with people's
  340.  * expectations of malloc, but this makes lint happier.
  341.  */
  342.  
  343. unsigned long * 
  344. FSalloc (amount)
  345.     unsigned long amount;
  346. {
  347.     char        *malloc();
  348.     register pointer  ptr;
  349.     
  350.     if ((long)amount < 0)
  351.     return (unsigned long *)NULL;
  352.     if (amount == 0)
  353.     amount++;
  354.     /* aligned extra on long word boundary */
  355.     amount = (amount + 3) & ~3;
  356. #ifdef MEMBUG
  357.     if (MemoryValidate)
  358.     ValidateAllActiveMemory ();
  359.     if (!Must_have_memory && MemoryFail &&
  360.     ((random() % MEM_FAIL_SCALE) < MemoryFail))
  361.     return (unsigned long *)NULL;
  362.     if (ptr = (pointer)malloc(request(amount)))
  363.     {
  364.     unsigned long    *ret;
  365.     ret = SetupBlock (ptr, amount);
  366.     FillMemoryContents ((MallocHeaderPtr) ptr, ALLOCMAGIC);
  367.     return ret;
  368.     }
  369. #else
  370.     if (ptr = (pointer)malloc(amount))
  371.     return (unsigned long *)ptr;
  372. #endif
  373.     if (Must_have_memory)
  374.     FatalError("Out of memory");
  375.     return (unsigned long *)NULL;
  376. }
  377.  
  378. /*****************
  379.  * FScalloc
  380.  *****************/
  381.  
  382. unsigned long *
  383. FScalloc (amount)
  384.     unsigned long   amount;
  385. {
  386.     unsigned long   *ret;
  387.  
  388.     ret = FSalloc (amount);
  389.     if (ret)
  390.     bzero ((char *) ret, (int) amount);
  391.     return ret;
  392. }
  393.  
  394. /*****************
  395.  * FSrealloc
  396.  *****************/
  397.  
  398. unsigned long *
  399. FSrealloc (ptr, amount)
  400.     register pointer ptr;
  401.     unsigned long amount;
  402. {
  403.     char *malloc();
  404.     char *realloc();
  405.  
  406. #ifdef MEMBUG
  407.     if (ptr)
  408.     {
  409.         if (MemoryValidate)
  410.         ValidateAllActiveMemory ();
  411.         if ((long)amount <= 0)
  412.         {
  413.         if (!amount)
  414.             FSfree(ptr);
  415.         return (unsigned long *)NULL;
  416.         }
  417.         if (!Must_have_memory && MemoryFail &&
  418.         ((random() % MEM_FAIL_SCALE) < MemoryFail))
  419.         return (unsigned long *)NULL;
  420.         amount = (amount + 3) & ~3;
  421.     CheckNode(ptr);
  422.     ptr = (pointer)realloc((char *) Header (ptr), request(amount));
  423.     if (ptr)
  424.         return SetupBlock (ptr, amount);
  425.     }
  426.     else
  427.     {
  428.     return FSalloc (amount);
  429.     }
  430. #else
  431.     if ((long)amount <= 0)
  432.     {
  433.     if (ptr && !amount)
  434.         free(ptr);
  435.     return (unsigned long *)NULL;
  436.     }
  437.     amount = (amount + 3) & ~3;
  438.     if (ptr)
  439.         ptr = (pointer)realloc((char *)ptr, amount);
  440.     else
  441.     ptr = (pointer)malloc(amount);
  442.     if (ptr)
  443.         return (unsigned long *)ptr;
  444. #endif
  445.     if (Must_have_memory)
  446.     FatalError("Out of memory");
  447.     return (unsigned long *)NULL;
  448. }
  449.                     
  450. /*****************
  451.  *  FSfree
  452.  *    calls free 
  453.  *****************/    
  454.  
  455. void
  456. FSfree(ptr)
  457.     register pointer ptr;
  458. {
  459. #ifdef MEMBUG
  460.     if (MemoryValidate)
  461.     ValidateAllActiveMemory ();
  462.     if (ptr)
  463.     {
  464.     MallocHeaderPtr        head;
  465.     MallocTrailerPtr    trail;
  466.  
  467.     CheckNode(ptr);
  468.     head = Header(ptr);
  469.     trail = Trailer(ptr);
  470.     if (head->time == MemoryFreeBreakpoint)
  471.         head->magic = FIRSTMAGIC;
  472.     head->magic = FREEDMAGIC;
  473.     trail->magic = FREEDMAGIC;
  474.     FillMemoryContents (head, BLANKMAGIC);
  475.     if (MemoryNeverFree)
  476.     {
  477.         head->prev = 0;
  478.         head->next = MemoryFreed;
  479.         MemoryFreed = head;
  480.     }
  481.     else
  482.         free ((char *) head);
  483.     }
  484. #else
  485.     if (ptr)
  486.     free((char *)ptr); 
  487. #endif
  488. }
  489.  
  490. #ifdef MEMBUG
  491. static void
  492. CheckNode(ptr)
  493.     pointer ptr;
  494. {
  495.     MallocHeaderPtr    head;
  496.     MallocHeaderPtr    f, prev;
  497.  
  498.     if (ptr < MemoryAllocationBase)
  499.     FatalError("Trying to free static storage");
  500.     head = Header(ptr);
  501.     if (((pointer) head) < MemoryAllocationBase)
  502.     FatalError("Trying to free static storage");
  503.     if (head->magic == FREEDMAGIC)
  504.     FatalError("Freeing something already freed");
  505.     if(head->magic != FIRSTMAGIC || Trailer(ptr)->magic != SECONDMAGIC)
  506.     FatalError("Freeing a garbage object");
  507.     if(head->prev)
  508.     head->prev->next = head->next;
  509.     else
  510.     MemoryInUse = head->next;
  511.     if (head->next)
  512.     head->next->prev = head->prev;
  513.     MemoryActive -= head->amount;
  514. }
  515.  
  516. DumpMemoryInUse (time)
  517.     unsigned long   time;
  518. {
  519.     MallocHeaderPtr    head;
  520.  
  521.     for (head = MemoryInUse; head; head = head->next)
  522.     if (head->time >= time)
  523.         fprintf (stderr, "0x%08x %5d %6d\n", head,
  524.                     head->amount,
  525.                     head->time);
  526. }
  527.  
  528. static unsigned long    MarkedTime;
  529.  
  530. MarkMemoryTime ()
  531. {
  532.     MarkedTime = MemoryAllocTime;
  533. }
  534.  
  535. DumpMemorySince ()
  536. {
  537.     DumpMemoryInUse (MarkedTime);
  538. }
  539. #endif
  540. #endif /* SPECIAL_MALLOC */
  541.