home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / TALLOC.C < prev    next >
Text File  |  1996-03-20  |  11KB  |  402 lines

  1. #include "all.h"
  2. char *MemStats(int isw) ;
  3. /*****************************************************************************/
  4. /* Talloc.c                                                               521*/
  5. /*                                                                           */
  6. /* Description:                                                              */
  7. /*   allocate some memory and clear the area.                                */
  8. /*                                                                           */
  9. /* Parameters:                                                               */
  10. /*   size       size of space required.                                      */
  11. /*                                                                           */
  12. /* Return:                                                                   */
  13. /*   void *                                                                  */
  14. /*                                                                           */
  15. /*****************************************************************************/
  16. void *Talloc(UINT size)
  17. {
  18.  void *p;
  19.  
  20. #ifdef __MYMALLOC
  21.  
  22. //MemStats(0);
  23.  p = (char *)MyMalloc(size,SD386_TEMP_CHAIN);
  24.  MemStats(0);
  25.  
  26. #else
  27.  
  28.  p = malloc(size);
  29.  if(p)
  30.   memset(p,0,size);
  31.  
  32. #endif
  33.  
  34.  return(p);
  35. }
  36.  
  37. void *T2alloc(UINT size, int chain)
  38. {
  39.  void *p;
  40.  
  41. #ifdef __MYMALLOC
  42.  
  43. // MemStats(0);
  44.  p = (char *)MyMalloc(size, chain);
  45.  MemStats(0);
  46.  
  47. #else
  48.  
  49.  p = Talloc(size);
  50.  
  51. #endif
  52.  
  53.  return(p);
  54. }
  55.  
  56. /*****************************************************************************/
  57. /*                                                                           */
  58. /*****************************************************************************/
  59. void *Tfree(void *ptr)
  60. {
  61. #ifdef __MYMALLOC
  62.  
  63. // MemStats(0);
  64.  MyFree(ptr);
  65.  MemStats(0);
  66.  
  67. #else
  68.  
  69.  free(ptr);
  70.  
  71. #endif
  72. }
  73.  
  74. /*****************************************************************************/
  75. /* - this function has no counterpart for a compilation that is not using    */
  76. /*   __MYMALLOC. It has been put here to resolve the call to FreeChain       */
  77. /*   in cpydata.c.                                                           */
  78. /*****************************************************************************/
  79. char *FreeChain(int chain)
  80. {
  81. #ifdef __MYMALLOC
  82.  return MyMalloc(0,-chain);
  83. #endif
  84. }
  85.  
  86. #ifdef __MYMALLOC
  87.  
  88. char *memnames[]={
  89.     "PERM_CHAIN",
  90.     "TEMP_CHAIN",
  91.     "CPY_CHAIN",
  92.     "BROWSEM_CHAIN",
  93.     "WINDOW_CHAIN"
  94.     ""
  95.     };
  96.  
  97. typedef struct memheader;
  98. typedef struct memheader *pmemheader;
  99.  
  100. typedef struct {
  101.         char *prev_ptr;
  102.         char *next_ptr;
  103.         int chain;
  104.         int n;
  105.         char marker[8];
  106. } memheader;
  107.  
  108. static char *last_ptr = NULL;
  109. char *ptr, *prev, *next;
  110.  
  111. int   GetChain(char *);
  112.  
  113. char *MyMalloc(int n, int chain)
  114. {
  115. /*Memory is allocated in chains. A chain can be freed with a single call.*/
  116. /* n>=0                                                     */
  117. /* chain >0 => allocate n bytes to chain and return pointer.*/
  118. /* chain <0 => free -chain.                                 */
  119. /* chain =0 => free (char *) n                              */
  120. /* n<0                                                      */
  121. /* chain >0 => move ptrs from chain -n to chain.            */
  122.  
  123.     if(n>=0) {
  124.         if (chain > 0) {
  125.            ptr = (char *) malloc(sizeof(memheader)+n+8);
  126.            if(!ptr) {
  127.                fprintf(stderr,"MyMalloc: %d %d\n",n,chain);
  128.                exit(1);
  129.            }
  130.            ((memheader *) ptr)->prev_ptr = last_ptr;
  131.            ((memheader *) ptr)->next_ptr = NULL;
  132.            if (last_ptr) ((memheader *) last_ptr)->next_ptr = ptr;
  133.            ((memheader *) ptr)->chain = chain;
  134.            ((memheader *) ptr)->n = n;
  135.            last_ptr = ptr;
  136.            strncpy(((memheader *)ptr)->marker,"mbegin12",8);
  137.            ptr += sizeof(memheader);
  138.            strncpy(ptr+n,"mend1234",8);
  139.            memset(ptr,'\0',n);
  140.            return ptr;
  141.         }
  142.         else if (chain < 0) {
  143.            chain  = -chain;
  144.            ptr = last_ptr;
  145.            while (ptr) {
  146.               if (((memheader *) ptr)->chain == chain) {
  147.                  next = ((memheader *) ptr)->next_ptr;
  148.                  prev = ((memheader *) ptr)->prev_ptr;
  149.                  if(prev)((memheader *) prev)->next_ptr = next;
  150.                  if(next)((memheader *) next)->prev_ptr = prev;
  151.                  if(ptr == last_ptr) last_ptr = prev;
  152.                  /*Try to force problems if a block is accessed after it is */
  153.                  /*freed by destroying contents.*/
  154.                  memset(ptr,0xAA,((memheader *)ptr)->n+sizeof(memheader)+8);
  155.                  free(ptr);
  156.                  ptr = prev;
  157.               }
  158.               else {
  159.                  ptr = prev = ((memheader *) ptr)->prev_ptr;
  160.               }
  161.            }
  162.            return NULL;
  163.         }
  164.         else {
  165.            char *delete_ptr;
  166.            int idel=0;
  167.            if(!n) return NULL;
  168.            delete_ptr=(char *)(n-sizeof(memheader));
  169.            ptr = last_ptr;
  170.            while (ptr) {
  171.               if (ptr==delete_ptr) {
  172.                  next = ((memheader *) ptr)->next_ptr;
  173.                  prev = ((memheader *) ptr)->prev_ptr;
  174.                  if(prev)((memheader *) prev)->next_ptr = next;
  175.                  if(next)((memheader *) next)->prev_ptr = prev;
  176.                  if(ptr == last_ptr) last_ptr = prev;
  177.                  /*Try to force problems if a block is accessed after it is */
  178.                  /*freed by destroying contents.*/
  179.                  memset(ptr,0xAA,((memheader *)ptr)->n+sizeof(memheader)+8);
  180.                  free(ptr);
  181.                  ptr = prev;
  182.                  idel=1;
  183.               }
  184.               else {
  185.                  ptr = prev = ((memheader *) ptr)->prev_ptr;
  186.               }
  187.            }
  188.            if(!idel) {
  189.                fprintf(stderr,"MyMalloc: deletion not performed.\006\n");
  190.                return  (char *) 1;
  191.            }
  192.         }
  193.     }
  194.     else if(n<0) { /*move everything from -n to chain*/
  195.        n  = -n;
  196.        ptr = last_ptr;
  197.        while (ptr) {
  198.           if (((memheader *) ptr)->chain == n) {
  199.               ((memheader *) ptr)->chain = chain;
  200.           }
  201.           ptr = ((memheader *) ptr)->prev_ptr;
  202.        }
  203.        return NULL;
  204.    }
  205.    return (char *) 2;
  206.     /* Internal memory management error if both conditions fail */
  207.     /* Messages ?? */
  208. }
  209.  
  210. char *MyStralloc(char *string, int chain) {
  211.     char *ptr=MyMalloc(strlen(string)+1,chain);
  212.     if(ptr) strcpy(ptr,string);
  213.     return ptr;
  214. }
  215.  
  216. char *MyFree(char *ptr) {
  217.     return (ptr?MyMalloc((int)ptr,0):NULL);
  218. }
  219.  
  220.  
  221.  
  222. int CheckPtr(char *ptr, int mode) {
  223.     int idel=0, ierror=0;
  224.     char *delete_ptr=ptr-sizeof(memheader);
  225.  
  226. /*Verify that ptr can be found by traversing the chain.*/
  227.     if(mode & 1) {
  228.         ptr = last_ptr;
  229.         while (ptr) {
  230.            if (ptr==delete_ptr) {
  231.               idel=1;
  232.               break;
  233.            }
  234.            else {
  235.               ptr = ((memheader *) ptr)->prev_ptr;
  236.            }
  237.         }
  238.         if(!idel) {
  239.             fprintf(stderr,"CheckPtr: ptr not found.\006\n");
  240.             ierror|=1;
  241.         }
  242.     }
  243.     if(mode & 2) {
  244.         if(strncmp(((memheader *)ptr)->marker,"mbegin12",8)) {
  245.             fprintf(stderr,"CheckPtr: ptr failed heading string check.\006\n");
  246.             ierror|=2;
  247.         }
  248.         if(strncmp(ptr+((memheader *)ptr)->n+sizeof(memheader),"mend1234",8)) {
  249.             fprintf(stderr,"CheckPtr: ptr failed trailing string check.\006\n");
  250.             ierror|=2;
  251.         }
  252.     }
  253.     if(mode & 4) {
  254.        if(*((int *)(ptr-4))!=(((memheader *)ptr)->n)+sizeof(memheader)+8) {
  255.            ierror|=4;
  256.        }
  257.     }
  258.     return ierror;
  259. }
  260.  
  261. char *MyRealloc(char *ptr, int n, int chain) {
  262.     int oldn;
  263.     char *next, *prev, *new_ptr;
  264.     if(CheckPtr(ptr,4|2|1))
  265.         return (char *) 1;
  266.     if(chain && GetChain(ptr)!=chain)
  267.         return (char *) 2;
  268.     ptr-=sizeof(memheader);
  269.     next = ((memheader *) ptr)->next_ptr;
  270.     prev = ((memheader *) ptr)->prev_ptr;
  271.     oldn=((memheader *)ptr)->n;
  272.     if(oldn>n) {
  273.         memset(ptr+sizeof(memheader)+n+8,0xAA,oldn-n);
  274.     }
  275.     new_ptr=realloc(ptr,n+sizeof(memheader)+8);
  276.     if(!new_ptr) return new_ptr;
  277.     ((memheader *)new_ptr)->n=n;
  278.     strncpy(ptr+sizeof(memheader)+n,"mend1234",8);
  279.     if(oldn<n) {
  280.         memset(new_ptr+sizeof(memheader)+oldn,0x00,n-oldn);
  281.     }
  282.     if(ptr==new_ptr) {
  283.         if(!CheckPtr(new_ptr+sizeof(memheader),4|2|1)) {
  284.             return new_ptr+sizeof(memheader);
  285.         }
  286.         else {
  287.             return NULL;
  288.         }
  289.     }
  290.  
  291.     /*Fixup  linked list.*/
  292.     ((memheader *) new_ptr)->prev_ptr = prev;
  293.     ((memheader *) new_ptr)->next_ptr = next;
  294.     if(prev) {
  295.         ((memheader *) prev)->next_ptr = new_ptr;
  296.     }
  297.     if(next) {
  298.         ((memheader *) next)->prev_ptr = new_ptr;
  299.     }
  300.     if(ptr == last_ptr) last_ptr = new_ptr;
  301.     if(!CheckPtr(new_ptr+sizeof(memheader),4|2|1)) {
  302.         return new_ptr+sizeof(memheader);
  303.     }
  304.     else {
  305.         return NULL;
  306.     }
  307. }
  308.  
  309. /*These next two might as well be macros.*/
  310. int GetChain(char *ptr) {
  311.     return((memheader *)(ptr-sizeof(memheader)))->chain;
  312. }
  313.  
  314. int GetN(char *ptr) {
  315.     return((memheader *)(ptr-sizeof(memheader)))->n;
  316. }
  317.  
  318. char *MyCalloc(int m, int n, int chain) {
  319.     return MyMalloc(m*n,chain);
  320. }
  321.  
  322. size_t MaxStorage (void)
  323.   {
  324.     return 10000000;
  325.     /*This doesn't work.*/
  326.  
  327. #if 0
  328. {
  329.     size_t iMinBytes, iNumBytes, iMaxBytes;
  330.     char *cDummy;
  331.  
  332. }
  333.     iMaxBytes = iMinBytes = 0;
  334.     iMaxBytes --;
  335.     iNumBytes = iMaxBytes / 2;
  336.  
  337.     do
  338.       {
  339.  
  340.         cDummy = (char *)malloc(iNumBytes);
  341.         if (cDummy == NULL)
  342.           {
  343.             iMaxBytes = iNumBytes;
  344.             iNumBytes = (iMaxBytes - iMinBytes) / 2 + iMinBytes;
  345.           }
  346.         else
  347.           {
  348.             free(cDummy);
  349.             iMinBytes = iNumBytes;
  350.             iNumBytes = (iMaxBytes - iMinBytes) / 2 + iMinBytes;
  351.           }
  352.  
  353.       }
  354.     while (iMinBytes + 1 < iMaxBytes);
  355.  
  356.     fflush(stdout);
  357.     return iNumBytes-sizeof(memheader);
  358. #endif
  359.   } /* end of MaxStorage */
  360.  
  361. char *MemStats(int isw) {
  362.     int i, min, max, chain, n;
  363.     struct {
  364.         int num;
  365.         int size;
  366.     } memstats[1000];
  367.     for(i=0;i<1000;++i) {
  368.         memstats[i].num=0;
  369.         memstats[i].size=0;
  370.     }
  371.     max=min=((memheader *)last_ptr)->chain;
  372.  
  373.     ptr=last_ptr;
  374.     while (ptr) {
  375.        chain=((memheader *)ptr)->chain;
  376.        n=((memheader *)ptr)->n;
  377.        if(min>((memheader *)ptr)->chain) {
  378.            min=((memheader *)ptr)->chain;
  379.        }
  380.        if(max<((memheader *)ptr)->chain) {
  381.            max=((memheader *)ptr)->chain;
  382.        }
  383.        if(CheckPtr(ptr,4|2)) {
  384.            return(ptr);
  385.        }
  386.        ++memstats[chain].num;
  387.        memstats[chain].size+=n;
  388.        ptr = prev = ((memheader *) ptr)->prev_ptr;
  389.    }
  390.    if(isw) return NULL;
  391.    printf("MemStats:%5s %5s       %4s %s\n","Chain","Count","Size","Chain Name");
  392.    for(i=min;i<=max;++i) {
  393.        if(memstats[i].num) {
  394.            printf("MemStats:%5d %5d %10d %s\n",
  395.            i,memstats[i].num,memstats[i].size,memnames[i]);
  396.        }
  397.    }
  398.    return NULL;
  399. }
  400.  
  401. #endif
  402.