home *** CD-ROM | disk | FTP | other *** search
- /* > $.CLIB.C.malloc
- *
- * HASWIN Graphics Library
- * =========================
- *
- * Copyright (C) H.A.Shaw 1990.
- * Howard A. Shaw.
- * The Unit for Space Sciences,
- * Room 165,
- * Physics Building,
- * University of Kent at Canterbury.
- * Canterbury.
- * Kent. CT2 7NJ
- * You may use and distribute this code freely, however please leave
- * it alone. If you find bugs (and there will be many) please contact
- * me and the master source can be modified. If you keep me informed
- * of who you give copies of this to then I can get release upgrades
- * to them.
- *
- * memory managment routines.
- */
- #include "includes.h"
-
- int haswin_getprogramtop(void) {
- return(haswin_programtop);
- }
-
- int haswin_getthisslotsize(void) {
-
- _kernel_swi_regs regs, ans;
-
- regs.r[0] = -1;
- regs.r[1] = -1;
- if (_kernel_swi(SWI_X|HASWIN_Slot_size, ®s, &ans) != 0) {
- return(HASWIN_FALSE);
- }
- return(ans.r[0]);
- }
-
- int haswin_getnextslotsize(void) {
-
- _kernel_swi_regs regs, ans;
-
- regs.r[0] = -1;
- regs.r[1] = -1;
- if (_kernel_swi(SWI_X|HASWIN_Slot_size, ®s, &ans) != 0) {
- return(HASWIN_FALSE);
- }
- return(ans.r[1]);
- }
-
- int haswin_getfreespacesize(void) {
-
- _kernel_swi_regs regs, ans;
-
- regs.r[0] = -1;
- regs.r[1] = -1;
- if (_kernel_swi(SWI_X|HASWIN_Slot_size, ®s, &ans) != 0) {
- return(HASWIN_FALSE);
- }
- return(ans.r[2]);
- }
-
- #ifdef DEBUG
- static FILE *mallocmsg = 0;
- #endif
-
- /*
- * HASWIN impliments a simple heap above the program workspace if
- * required to do so by a call to "haswin_initialiseuserheap()".
- * The heap is kept in memory above the program workspace, obtained
- * by calls to HASWIN_Slot_size.
- * All the usual calls are provided, namely:
- * haswin_usermalloc()
- * haswin_userrealloc()
- * haswin_userfree()
- *
- * The reason that the DEBUG bits are in here is that this bit was a
- * real pain to get working.
- */
- static int haswin_userheap = 0;
- static int haswin_heapsize = 0;
-
- int haswin_getuserheapsize() {
- return(haswin_heapsize);
- }
-
- /*
- * Resize the user heap. If no heap exists then create it from
- * scratch.
- * We try to get enough room above haswin_programtop for the
- * heap by using Slot_size. We return the actual amount of heap
- * allocated, or HASWIN_FALSE if an error occoured. For ease of
- * expansion we round the allocacted memory up to the next page.
- */
- int haswin_initialiseuserheap(int needed) {
-
- _kernel_swi_regs regs, ans;
- int pagesize, size, totalsize;
-
- if (needed < 0)
- return(HASWIN_FALSE);
- /*
- * get the machine page size.
- */
- haswin_swi(OS_Read_mem_map_info, ®s);
- pagesize = regs.r[0];
- /* totalsize is the total program memory size rounded to the next
- memory page */
- totalsize = (needed+haswin_getprogramtop()) / pagesize;
- totalsize = (totalsize+1) * pagesize;
- size = totalsize - haswin_getprogramtop();
- if (haswin_userheap) {
- if (haswin_heapsize == size)
- return(size);
- if (size < haswin_heapsize) {
- /* heap going down, we hope! */
- regs.r[0] = 5;
- regs.r[1] = haswin_userheap;
- regs.r[3] = size - haswin_heapsize;
- /* direct call to stop error trap in haswin_swi() */
- if (_kernel_swi(SWI_X|OS_Heap, ®s, &ans) != 0) {
- return(HASWIN_FALSE);
- }
- /* reduction OK, continue */
- haswin_heapsize = size;
- }
- }
- /* change the slot size. We might not get all we wanted so check
- the amount we actually got and continue. */
- regs.r[0] = totalsize;
- regs.r[1] = -1;
- if (_kernel_swi(SWI_X|HASWIN_Slot_size, ®s, &ans) != 0) {
- return(HASWIN_FALSE);
- }
- size = haswin_getthisslotsize() - haswin_getprogramtop();
- if (haswin_userheap) {
- if (size > haswin_heapsize) {
- /* heap going up, hope we have room! */
- regs.r[0] = 5;
- regs.r[1] = haswin_userheap;
- regs.r[3] = size - haswin_heapsize;
- /* direct call to stop error trap in haswin_swi() */
- if (_kernel_swi(SWI_X|OS_Heap, ®s, &ans) != 0) {
- return(HASWIN_FALSE);
- }
- /* OK, continue */
- haswin_heapsize = size;
- }
- return(size);
- }
- /* heap is new, hope we have room! */
- haswin_userheap = haswin_getprogramtop();
- regs.r[0] = 0;
- regs.r[1] = haswin_userheap;
- regs.r[3] = size;
- /* direct call to stop error trap in haswin_swi() */
- if (_kernel_swi(SWI_X|OS_Heap, ®s, &ans) != 0) {
- return(HASWIN_FALSE);
- }
- /* OK, continue */
- haswin_heapsize = size;
- return(size);
- }
-
- void *haswin_usermalloc(size_t size, char *routine, char *msg) {
-
- _kernel_swi_regs regs;
-
- if (!haswin_userheap) {
- if ((routine) && (msg)) {
- haswin_errorprintf("haswin_usermalloc:%s: cannot allocate %d bytes for %s from user heap - not initialised", routine, size, msg);
- #ifdef DEBUG
- fprintf(mallocmsg, "%s\n", haswintemp);
- #endif
- haswin_exit(1);
- } else {
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_usermalloc(%d) - heap not initialised before use\n", size);
- #endif
- return(0);
- }
- }
- if ((int)size <= 0)
- size = 1;
- regs.r[0] = 2;
- regs.r[1] = (int)haswin_userheap;
- regs.r[3] = size;
- if (!haswin_swi(OS_Heap, ®s)) {
- if ((routine) && (msg)) {
- haswin_errorprintf("haswin_usermalloc:%s: cannot allocate %d bytes for %s from user heap - failed", routine, size, msg);
- #ifdef DEBUG
- fprintf(mallocmsg, "%s\n", haswintemp);
- #endif
- haswin_exit(1);
- } else {
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_usermalloc(%d) - failed\n", size);
- #endif
- return(0);
- }
- }
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_usermalloc(%d): %s: '%s'. ptr=%8.8X\n", size, routine, msg, regs.r[2]);
- #endif
- if ((routine == 0) || (msg == 0))
- return((void *)regs.r[2]);
- if (regs.r[2] == 0) {
- if ((routine) && (msg)) {
- haswin_errorprintf("haswin_usermalloc:%s: cannot allocate %d bytes for %s from user heap", routine, size, msg);
- #ifdef DEBUG
- fprintf(mallocmsg, "%s\n", haswintemp);
- #endif
- haswin_exit(1);
- } else {
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_usermalloc(%d) - cannot allocate\n", size);
- #endif
- return(0);
- }
- }
- return((void *)regs.r[2]);
- }
-
- void *haswin_userrealloc(void *optr, size_t size, char *routine, char *msg) {
-
- _kernel_swi_regs regs;
-
- if (!haswin_userheap) {
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_userrealloc(%d): %s: '%s'. - heap not initialised before use\n", size, routine, msg);
- #endif
- haswin_errorprintf("haswin_userrealloc:%s: cannot re-allocate %d bytes for %s from user heap - not initialised", routine, size, msg);
- haswin_exit(1);
- }
- if (optr == 0)
- return(haswin_usermalloc(size, routine, msg));
- if ((int)size <= 0)
- size = 1;
- regs.r[0] = 6;
- regs.r[1] = (int)haswin_userheap;
- regs.r[2] = (int)optr;
- haswin_swi(OS_Heap, ®s);
- /* now have current block size in regs.r[3] */
- regs.r[0] = 4;
- regs.r[1] = (int)haswin_userheap;
- regs.r[2] = (int)optr;
- regs.r[3] = size - regs.r[3];
- if (!haswin_swi(OS_Heap, ®s)) {
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_userrealloc(%d): %s: '%s'. - SWI fails\n", size, routine, msg);
- #endif
- haswin_errorprintf("haswin_userrealloc:%s: cannot re-allocate %d bytes for %s from user heap - failed", routine, size, msg);
- haswin_exit(1);
- }
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_userrealloc(%8.8p, %d): %s: %s. ptr=%8.8p\n", optr, size, routine, msg, ptr);
- #endif
- if ((routine == 0) || (msg == 0))
- return((void *)regs.r[2]);
- if (regs.r[2] == 0) {
- haswin_errorprintf("haswin_userrealloc:%s: cannot re-allocate %d bytes for %s from %8.8p", routine, size, msg, optr);
- #ifdef DEBUG
- fprintf(mallocmsg, "%s\n", haswintemp);
- #endif
- haswin_exit(1);
- }
- return((void *)regs.r[2]);
- }
-
- int haswin_userfree(void *ptr) {
- _kernel_swi_regs regs;
-
- if (!ptr)
- return(HASWIN_TRUE);
- if (!haswin_userheap) {
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_userfree(%p) - heap not initialised before use\n", ptr);
- #endif
- haswin_errorprintf("haswin_userfree: cannot free %p from user heap - not initialised", ptr);
- haswin_exit(1);
- }
- regs.r[0] = 3;
- regs.r[1] = (int)haswin_userheap;
- regs.r[2] = (int)ptr;
- if (!haswin_swi(OS_Heap, ®s)) {
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_userfree(%d) - SWI fails\n", ptr);
- #endif
- haswin_errorprintf("haswin_userfree cannot free %p from user heap - failed", ptr);
- haswin_exit(1);
- }
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_userfree: ptr=%8.8p -ok\n", ptr);
- #endif
- return(HASWIN_TRUE);
- }
-
- int haswin_initmemorymanager() {
-
- #ifdef DEBUG
- if (!mallocmsg) {
- if ((mallocmsg=fopen("mallocmsg", "w")) == 0) {
- haswin_errorbox("haswin_initmemorymanager: cannot open errorfile");
- return(HASWIN_FALSE);
- }
- }
- #endif
- haswin_flags |= HASWIN_FLAGS_MEMORY;
- return(HASWIN_TRUE);
- }
-
- int haswin_killmemorymanager() {
-
- haswin_flags &= ~HASWIN_FLAGS_MEMORY;
- #ifdef DEBUG
- if (mallocmsg)
- fclose(mallocmsg);
- #endif
- return(HASWIN_TRUE);
- }
-
- void *haswin_malloc(size_t size, char *routine, char *msg) {
-
- void *ptr;
-
- if ((int)size <= 0)
- size = 1;
- ptr = malloc(size);
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_malloc(%d): %s: '%s'. ptr=%8.8p\n", size, routine, msg, ptr);
- #endif
- if ((routine == 0) || (msg == 0))
- return(ptr);
- if (!ptr) {
- haswin_errorprintf("haswin_malloc:%s: cannot allocate %d bytes for %s", routine, size, msg);
- #ifdef DEBUG
- fprintf(mallocmsg, "%s\n", haswintemp);
- #endif
- haswin_exit(1);
- }
- return(ptr);
- }
-
- void *haswin_realloc(void *optr, size_t size, char *routine, char *msg) {
-
- void *ptr;
-
- if (optr == 0)
- return(haswin_malloc(size, routine, msg));
- if ((routine) && (msg) && (!haswin_validpointer(optr))) {
- haswin_errorprintf("haswin_realloc:%s: cannot re-allocate %d bytes for %s from %8.8p, invalid", routine, size, msg, optr);
- #ifdef DEBUG
- fprintf(mallocmsg, "%s\n", haswintemp);
- #endif
- haswin_exit(1);
- }
- if ((int)size <= 0)
- size = 1;
- ptr = realloc(optr, size);
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_realloc(%8.8p, %d): %s: %s. ptr=%8.8p\n", optr, size, routine, msg, ptr);
- #endif
- if ((routine == 0) || (msg == 0))
- return(ptr);
- if (!ptr) {
- haswin_errorprintf("haswin_realloc:%s: cannot re-allocate %d bytes for %s from %8.8p", routine, size, msg, optr);
- #ifdef DEBUG
- fprintf(mallocmsg, "%s\n", haswintemp);
- #endif
- haswin_exit(1);
- }
- return(ptr);
- }
-
- int haswin_validpointer(void *ptr) {
-
- if (((int)ptr < 0x0008000) || ((int)ptr > haswin_getprogramtop()))
- return(HASWIN_FALSE);
- return(HASWIN_TRUE);
- }
-
- int haswin_free(void *ptr) {
-
- if (haswin_validpointer(ptr)) {
- free(ptr);
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_free: ptr=%8.8p -ok\n", ptr);
- #endif
- return(HASWIN_TRUE);
- }
- #ifdef DEBUG
- fprintf(mallocmsg, "haswin_free: ptr=%8.8p - fails\n", ptr);
- #endif
- return(HASWIN_FALSE);
- }
-
- /*
- * note: we pass haswin_freeptr the ADDRESS of the pointer to the
- * data to free. The pointer is cleared to 0 to show that
- * it no longer points to valid data.
- * this routine is _haswin_freeptr because a possible bug in the
- * compiler requires haswin_freeptr to be a #define in <haswin.h>
- * For the reason for this see <haswin.h>
- */
- int _haswin_freeptr(void **ptr) {
-
- if (!haswin_free(*ptr))
- return(HASWIN_FALSE);
- *ptr = 0;
- return(HASWIN_TRUE);
- }
-
- /*
- * create a special memory block.
- * realloc() is used to create it from the pointer obuf (which may be
- * zero). The real buffer is one int longer than required, and the
- * pointer returned is moved up by one int. The "missing" int at
- * ((int *)buf[-1] is the length of the buffer.
- * This is used as the menu memory allocation routine.
- */
- void *haswin_mallocblock(void *obuf, size_t len, char *s1, char *s2) {
- void *buf;
-
- if (obuf) {
- /* buffer exists */
- if (((int *)obuf)[-1] >= len)
- return(obuf); /* buffer is large enough */
- buf = haswin_realloc(&((int *)obuf)[-1], len+sizeof(int), s1, s2);
- } else {
- /* buffer does not exist */
- buf=haswin_malloc(len+sizeof(int), s1, s2);
- }
- ((int *)buf)[0] = len;
- return(&((int *)buf)[1]);
- }
-
- int haswin_freeblock(void *buf) {
-
- return(haswin_free(&((int *)buf)[-1]));
- }
-
-