17static char SccsId[] =
"%W% %G%";
48#if HAVE_SYS_RESOURCE_H
49#include <sys/resource.h>
81void *my_malloc(
size_t sz) {
87 if (DEBUG_DIRECT || Yap_do_low_level_trace) {
91 fprintf(stderr,
"+s %p\n @%p %ld\n", p, TR, LCL0 - (CELL *)LCL0);
98void *my_realloc(
void *ptr,
size_t sz) {
101 p = realloc(ptr, sz);
103 if (DEBUG_DIRECT ||Yap_do_low_level_trace)
104 fprintf(stderr,
"+ %p -> %p : " Sizet_F
"\n", ptr, p, sz);
113void my_free(
void *p) {
116if (DEBUG_DIRECT ||Yap_do_low_level_trace)
117 fprintf(stderr,
"- %p\n @%p %ld\n", p, TR, (
long int)(LCL0 - (CELL *)B) );
127#define my_malloc(sz) Yap_dlmalloc(sz)
128#define my_realloc(ptr, sz) Yap_dlrealloc(ptr, sz)
129#define my_free(sz) Yap_dlfree(sz)
131static char *my_reallocl(
char *ptr, UInt sz, UInt osz,
int safe) {
136 if (ptr < Yap_HeapBase || ptr > HeapTop) {
138 nptr = Yap_dlmalloc(sz);
140 memmove(nptr, ptr, osz);
144 nptr = Yap_dlrealloc(ptr, sz);
151 if (Yap_growheap(FALSE, sz, NULL)) {
157 if (ptr < Yap_HeapBase || ptr > HeapTop) {
159 nptr = realloc(ptr, sz);
161 memmove(nptr, ptr, osz);
168 memmove(nptr, ptr, osz);
176#if USE_SYSTEM_MALLOC || USE_DL_MALLOC
178long long unsigned int mallocs, reallocs, frees;
179long long unsigned int tmalloc;
181#undef INSTRUMENT_MALLOC
183static inline char *call_malloc(
size_t size) {
192 size +=
sizeof(CELL);
194 LOCAL_PrologMode |= MallocMode;
195 out = (
char *)my_malloc(size);
197 *(CELL *)out = size -
sizeof(CELL);
200 LOCAL_PrologMode &= ~MallocMode;
202 UNLOCK(DLMallocLock);
207void *Yap_AllocCodeSpace(
size_t size) {
208 size = AdjustSize(size);
209 return call_malloc(size);
212static inline char *call_realloc(
char *p,
size_t size) {
221 size +=
sizeof(CELL);
223 tmalloc -= *(CELL *)p;
225 LOCAL_PrologMode |= MallocMode;
226 out = (
char *)my_realloc(p, size);
228 *(CELL *)out = size -
sizeof(CELL);
231 LOCAL_PrologMode &= ~MallocMode;
233 UNLOCK(DLMallocLock);
238void *Yap_ReallocCodeSpace(
void *p,
size_t size) {
239 size = AdjustSize(size);
240 return call_realloc(p, size);
243void Yap_FreeCodeSpace(
void *p) {
248 LOCAL_PrologMode |= MallocMode;
251 tmalloc -= *(CELL *)p;
255 LOCAL_PrologMode &= ~MallocMode;
257 UNLOCK(DLMallocLock);
261void *Yap_AllocAtomSpace(
size_t size) {
262 size = AdjustSize(size);
263 return call_malloc(size);
266void Yap_FreeAtomSpace(
void *p) {
271 LOCAL_PrologMode |= MallocMode;
274 tmalloc -= *(CELL *)p;
278 LOCAL_PrologMode &= ~MallocMode;
280 UNLOCK(DLMallocLock);
288ADDR Yap_InitPreAllocCodeSpace(
int wid) {
291 UInt sz = REMOTE_ScratchPad(wid).msz;
293 if (REMOTE_ScratchPad(wid).ptr == NULL) {
297 REMOTE_PrologMode(wid) |= MallocMode;
310 REMOTE_PrologMode(wid) &= ~MallocMode;
312 UNLOCK(DLMallocLock);
314 if (!Yap_growheap(FALSE, LOCAL_Error_Size, NULL)) {
315 Yap_Error(RESOURCE_ERROR_HEAP, TermNil, LOCAL_ErrorMessage);
326 REMOTE_PrologMode(wid) |= MallocMode;
328 REMOTE_PrologMode(wid) &= ~MallocMode;
330 UNLOCK(DLMallocLock);
332 REMOTE_ScratchPad(wid).ptr = ptr;
334 ptr = REMOTE_ScratchPad(wid).ptr;
336 AuxBase = (ADDR)(ptr);
337 AuxSp = (CELL *)(AuxTop = AuxBase + REMOTE_ScratchPad(wid).sz);
341ADDR Yap_ExpandPreAllocCodeSpace(UInt sz0,
void *cip,
int safe) {
345 if (sz0 < SCRATCH_INC_SIZE)
346 sz0 = SCRATCH_INC_SIZE;
347 if (sz0 < LOCAL_ScratchPad.sz)
348 sz = LOCAL_ScratchPad.sz + sz0;
351 sz = AdjustLargePageSize(sz + sz / 4);
356 LOCAL_PrologMode |= MallocMode;
359 tmalloc -= LOCAL_ScratchPad.sz;
362 if (!(ptr = my_realloc(LOCAL_ScratchPad.ptr, sz))) {
363 LOCAL_PrologMode &= ~MallocMode;
365 UNLOCK(DLMallocLock);
369 LOCAL_PrologMode &= ~MallocMode;
371 UNLOCK(DLMallocLock);
373 LOCAL_ScratchPad.sz = LOCAL_ScratchPad.msz = sz;
374 LOCAL_ScratchPad.ptr = ptr;
376 AuxSp = (CELL *)(AuxTop = ptr + sz);
386 size_t Yap_HeapUsed(
void)
389 struct mallinfo mi = mallinfo();
390 return mi.uordblks - (LOCAL_TrailTop-LOCAL_GlobalBase);
392 return Yap_ClauseSpace+Yap_IndexSpace_Tree+Yap_LUClauseSpace+Yap_LUIndexSpace_CP;
396static void InitExStacks(
int wid,
size_t Trail,
size_t Stack) {
401 if (Trail < MinTrailSpace)
402 Trail = MinTrailSpace;
403 if (Stack < MinStackSpace)
404 Stack = MinStackSpace;
405 pm = (Trail + Stack) * K;
411 REMOTE_GlobalBase(wid) = (ADDR)REMOTE_ThreadHandle(wid).stack_address;
415 REMOTE_TrailTop(wid) = REMOTE_GlobalBase(wid) + pm;
416 REMOTE_LocalBase(wid) = REMOTE_GlobalBase(wid) + sa;
417 REMOTE_TrailBase(wid) = REMOTE_LocalBase(wid) +
sizeof(CELL);
419 REMOTE_ScratchPad(wid).ptr = NULL;
420 REMOTE_ScratchPad(wid).sz = REMOTE_ScratchPad(wid).msz = SCRATCH_START_SIZE;
423 if (Yap_output_msg) {
427 "HeapBase = %p GlobalBase = %p\n LocalBase = %p TrailTop = %p\n",
428 Yap_HeapBase, REMOTE_GlobalBase(wid), REMOTE_LocalBase(wid),
429 REMOTE_TrailTop(wid));
432 fprintf(stderr,
"Heap+Aux: %lu\tLocal+Global: %lu\tTrail: %lu\n",
433 (
long unsigned)(pm - sa - ta), (
long unsigned)sa,
439void Yap_InitExStacks(
int wid,
size_t Trail,
size_t Stack) {
441 InitExStacks(wid, Trail, Stack);
445void Yap_KillStacks(
int wid) {
446 ADDR gb = REMOTE_ThreadHandle(wid).stack_address;
449 REMOTE_ThreadHandle(wid).stack_address = NULL;
453void Yap_KillStacks(
int wid) {
454 if (LOCAL_GlobalBase) {
455 free(LOCAL_GlobalBase);
456 LOCAL_GlobalBase = NULL;
461void Yap_InitMemory(
size_t Trail,
size_t Heap,
size_t Stack) {
468int Yap_ExtendWorkSpace(Int s) {
470 void *basebp = LOCAL_GlobalBase, *nbp;
471 UInt s0 = LOCAL_TrailTop - LOCAL_GlobalBase;
472 nbp = realloc(basebp, s + s0);
476 LOCAL_ThreadHandle.stack_address = (
char *)nbp;
478 LOCAL_GlobalBase = (
char *)nbp;
482size_t Yap_ExtendWorkSpaceThroughHole(
size_t s) {
return 0; }
484void Yap_AllocHole(UInt actual_request, UInt total_size) {}
487UInt Yap_givemallinfo(
void) {
488 struct mallinfo mi = mallinfo();
496#define snprintf3(A, B, C) snprintf(A, B, C)
497#define snprintf4(A, B, C, D) snprintf(A, B, C, D)
498#define snprintf5(A, B, C, D, E) snprintf(A, B, C, D, E)
500#define snprintf3(A, B, C) sprintf(A, C)
501#define snprintf4(A, B, C, D) sprintf(A, C, D)
502#define snprintf5(A, B, C, D, E) sprintf(A, C, D, E)
513static char *AllocHeap(
unsigned long int);
517#define MinHGap 256 * K
525 UNLOCK(HeapUsedLock);
527 if (p && b->b_size == p->b_size) {
536 q = &((*q)->b_next_size);
540 p->b_next_size = b->b_next_size;
553 sp = &(b->b_size) + b->b_size;
557 UNLOCK(HeapUsedLock);
559 while ((p = *q) && p->b_size < b->b_size)
561 if (p && p->b_size == b->b_size) {
563 b->b_next_size = p->b_next_size;
585 sp = &(b->b_size) + (b->b_size & ~InUseFlag);
586 if (!(b->b_size & InUseFlag) || *sp != b->b_size) {
590 "%% YAP INTERNAL ERROR: sanity check failed in FreeBlock %p %x %x\n", b,
591 b->b_size, Unsigned(*sp));
595 "%% YAP INTERNAL ERROR: sanity check failed in FreeBlock %p %lx %lx\n",
600 b->b_size &= ~InUseFlag;
601 LOCK(FreeBlocksLock);
604 sp = &(b->b_size) - 1;
605 if (!(*sp & InUseFlag)) {
607 RemoveFromFreeList(p);
608 p->b_size += b->b_size + 1;
612 sp = &(b->b_size) + b->b_size + 1;
613 if (!(*sp & InUseFlag)) {
615 RemoveFromFreeList(p);
616 b->b_size += p->b_size + 1;
622 UNLOCK(HeapUsedLock);
630 UNLOCK(FreeBlocksLock);
634GetBlock(
unsigned long int n) {
637 if (FreeBlocks == NIL)
643 while (((b = *p) != NIL) && b->b_size < n)
645 if (b == NIL || b->b_size < n)
647 if ((r = b->b_next) == NIL)
650 r->b_next_size = b->b_next_size;
655 if (HeapUsed > HeapMax)
657 UNLOCK(HeapUsedLock);
661static char *AllocHeap(
size_t size) {
675 align = 2 *
sizeof(CELL);
678 align =
sizeof(CELL);
680 while (align < extra)
682 size = ALIGN_SIZE(size, align);
687 size = size /
sizeof(CELL);
688 LOCK(FreeBlocksLock);
689 if ((b = GetBlock(size))) {
690 if (b->b_size >= size + 24 + 1) {
692 n->b_size = b->b_size - size - 1;
696 sp = &(b->b_size) + b->b_size;
697 *sp = b->b_size | InUseFlag;
698 b->b_size |= InUseFlag;
699 UNLOCK(FreeBlocksLock);
703 UNLOCK(FreeBlocksLock);
710 if (HeapTop > Addr(LOCAL_GlobalBase) - MinHeapGap)
711 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"no heap left (AllocHeap)");
713 if (HeapTop > HeapLim - MinHeapGap) {
716 if (HeapTop > HeapLim) {
717 UNLOCK(HeapUsedLock);
720 Yap_Error(RESOURCE_ERROR_HEAP, TermNil,
"Stack Crashed against Heap...");
723 if (HeapTop + size *
sizeof(CELL) +
sizeof(
YAP_SEG_SIZE) < HeapLim) {
727 UNLOCK(HeapUsedLock);
729 Yap_signal(YAP_CDOVF_SIGNAL);
731 if (size > GLOBAL_SizeOfOverflow)
732 GLOBAL_SizeOfOverflow = size *
sizeof(CELL) +
sizeof(
YAP_SEG_SIZE);
734 UNLOCK(HeapUsedLock);
742 if (HeapUsed > HeapMax)
744 UNLOCK(HeapUsedLock);
745 b->b_size = size | InUseFlag;
746 sp = &(b->b_size) + size;
754static void FreeCodeSpace(
char *p) {
758static char *AllocCodeSpace(
unsigned long int size) {
759 if (size < SmallSize + 2 * OpCodeSize + 3 * CellSize)
760 return (AllocHeap(SmallSize + 2 * OpCodeSize + 3 * CellSize));
761 return (AllocHeap(size));
770void Yap_FreeCodeSpace(
char *p) {
778char *Yap_AllocAtomSpace(
unsigned long int size) {
779 char *out = AllocHeap(size);
782 printf(
"+%p/%d\n", out, size);
787void Yap_FreeAtomSpace(
char *p) {
795char *Yap_AllocCodeSpace(
unsigned long int size) {
796 char *out = AllocCodeSpace(size);
799 printf(
"+%p/%d\n", out, size);
822#if defined(_WIN32) || defined(__CYGWIN__)
824#undef DEBUG_WIN32_ALLO
830static int ExtendWorkSpace(Int s,
int fixed_allocation) {
832 prolog_exec_mode OldPrologMode = LOCAL_PrologMode;
834 LOCAL_PrologMode = ExtendStackMode;
837 fprintf(stderr,
"trying: %p (" Int_FORMAT
"K) %d\n", b, s / 1024,
840 if (fixed_allocation) {
841 b = VirtualAlloc(b, s, MEM_RESERVE, PAGE_NOACCESS);
843 b = VirtualAlloc(NULL, s, MEM_RESERVE, PAGE_NOACCESS);
845 LOCAL_PrologMode = OldPrologMode;
846 return ExtendWorkSpace(s, fixed_allocation);
850 LOCAL_PrologMode = OldPrologMode;
854 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
855 NULL, GetLastError(),
856 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), msg, 256, NULL);
857 fprintf(stderr,
"NOT OK1: %p %p %s\n", brk, b, msg);
862 b = VirtualAlloc(b, s, MEM_COMMIT, PAGE_READWRITE);
864 LOCAL_ErrorMessage = LOCAL_ErrorSay;
865 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
866 "VirtualAlloc could not commit %ld bytes", (
long int)s);
867 LOCAL_PrologMode = OldPrologMode;
869 fprintf(stderr,
"NOT OK2: %p--%p\n", b, brk);
873 brk = (LPVOID)((Int)b + s);
875 fprintf(stderr,
"OK: %p--%p " Int_FORMAT
"\n", b, brk, s);
877 LOCAL_PrologMode = OldPrologMode;
881static MALLOC_T InitWorkSpace(Int s) {
886 psz = Yap_page_size = si.dwPageSize;
888 if (!ExtendWorkSpace(s, 0))
890 return (MALLOC_T)brk - s;
893int Yap_FreeWorkSpace(
void) {
return TRUE; }
904#include <sys/types.h>
918static MALLOC_T WorkSpaceTop;
920static MALLOC_T InitWorkSpace(Int s) {
922#if !defined(_AIX) && !defined(__APPLE__) && !__hpux
926 a = mmap(0, (
size_t)s, PROT_READ | PROT_WRITE | PROT_EXEC,
927 MAP_PRIVATE | MAP_ANONYMOUS | MAP_VARIABLE, -1, 0);
929 a = mmap(((
void *)MMAP_ADDR), (
size_t)s, PROT_READ | PROT_WRITE | PROT_EXEC,
930 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
931 if (a != (MALLOC_T)MMAP_ADDR) {
932 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
933 "mmap could not map ANON at %p, got %p", (
void *)MMAP_ADDR, a);
936#elif defined(__APPLE__)
938 a = mmap(((
void *)MMAP_ADDR), (
size_t)s, PROT_READ | PROT_WRITE | PROT_EXEC,
939 MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
940 if (a != (MALLOC_T)MMAP_ADDR) {
941 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
942 "mmap could not map ANON at %p, got %p", (
void *)MMAP_ADDR, a);
946 a = mmap(NULL, (
size_t)s, PROT_READ | PROT_WRITE | PROT_EXEC,
947 MAP_PRIVATE | MAP_ANON, -1, 0);
950 fd = open(
"/dev/zero", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
954 strncpy(file,
"/tmp/YAP.TMPXXXXXX", 256);
955 if (mkstemp(file) == -1) {
957 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
958 "mkstemp could not create temporary file %s (%s)", file,
961 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
962 "mkstemp could not create temporary file %s", file);
968 char *file = tmpnam(NULL);
971 strcpy(file,
"/tmp/mapfile");
972 itos(getpid(), &file[12]);
975 fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
977 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
"mmap could not open %s", file);
980 if (lseek(fd, s, SEEK_SET) < 0) {
981 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
982 "mmap could not lseek in mmapped file %s", file);
986 if (write(fd,
"", 1) < 0) {
987 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
988 "mmap could not write in mmapped file %s", file);
992 if (unlink(file) < 0) {
993 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
994 "mmap could not unlink mmapped file %s", file);
1000 a = mmap(((
void *)MMAP_ADDR), (
size_t)s, PROT_READ | PROT_WRITE | PROT_EXEC,
1001 MAP_PRIVATE | MAP_FIXED, fd, 0);
1002 if (a != (MALLOC_T)MMAP_ADDR) {
1003 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
"mmap could not map at %p, got %p",
1004 (
void *)MMAP_ADDR, a);
1008 a = mmap(0, (
size_t)s, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd,
1010 if ((CELL)a & YAP_PROTECTED_MASK) {
1012 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
1013 "mmapped address %p collides with YAP tags", a);
1016 if (close(fd) == -1) {
1017 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
"while closing mmaped file");
1024 (a == (MALLOC_T)MMAP_FAILED)
1029 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
"mmap cannot allocate memory ***");
1032 WorkSpaceTop = (
char *)a + s;
1037static MALLOC_T mmap_extension(Int s, MALLOC_T base,
int fixed_allocation) {
1040#if !defined(_AIX) && !defined(__hpux) && !defined(__APPLE__)
1043#if defined(_AIX) || defined(__hpux)
1044 a = mmap(base, (
size_t)s, PROT_READ | PROT_WRITE | PROT_EXEC,
1045 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
1047#elif defined(__APPLE__)
1048 a = mmap(base, (
size_t)s, PROT_READ | PROT_WRITE | PROT_EXEC,
1049 MAP_PRIVATE | MAP_ANON | fixed_allocation, -1, 0);
1051 fd = open(
"/dev/zero", O_RDWR);
1055 strncpy(file,
"/tmp/YAP.TMPXXXXXX", 256);
1056 if (mkstemp(file) == -1) {
1057 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1059 snprintf5(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1060 "mkstemp could not create temporary file %s (%s)", file,
1063 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1064 "mkstemp could not create temporary file %s", file);
1066 return (MALLOC_T)-1;
1070 char *file = tmpnam(NULL);
1072 char file[MAX_PATH];
1073 strcpy(file,
"/tmp/mapfile");
1074 itos(getpid(), &file[12]);
1077 fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
1079 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1080 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1081 "mmap could not open %s", file);
1082 return (MALLOC_T)-1;
1084 if (lseek(fd, s, SEEK_SET) < 0) {
1085 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1086 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1087 "mmap could not lseek in mmapped file %s", file);
1089 return (MALLOC_T)-1;
1091 if (write(fd,
"", 1) < 0) {
1092 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1093 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1094 "mmap could not write in mmapped file %s", file);
1096 return (MALLOC_T)-1;
1098 if (unlink(file) < 0) {
1099 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1100 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1101 "mmap could not unlink mmapped file %s", file);
1103 return (MALLOC_T)-1;
1107 base, (
size_t)s, PROT_READ | PROT_WRITE | PROT_EXEC,
1109#
if !defined(__linux)
1115 if (close(fd) == -1) {
1116 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1118 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1119 "mmap could not close file (%s) ]\n", strerror(errno));
1121 snprintf3(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1122 "mmap could not close file ]\n");
1124 return (MALLOC_T)-1;
1138static int ExtendWorkSpace(Int s,
int fixed_allocation) {
1140 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
1141 "cannot extend stacks (ExtendWorkSpace)");
1145 prolog_exec_mode OldPrologMode = LOCAL_PrologMode;
1146 MALLOC_T base = WorkSpaceTop;
1148 if (fixed_allocation == MAP_FIXED)
1149 base = WorkSpaceTop;
1152 LOCAL_PrologMode = ExtendStackMode;
1153 a = mmap_extension(s, base, fixed_allocation);
1154 LOCAL_PrologMode = OldPrologMode;
1155 if (a == (MALLOC_T)-1) {
1156 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1158 snprintf5(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1159 "could not allocate %d bytes (%s)", (
int)s, strerror(errno));
1161 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1162 "could not allocate %d bytes", (
int)s);
1166 if (fixed_allocation) {
1167 if (a != WorkSpaceTop) {
1168 munmap((
void *)a, (
size_t)s);
1169 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1170 snprintf5(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1171 "mmap could not grow memory at %p, got %p", WorkSpaceTop, a);
1172 LOCAL_PrologMode = OldPrologMode;
1175 }
else if (a < WorkSpaceTop) {
1177 int res = ExtendWorkSpace(s, fixed_allocation);
1182 WorkSpaceTop = (
char *)a + s;
1183 LOCAL_PrologMode = OldPrologMode;
1188int Yap_FreeWorkSpace(
void) {
return 1; }
1197#define MMAP_ADDR 0x0L
1200static MALLOC_T WorkSpaceTop;
1202static MALLOC_T InitWorkSpace(Int s) {
1207 if ((shm_id = shmget(IPC_PRIVATE, (
size_t)s, SHM_R | SHM_W)) == -1) {
1208 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
"could not shmget %d bytes", s);
1211 if ((ptr = (MALLOC_T)shmat(shm_id, (
void *)MMAP_ADDR, 0)) == (MALLOC_T)-1) {
1212 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
"could not shmat at %p", MMAP_ADDR);
1215 if (shmctl(shm_id, IPC_RMID, 0) != 0) {
1216 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
"could not remove shm segment",
1220 WorkSpaceTop = (
char *)ptr + s;
1224static int ExtendWorkSpace(Int s) {
1227 prolog_exec_mode OldPrologMode = LOCAL_PrologMode;
1229 LOCAL_PrologMode = ExtendStackMode;
1231 if ((shm_id = shmget(IPC_PRIVATE, (
size_t)s, SHM_R | SHM_W)) == -1) {
1232 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1233 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1234 "could not shmget %d bytes", s);
1235 LOCAL_PrologMode = OldPrologMode;
1238 if ((ptr = (MALLOC_T)shmat(shm_id, WorkSpaceTop, 0)) == (MALLOC_T)-1) {
1239 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1240 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
"could not shmat at %p",
1242 LOCAL_PrologMode = OldPrologMode;
1245 if (shmctl(shm_id, IPC_RMID, 0) != 0) {
1246 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1247 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1248 "could not remove shm segment", shm_id);
1249 LOCAL_PrologMode = OldPrologMode;
1252 WorkSpaceTop = (
char *)ptr + s;
1253 LOCAL_PrologMode = OldPrologMode;
1257int Yap_FreeWorkSpace(
void) {
return TRUE; }
1276#define LIMBO_SIZE 32 * K
1279static char limbo_space[LIMBO_SIZE];
1280static char *limbo_p = limbo_space, *limbo_pp = 0;
1282static MALLOC_T InitWorkSpace(Int s) {
1283 MALLOC_T ptr = (MALLOC_T)sbrk(s);
1285 if (ptr == ((MALLOC_T)-1)) {
1286 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
"could not allocate %d bytes", s);
1292static int ExtendWorkSpace(Int s) {
1293 MALLOC_T ptr = (MALLOC_T)sbrk(s);
1294 prolog_exec_mode OldPrologMode = LOCAL_PrologMode;
1296 LOCAL_PrologMode = ExtendStackMode;
1297 if (ptr == ((MALLOC_T)-1)) {
1298 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1299 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1300 "could not expand stacks over %d bytes", s);
1301 LOCAL_PrologMode = OldPrologMode;
1304 LOCAL_PrologMode = OldPrologMode;
1308int Yap_FreeWorkSpace(
void) {
return TRUE; }
1311malloc(
size_t size) {
1314 limbo_p += (size + 7) & 0xffff8;
1315 if (limbo_p >= &limbo_space[LIMBO_SIZE])
1319 CODEADDR codep = (CODEADDR)AllocCodeSpace(size + 2 *
sizeof(
void *));
1323 return (codep + 2 *
sizeof(
void *));
1327void free(MALLOC_T ptr) {
1331 if (ptr == limbo_pp) {
1337 if ((
char *)ptr < Yap_HeapBase || (
char *)ptr > HeapTop)
1339 if (!(b->b_size & InUseFlag))
1341 FreeCodeSpace((
char *)ptr - 2 *
sizeof(
void *));
1345XX realloc(MALLOC_T ptr,
size_t size) {
1346 MALLOC_T
new = malloc(size);
1349 memmove(
new, ptr, size);
1355calloc(
size_t n,
size_t e) {
1357 MALLOC_T p = malloc(k);
1364int mallopt(cmd, value) {
return (value); }
1366static struct mallinfo xmall;
1368struct mallinfo mallinfo(void) {
1380#define MAX_SPACE 420 * 1024 * 1024
1382#define MAX_SPACE 128 * 1024 * 1024
1385static int total_space;
1387static MALLOC_T InitWorkSpace(Int s) {
1391 mallopt(M_MMAP_MAX, 0);
1393 ptr = (MALLOC_T)calloc(MAX_SPACE, 1);
1397 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
"could not allocate %d bytes", s);
1403static int ExtendWorkSpace(Int s) {
1405 prolog_exec_mode OldPrologMode = LOCAL_PrologMode;
1408 if (total_space < MAX_SPACE)
1410 LOCAL_PrologMode = ExtendStackMode;
1411 ptr = (MALLOC_T)realloc((
void *)Yap_HeapBase, total_space);
1413 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1414 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1415 "could not allocate %d bytes", s);
1416 LOCAL_PrologMode = OldPrologMode;
1419 if (ptr != (MALLOC_T)Yap_HeapBase) {
1420 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1421 snprintf4(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1422 "could not expand contiguous stacks %d bytes", s);
1423 LOCAL_PrologMode = OldPrologMode;
1427 if ((CELL)ptr & MBIT) {
1428 LOCAL_ErrorMessage = LOCAL_ErrorSay;
1429 snprintf5(LOCAL_ErrorMessage, MAX_ERROR_MSG_SIZE,
1430 "memory at %p conflicts with MBIT %lx", ptr, (
unsigned long)MBIT);
1431 LOCAL_PrologMode = OldPrologMode;
1435 LOCAL_PrologMode = OldPrologMode;
1439int Yap_FreeWorkSpace(
void) {
return TRUE; }
1442static void InitHeap(
void *heap_addr) {
1444 Yap_HeapBase = heap_addr;
1453 HeapMax = HeapUsed = HeapTop - Yap_HeapBase;
1463void Yap_InitHeap(
void *heap_addr) { InitHeap(heap_addr); }
1465void Yap_InitMemory(UInt Trail, UInt Heap, UInt Stack) {
1469#if defined(_WIN32) || defined(__CYGWIN__)
1470 Stack = ((Stack + (YAP_ALLOC_SIZE - 1)) / YAP_ALLOC_SIZE) * YAP_ALLOC_SIZE;
1471 Heap = ((Heap + (YAP_ALLOC_SIZE - 1)) / YAP_ALLOC_SIZE) * YAP_ALLOC_SIZE;
1472 Trail = ((Trail + (YAP_ALLOC_SIZE - 1)) / YAP_ALLOC_SIZE) * YAP_ALLOC_SIZE;
1474 pm = (Trail + Heap + Stack);
1479#if RANDOMIZE_START_ADDRESS
1481 UInt x = (rand() % 100) * YAP_ALLOC_SIZE;
1484 addr = InitWorkSpace(pm);
1485#if RANDOMIZE_START_ADDRESS
1486 addr = (
char *)addr + x;
1492 LOCAL_TrailTop = Yap_HeapBase + pm;
1493 LOCAL_LocalBase = LOCAL_TrailTop - ta;
1494 LOCAL_TrailBase = LOCAL_LocalBase +
sizeof(CELL);
1496 LOCAL_GlobalBase = LOCAL_LocalBase - sa;
1497 HeapLim = LOCAL_GlobalBase;
1500 AuxTop = (ADDR)(AuxSp = (CELL *)LOCAL_GlobalBase);
1504#if SIZEOF_INT_P != SIZEOF_INT
1505 if (Yap_output_msg) {
1507 "HeapBase = %p GlobalBase = %p\n LocalBase = %p TrailTop = %p\n",
1508 Yap_HeapBase, LOCAL_GlobalBase, LOCAL_LocalBase, LOCAL_TrailTop);
1510 if (Yap_output_msg) {
1512 "HeapBase = %x GlobalBase = %x\n LocalBase = %x TrailTop = %x\n",
1513 (UInt)Yap_HeapBase, (UInt)LOCAL_GlobalBase, (UInt)LOCAL_LocalBase,
1514 (UInt)LOCAL_TrailTop);
1518 "Heap+Aux: " UInt_FORMAT
"\tLocal+Global: " UInt_FORMAT
1519 "\tTrail: " UInt_FORMAT
"\n",
1520 pm - sa - ta, sa, ta);
1525void Yap_InitExStacks(
int wid,
int Trail,
int Stack) {
1527 REMOTE_ScratchPad(wid).ptr = NULL;
1528 REMOTE_ScratchPad(wid).sz = REMOTE_ScratchPad(wid).msz = SCRATCH_START_SIZE;
1533#if defined(_WIN32) || defined(__CYGWIN__)
1534#define WorkSpaceTop brk
1540void Yap_add_memory_hole(ADDR Start, ADDR End) { Yap_HoleSize += Start - End; }
1543int Yap_ExtendWorkSpace(Int s) {
1545 return ExtendWorkSpace(s, MAP_FIXED);
1546#elif defined(_WIN32)
1547 return ExtendWorkSpace(s, MAP_FIXED);
1549 return ExtendWorkSpace(s);
1553size_t Yap_ExtendWorkSpaceThroughHole(
size_t s) {
1554#if USE_SYSTEM_MMAP || defined(_WIN32) || defined(__CYGWIN__)
1555 MALLOC_T WorkSpaceTop0 = WorkSpaceTop;
1556#if SIZEOF_INT_P == 4
1557 while (WorkSpaceTop < (MALLOC_T)0xc0000000L) {
1559 WorkSpaceTop += 512 * 1024;
1560 if (ExtendWorkSpace(s, MAP_FIXED)) {
1561 Yap_add_memory_hole((ADDR)WorkSpaceTop0, (ADDR)WorkSpaceTop - s);
1562 LOCAL_ErrorMessage = NULL;
1563 return WorkSpaceTop - WorkSpaceTop0;
1567 if (GetLastError() != 487) {
1568 WorkSpaceTop = WorkSpaceTop0;
1572#elif SIZEOF_INT_P == 8
1574 int n = 1024 * 1024;
1577 WorkSpaceTop += 512 * 1024;
1578 if (ExtendWorkSpace(s, MAP_FIXED)) {
1579 Yap_add_memory_hole((ADDR)WorkSpaceTop0, (ADDR)WorkSpaceTop - s);
1580 LOCAL_ErrorMessage = NULL;
1581 return WorkSpaceTop - WorkSpaceTop0;
1585 WorkSpaceTop = WorkSpaceTop0;
1592 WorkSpaceTop = WorkSpaceTop0;
1597void Yap_AllocHole(UInt actual_request, UInt total_size) {
1598#if (USE_SYSTEM_MMAP || defined(_WIN32) || defined(__CYGWIN__)) && \
1602 ADDR WorkSpaceTop0 = WorkSpaceTop - total_size;
1605 YAP_SEG_SIZE bsiz = (WorkSpaceTop0 - HeapTop) /
sizeof(CELL) -
1609 HeapTop = WorkSpaceTop - (actual_request -
sizeof(
YAP_SEG_SIZE));
1613 (HeapTop - WorkSpaceTop0) /
sizeof(
YAP_SEG_SIZE) | InUseFlag;
1614 newb->b_size = bsiz;
1615 AddToFreeList(newb);
1635#include "YapStreams.h"
1650#define MAX_PATHNAME 2048
1653 struct mblock *prev, *next;
1661 struct mblock *first[16];
1666int AllocLevel(
void) {
return LOCAL_TextBuffer->lvl; }
1668void insert_block(
struct mblock *o) {
1670 o->prev = LOCAL_TextBuffer->last[lvl];
1674 if (LOCAL_TextBuffer->first[lvl]) {
1675 LOCAL_TextBuffer->last[lvl] = o;
1677 LOCAL_TextBuffer->first[lvl] = LOCAL_TextBuffer->last[lvl] = o;
1682 void release_block(
struct mblock *o) {
1684 if (LOCAL_TextBuffer->first[lvl] == o) {
1685 if (LOCAL_TextBuffer->last[lvl] == o) {
1686 LOCAL_TextBuffer->first[lvl] = LOCAL_TextBuffer->last[lvl] = NULL;
1688 LOCAL_TextBuffer->first[lvl] = o->next;
1689 }
else if (LOCAL_TextBuffer->last[lvl] == o) {
1690 LOCAL_TextBuffer->last[lvl] = o->prev;
1693 o->prev->next = o->next;
1695 o->next->prev = o->prev;
1698int push_text_stack__(USES_REGS1) {
1699 int i = LOCAL_TextBuffer->lvl;
1700 LOCAL_TextBuffer->lvl = i+1;
1705int pop_text_stack__(
int i) {
1706 int lvl = LOCAL_TextBuffer->lvl;
1708 struct mblock *p = LOCAL_TextBuffer->first[lvl];
1710 struct mblock *np = p->next;
1714 LOCAL_TextBuffer->first[lvl] = NULL;
1715 LOCAL_TextBuffer->last[lvl] = NULL;
1718 LOCAL_TextBuffer->lvl = lvl;
1722void *pop_output_text_stack__(
int i,
const void *export) {
1723 int lvl = LOCAL_TextBuffer->lvl;
1726 struct mblock *p = LOCAL_TextBuffer->first[lvl];
1728 struct mblock *np = p->next;
1729 if (p + 1 == export) {
1736 LOCAL_TextBuffer->first[lvl] = NULL;
1737 LOCAL_TextBuffer->last[lvl] = NULL;
1740 LOCAL_TextBuffer->lvl = lvl;
1745 o->prev = o->next = 0;
1750 size_t sz = p->sz -
sizeof(
struct mblock);
1751 memmove(p, p + 1, sz);
1756 return (
void *)export;
1760 int lvl = LOCAL_TextBuffer->lvl;
1763 sz = ALIGN_BY_TYPE(sz +
sizeof(
struct mblock), CELL);
1764 struct mblock *o = malloc(sz);
1769 o->prev = o->next = 0;
1774void *MallocAtLevel(
size_t sz,
int atL USES_REGS) {
1775 int lvl = LOCAL_TextBuffer->lvl;
1776 if (atL > 0 && atL <= lvl) {
1778 }
else if (atL < 0 && lvl - atL >= 0) {
1785 sz = ALIGN_BY_TYPE(sz +
sizeof(
struct mblock), CELL);
1786 struct mblock *o = malloc(sz);
1791 o->prev = o->next = 0;
1796void *Realloc(
void *pt,
size_t sz USES_REGS) {
1797 struct mblock *old = pt, *o;
1799 return Malloc(sz PASS_REGS);
1801 sz = ALIGN_BY_TYPE(sz, Yap_Max(CELLSIZE,
sizeof(
struct mblock)));
1802 sz += 2*
sizeof(
struct mblock);
1803 o = realloc(old, sz);
1807 LOCAL_TextBuffer->last[o->lvl] = o;
1812 LOCAL_TextBuffer->first[o->lvl] = o;
1824const void *MallocExportAsRO(
const void *pt USES_REGS) {
1825 struct mblock *old = (
void *)pt, *o = old - 1;
1830 memmove((
void *)o, pt, sz);
1831 return realloc((
void *)o, sz);
1834void Free(
void *pt USES_REGS) {
1841void *Yap_InitTextAllocator(
void) {
CELL YAP_SEG_SIZE
definitions required by saver/restorer and memory manager
void * Malloc(size_t sz USES_REGS)
allocate a temporary text block