home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / clib / progs / haswinlib / c / malloc < prev    next >
Encoding:
Text File  |  1991-02-04  |  14.6 KB  |  443 lines

  1. /* > $.CLIB.C.malloc
  2.  *
  3.  *      HASWIN Graphics Library
  4.  *     =========================
  5.  *
  6.  *      Copyright (C) H.A.Shaw 1990.
  7.  *              Howard A. Shaw.
  8.  *              The Unit for Space Sciences,
  9.  *              Room 165,
  10.  *              Physics Building,
  11.  *              University of Kent at Canterbury.
  12.  *              Canterbury.
  13.  *              Kent.  CT2 7NJ
  14.  *      You may use and distribute this code freely, however please leave
  15.  *      it alone.  If you find bugs (and there will be many) please contact
  16.  *      me and the master source can be modified.  If you keep me informed
  17.  *      of who you give copies of this to then I can get release upgrades
  18.  *      to them.
  19.  *
  20.  *      memory managment routines.
  21.  */
  22. #include "includes.h"
  23.  
  24. int haswin_getprogramtop(void) {
  25.         return(haswin_programtop);
  26. }
  27.  
  28. int haswin_getthisslotsize(void) {
  29.  
  30.         _kernel_swi_regs        regs, ans;
  31.  
  32.         regs.r[0] = -1;
  33.         regs.r[1] = -1;
  34.         if (_kernel_swi(SWI_X|HASWIN_Slot_size, ®s, &ans) != 0) {
  35.                 return(HASWIN_FALSE);
  36.         }
  37.         return(ans.r[0]);
  38. }
  39.  
  40. int haswin_getnextslotsize(void) {
  41.  
  42.         _kernel_swi_regs        regs, ans;
  43.  
  44.         regs.r[0] = -1;
  45.         regs.r[1] = -1;
  46.         if (_kernel_swi(SWI_X|HASWIN_Slot_size, ®s, &ans) != 0) {
  47.                 return(HASWIN_FALSE);
  48.         }
  49.         return(ans.r[1]);
  50. }
  51.  
  52. int haswin_getfreespacesize(void) {
  53.  
  54.         _kernel_swi_regs        regs, ans;
  55.  
  56.         regs.r[0] = -1;
  57.         regs.r[1] = -1;
  58.         if (_kernel_swi(SWI_X|HASWIN_Slot_size, ®s, &ans) != 0) {
  59.                 return(HASWIN_FALSE);
  60.         }
  61.         return(ans.r[2]);
  62. }
  63.  
  64. #ifdef DEBUG
  65. static FILE *mallocmsg = 0;
  66. #endif
  67.  
  68. /*
  69.  *      HASWIN impliments a simple heap above the program workspace if
  70.  *      required to do so by a call to "haswin_initialiseuserheap()".
  71.  *      The heap is kept in memory above the program workspace, obtained
  72.  *      by calls to HASWIN_Slot_size.
  73.  *      All the usual calls are provided, namely:
  74.  *              haswin_usermalloc()
  75.  *              haswin_userrealloc()
  76.  *              haswin_userfree()
  77.  *
  78.  *      The reason that the DEBUG bits are in here is that this bit was a
  79.  *      real pain to get working.
  80.  */
  81. static int haswin_userheap = 0;
  82. static int haswin_heapsize = 0;
  83.  
  84. int haswin_getuserheapsize() {
  85.         return(haswin_heapsize);
  86. }
  87.  
  88. /*
  89.  *      Resize the user heap.  If no heap exists then create it from
  90.  *      scratch.
  91.  *      We try to get enough room above haswin_programtop for the
  92.  *      heap by using Slot_size.  We return the actual amount of heap
  93.  *      allocated, or HASWIN_FALSE if an error occoured.  For ease of
  94.  *      expansion we round the allocacted memory up to the next page.
  95.  */
  96. int haswin_initialiseuserheap(int needed) {
  97.  
  98.         _kernel_swi_regs        regs, ans;
  99.         int                     pagesize, size, totalsize;
  100.  
  101.         if (needed < 0)
  102.                 return(HASWIN_FALSE);
  103.         /*
  104.          *      get the machine page size.
  105.          */
  106.         haswin_swi(OS_Read_mem_map_info, ®s);
  107.         pagesize = regs.r[0];
  108.         /* totalsize is the total program memory size rounded to the next
  109.            memory page */
  110.         totalsize = (needed+haswin_getprogramtop()) / pagesize;
  111.         totalsize = (totalsize+1) * pagesize;
  112.         size = totalsize - haswin_getprogramtop();
  113.         if (haswin_userheap) {
  114.                 if (haswin_heapsize == size)
  115.                         return(size);
  116.                 if (size < haswin_heapsize) {
  117.                         /* heap going down, we hope! */
  118.                         regs.r[0] = 5;
  119.                         regs.r[1] = haswin_userheap;
  120.                         regs.r[3] = size - haswin_heapsize;
  121.                         /* direct call to stop error trap in haswin_swi() */
  122.                         if (_kernel_swi(SWI_X|OS_Heap, ®s, &ans) != 0) {
  123.                                 return(HASWIN_FALSE);
  124.                         }
  125.                         /* reduction OK, continue */
  126.                         haswin_heapsize = size;
  127.                 }
  128.         }
  129.         /* change the slot size.  We might not get all we wanted so check
  130.            the amount we actually got and continue.                        */
  131.         regs.r[0] = totalsize;
  132.         regs.r[1] = -1;
  133.         if (_kernel_swi(SWI_X|HASWIN_Slot_size, ®s, &ans) != 0) {
  134.                 return(HASWIN_FALSE);
  135.         }
  136.         size = haswin_getthisslotsize() - haswin_getprogramtop();
  137.         if (haswin_userheap) {
  138.                 if (size > haswin_heapsize) {
  139.                         /* heap going up, hope we have room! */
  140.                         regs.r[0] = 5;
  141.                         regs.r[1] = haswin_userheap;
  142.                         regs.r[3] = size - haswin_heapsize;
  143.                         /* direct call to stop error trap in haswin_swi() */
  144.                         if (_kernel_swi(SWI_X|OS_Heap, ®s, &ans) != 0) {
  145.                                 return(HASWIN_FALSE);
  146.                         }
  147.                         /* OK, continue */
  148.                         haswin_heapsize = size;
  149.                 }
  150.                 return(size);
  151.         }
  152.         /* heap is new, hope we have room! */
  153.         haswin_userheap = haswin_getprogramtop();
  154.         regs.r[0] = 0;
  155.         regs.r[1] = haswin_userheap;
  156.         regs.r[3] = size;
  157.         /* direct call to stop error trap in haswin_swi() */
  158.         if (_kernel_swi(SWI_X|OS_Heap, ®s, &ans) != 0) {
  159.                 return(HASWIN_FALSE);
  160.         }
  161.         /* OK, continue */
  162.         haswin_heapsize = size;
  163.         return(size);
  164. }
  165.  
  166. void *haswin_usermalloc(size_t size, char *routine, char *msg) {
  167.  
  168.         _kernel_swi_regs        regs;
  169.  
  170.         if (!haswin_userheap) {
  171.                 if ((routine) && (msg)) {
  172.                         haswin_errorprintf("haswin_usermalloc:%s: cannot allocate %d bytes for %s from user heap - not initialised", routine, size, msg);
  173. #ifdef DEBUG
  174.                         fprintf(mallocmsg, "%s\n", haswintemp);
  175. #endif
  176.                         haswin_exit(1);
  177.                 } else {
  178. #ifdef DEBUG
  179.                         fprintf(mallocmsg, "haswin_usermalloc(%d) - heap not initialised before use\n", size);
  180. #endif
  181.                         return(0);
  182.                 }
  183.         }
  184.         if ((int)size <= 0)
  185.                 size = 1;
  186.         regs.r[0] = 2;
  187.         regs.r[1] = (int)haswin_userheap;
  188.         regs.r[3] = size;
  189.         if (!haswin_swi(OS_Heap, ®s)) {
  190.                 if ((routine) && (msg)) {
  191.                         haswin_errorprintf("haswin_usermalloc:%s: cannot allocate %d bytes for %s from user heap - failed", routine, size, msg);
  192. #ifdef DEBUG
  193.                         fprintf(mallocmsg, "%s\n", haswintemp);
  194. #endif
  195.                         haswin_exit(1);
  196.                 } else {
  197. #ifdef DEBUG
  198.                         fprintf(mallocmsg, "haswin_usermalloc(%d) - failed\n", size);
  199. #endif
  200.                         return(0);
  201.                 }
  202.         }
  203. #ifdef DEBUG
  204.         fprintf(mallocmsg, "haswin_usermalloc(%d): %s: '%s'.  ptr=%8.8X\n", size, routine, msg, regs.r[2]);
  205. #endif
  206.         if ((routine == 0) || (msg == 0))
  207.                 return((void *)regs.r[2]);
  208.         if (regs.r[2] == 0) {
  209.                 if ((routine) && (msg)) {
  210.                         haswin_errorprintf("haswin_usermalloc:%s: cannot allocate %d bytes for %s from user heap", routine, size, msg);
  211. #ifdef DEBUG
  212.                         fprintf(mallocmsg, "%s\n", haswintemp);
  213. #endif
  214.                         haswin_exit(1);
  215.                 } else {
  216. #ifdef DEBUG
  217.                         fprintf(mallocmsg, "haswin_usermalloc(%d) - cannot allocate\n", size);
  218. #endif
  219.                         return(0);
  220.                 }
  221.         }
  222.         return((void *)regs.r[2]);
  223. }
  224.  
  225. void *haswin_userrealloc(void *optr, size_t size, char *routine, char *msg) {
  226.  
  227.         _kernel_swi_regs        regs;
  228.  
  229.         if (!haswin_userheap) {
  230. #ifdef DEBUG
  231.                 fprintf(mallocmsg, "haswin_userrealloc(%d): %s: '%s'. - heap not initialised before use\n", size, routine, msg);
  232. #endif
  233.                 haswin_errorprintf("haswin_userrealloc:%s: cannot re-allocate %d bytes for %s from user heap - not initialised", routine, size, msg);
  234.                 haswin_exit(1);
  235.         }
  236.         if (optr == 0)
  237.                 return(haswin_usermalloc(size, routine, msg));
  238.         if ((int)size <= 0)
  239.                 size = 1;
  240.         regs.r[0] = 6;
  241.         regs.r[1] = (int)haswin_userheap;
  242.         regs.r[2] = (int)optr;
  243.         haswin_swi(OS_Heap, ®s);
  244.         /* now have current block size in regs.r[3] */
  245.         regs.r[0] = 4;
  246.         regs.r[1] = (int)haswin_userheap;
  247.         regs.r[2] = (int)optr;
  248.         regs.r[3] = size - regs.r[3];
  249.         if (!haswin_swi(OS_Heap, ®s)) {                
  250. #ifdef DEBUG
  251.                 fprintf(mallocmsg, "haswin_userrealloc(%d): %s: '%s'. - SWI fails\n", size, routine, msg);
  252. #endif
  253.                 haswin_errorprintf("haswin_userrealloc:%s: cannot re-allocate %d bytes for %s from user heap - failed", routine, size, msg);
  254.                 haswin_exit(1);
  255.         }
  256. #ifdef DEBUG
  257.         fprintf(mallocmsg, "haswin_userrealloc(%8.8p, %d): %s: %s.  ptr=%8.8p\n", optr, size, routine, msg, ptr);
  258. #endif
  259.         if ((routine == 0) || (msg == 0))
  260.                 return((void *)regs.r[2]);
  261.         if (regs.r[2] == 0) {
  262.                 haswin_errorprintf("haswin_userrealloc:%s: cannot re-allocate %d bytes for %s from %8.8p", routine, size, msg, optr);
  263. #ifdef DEBUG
  264.                 fprintf(mallocmsg, "%s\n", haswintemp);
  265. #endif
  266.                 haswin_exit(1);
  267.         }
  268.         return((void *)regs.r[2]);
  269. }
  270.  
  271. int haswin_userfree(void *ptr) {
  272.         _kernel_swi_regs        regs;
  273.  
  274.         if (!ptr)
  275.                 return(HASWIN_TRUE);
  276.         if (!haswin_userheap) {
  277. #ifdef DEBUG
  278.                 fprintf(mallocmsg, "haswin_userfree(%p) - heap not initialised before use\n", ptr);
  279. #endif
  280.                 haswin_errorprintf("haswin_userfree: cannot free %p from user heap - not initialised", ptr);
  281.                 haswin_exit(1);
  282.         }
  283.         regs.r[0] = 3;
  284.         regs.r[1] = (int)haswin_userheap;
  285.         regs.r[2] = (int)ptr;
  286.         if (!haswin_swi(OS_Heap, ®s)) {                
  287. #ifdef DEBUG
  288.                 fprintf(mallocmsg, "haswin_userfree(%d) - SWI fails\n", ptr);
  289. #endif
  290.                 haswin_errorprintf("haswin_userfree cannot free %p from user heap - failed", ptr);
  291.                 haswin_exit(1);
  292.         }
  293. #ifdef DEBUG
  294.         fprintf(mallocmsg, "haswin_userfree: ptr=%8.8p -ok\n", ptr);
  295. #endif
  296.         return(HASWIN_TRUE);
  297. }
  298.  
  299. int haswin_initmemorymanager() {
  300.  
  301. #ifdef DEBUG
  302.         if (!mallocmsg) {
  303.                 if ((mallocmsg=fopen("mallocmsg", "w")) == 0) {
  304.                         haswin_errorbox("haswin_initmemorymanager: cannot open errorfile");
  305.                         return(HASWIN_FALSE);
  306.                 }
  307.         }
  308. #endif
  309.         haswin_flags |= HASWIN_FLAGS_MEMORY;
  310.         return(HASWIN_TRUE);
  311. }
  312.  
  313. int haswin_killmemorymanager() {
  314.  
  315.         haswin_flags &= ~HASWIN_FLAGS_MEMORY;
  316. #ifdef DEBUG
  317.         if (mallocmsg)
  318.                 fclose(mallocmsg);
  319. #endif
  320.         return(HASWIN_TRUE);
  321. }
  322.  
  323. void *haswin_malloc(size_t size, char *routine, char *msg) {
  324.  
  325.         void    *ptr;
  326.  
  327.         if ((int)size <= 0)
  328.                 size = 1;
  329.         ptr = malloc(size);
  330. #ifdef DEBUG
  331.         fprintf(mallocmsg, "haswin_malloc(%d): %s: '%s'.  ptr=%8.8p\n", size, routine, msg, ptr);
  332. #endif
  333.         if ((routine == 0) || (msg == 0))
  334.                 return(ptr);
  335.         if (!ptr) {
  336.                 haswin_errorprintf("haswin_malloc:%s: cannot allocate %d bytes for %s", routine, size, msg);
  337. #ifdef DEBUG
  338.                 fprintf(mallocmsg, "%s\n", haswintemp);
  339. #endif
  340.                 haswin_exit(1);
  341.         }
  342.         return(ptr);
  343. }
  344.  
  345. void *haswin_realloc(void *optr, size_t size, char *routine, char *msg) {
  346.  
  347.         void    *ptr;
  348.  
  349.         if (optr == 0)
  350.                 return(haswin_malloc(size, routine, msg));
  351.         if ((routine) && (msg) && (!haswin_validpointer(optr))) {
  352.                 haswin_errorprintf("haswin_realloc:%s: cannot re-allocate %d bytes for %s from %8.8p, invalid", routine, size, msg, optr);
  353. #ifdef DEBUG
  354.                 fprintf(mallocmsg, "%s\n", haswintemp);
  355. #endif
  356.                 haswin_exit(1);
  357.         }
  358.         if ((int)size <= 0)
  359.                 size = 1;
  360.         ptr = realloc(optr, size);
  361. #ifdef DEBUG
  362.         fprintf(mallocmsg, "haswin_realloc(%8.8p, %d): %s: %s.  ptr=%8.8p\n", optr, size, routine, msg, ptr);
  363. #endif
  364.         if ((routine == 0) || (msg == 0))
  365.                 return(ptr);
  366.         if (!ptr) {
  367.                 haswin_errorprintf("haswin_realloc:%s: cannot re-allocate %d bytes for %s from %8.8p", routine, size, msg, optr);
  368. #ifdef DEBUG
  369.                 fprintf(mallocmsg, "%s\n", haswintemp);
  370. #endif
  371.                 haswin_exit(1);
  372.         }
  373.         return(ptr);
  374. }
  375.  
  376. int haswin_validpointer(void *ptr) {
  377.  
  378.         if (((int)ptr < 0x0008000) || ((int)ptr > haswin_getprogramtop()))
  379.                 return(HASWIN_FALSE);
  380.         return(HASWIN_TRUE);
  381. }
  382.  
  383. int haswin_free(void *ptr) {
  384.  
  385.         if (haswin_validpointer(ptr)) {
  386.                 free(ptr);
  387. #ifdef DEBUG
  388.                 fprintf(mallocmsg, "haswin_free: ptr=%8.8p -ok\n", ptr);
  389. #endif
  390.                 return(HASWIN_TRUE);
  391.         }
  392. #ifdef DEBUG
  393.         fprintf(mallocmsg, "haswin_free: ptr=%8.8p - fails\n", ptr);
  394. #endif
  395.         return(HASWIN_FALSE);
  396. }
  397.  
  398. /*
  399.  *      note:  we pass haswin_freeptr the ADDRESS of the pointer to the
  400.  *             data to free.  The pointer is cleared to 0 to show that
  401.  *             it no longer points to valid data.
  402.  *      this routine is _haswin_freeptr because a possible bug in the
  403.  *      compiler requires haswin_freeptr to be a #define in <haswin.h>
  404.  *      For the reason for this see <haswin.h>
  405.  */
  406. int _haswin_freeptr(void **ptr) {
  407.  
  408.         if (!haswin_free(*ptr))
  409.                 return(HASWIN_FALSE);
  410.         *ptr = 0;
  411.         return(HASWIN_TRUE);
  412. }
  413.  
  414. /*
  415.  *      create a special memory block.
  416.  *      realloc() is used to create it from the pointer obuf (which may be
  417.  *      zero).  The real buffer is one int longer than required, and the
  418.  *      pointer returned is moved up by one int.  The "missing" int at
  419.  *      ((int *)buf[-1] is the length of the buffer.
  420.  *      This is used as the menu memory allocation routine.
  421.  */
  422. void *haswin_mallocblock(void *obuf, size_t len, char *s1, char *s2) {
  423.         void    *buf;
  424.  
  425.         if (obuf) {
  426.                 /* buffer exists */
  427.                 if (((int *)obuf)[-1] >= len)
  428.                         return(obuf);     /* buffer is large enough */
  429.                 buf = haswin_realloc(&((int *)obuf)[-1], len+sizeof(int), s1, s2);
  430.         } else {
  431.                 /* buffer does not exist */
  432.                 buf=haswin_malloc(len+sizeof(int), s1, s2);
  433.         }
  434.         ((int *)buf)[0] = len;
  435.         return(&((int *)buf)[1]);
  436. }
  437.  
  438. int haswin_freeblock(void *buf) {
  439.  
  440.         return(haswin_free(&((int *)buf)[-1]));
  441. }
  442.  
  443.