home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / prolog / brklyprl.lha / Emulator / memory.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-14  |  3.7 KB  |  189 lines

  1.  
  2. /* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */
  3.  
  4. /* Copyright Herve' Touati, Aquarius Project, UC Berkeley */
  5.  
  6. #include <stream.h>
  7. #include <sys/types.h>
  8. #include <sys/time.h>
  9. #include <sys/resource.h>
  10. #include "tags.h"
  11. #include "instr.h"
  12. #include "hash_table.h"
  13. #include "string_table.h"
  14. #include "memory.h"
  15. #include "top_level.h"
  16.  
  17. CellPtr S, B0, B, E0, E, TR0, TR, H0, H, R0, R;
  18. InstrPtr P0, CP0, FP0, NP0, MP0, P;
  19.  
  20. #ifdef WITH_GC
  21. CellPtr H2, TR2, E2;
  22. CellPtr HMIN, HMAXSOFT, HMAXHARD;
  23. unsigned char* MKMIN;
  24. #endif
  25.  
  26. Cell X[NUMBER_OF_REGISTERS];
  27.  
  28. void memory_allocator_error(char* s)
  29. {
  30.   cout << s << "\n";
  31.   exit(2);
  32. }
  33.  
  34. extern int getrlimit(...);
  35. extern int setrlimit(...);
  36.  
  37. int amem()
  38. {
  39.   int vfork();
  40.   int execl(...);
  41.   int wait(...);
  42.   int pid;
  43.   switch (pid = vfork()) {
  44.   case 0:
  45.     execl("pasmem", "pasmem", 0);
  46.     break;
  47.   case -1:
  48.     cout << "can't fork out amem\n";
  49.     exit(-1);
  50.   default:
  51.     wait(0);
  52.     break;
  53.   }
  54.   filebuf* f1 = new filebuf;
  55.   if (f1->open(".pas_data_limit", input) == 0) {
  56.     cerr << "can't open .pas_data_limit\n";
  57.     exit(1);
  58.   }
  59.   istream* i = new istream(f1);
  60.   int size;
  61.   *i >> size;
  62.   return size;
  63. }
  64.  
  65. int get_limit()
  66. {
  67.   struct rlimit rl;
  68.   if (getrlimit(RLIMIT_DATA, &rl)) return -1;
  69.   rl.rlim_cur = rl.rlim_max;
  70.   if (setrlimit(RLIMIT_DATA, &rl)) return -1;
  71.   int size = amem();
  72.   int i;
  73.   for (i = 1; i <= size; i <<= 1) 
  74.     ;
  75.   return i / 2;
  76. }
  77.  
  78. struct AllocMem {
  79.   int* p;
  80.   int size;
  81.   AllocMem(int* P =0, int SIZE =0) {p = P; size = SIZE;}
  82. };
  83.  
  84. static int pagesize;
  85. const int MIN_NUMBER_OF_PAGES = 32;
  86. const int NUMBER_OF_PAGES_FREE = 32;
  87. const float MEM_SHARE_CONST = 0.5;
  88.  
  89. AllocMem allocate_mem_civically(int size)
  90. {
  91.   extern int getpagesize();
  92.   pagesize = getpagesize();
  93.   size = (int) (MEM_SHARE_CONST * size);
  94.   size -= pagesize * NUMBER_OF_PAGES_FREE;
  95.   size /= sizeof(int);
  96.   for (int* p = 0;;) {
  97.     p = new int[size];
  98.     if (p == 0 && size > 0) 
  99.       size >>= 1; 
  100.     else 
  101.       break;
  102.   }
  103.   AllocMem A(p, size);
  104.   return A;
  105. }
  106.  
  107. void is_enough_memory(int size)
  108. {
  109.   if (size < pagesize * MIN_NUMBER_OF_PAGES)
  110.     memory_allocator_error("not enough memory");
  111. }
  112.  
  113. AllocMem get_memory()
  114. {
  115.   AllocMem A = allocate_mem_civically(get_limit());
  116.   is_enough_memory(A.size);
  117.   return A;
  118. }  
  119.  
  120. int memory_sizes[LAST_SIZE];
  121. static int memory_coeffs[] = {
  122. #define use(Name,ID,Coeff,Reg,Type)\
  123.   Coeff,
  124. #include "memory_sizes.h"
  125. #undef use
  126. };
  127.  
  128. static inline int round(int i)
  129. {
  130.   int size = pagesize >> 2;
  131.   return ((int) (i / size)) * size;
  132. }
  133.  
  134. void compute_memory_sizes(int size) 
  135. {
  136.   int total_weight = 0;
  137.   for (int i = 0; i < LAST_SIZE; i++)
  138.     total_weight += memory_coeffs[i];
  139.   for (i = 0; i < LAST_SIZE; i++)
  140.     memory_sizes[i] = round((size * memory_coeffs[i]) / total_weight);
  141. }
  142.   
  143. void partition_memory(AllocMem mem)
  144. {
  145. #define use(Name,ID,Coeff,Reg,Type)\
  146.   Reg = (Type*) mem.p;\
  147.   mem.p += memory_sizes[ID];\
  148.   memory_sizes[ID] /= sizeof(Type) /sizeof(int);
  149. #include "memory_sizes.h"
  150. #undef use
  151. }
  152.  
  153. void Memory::allocate()
  154. {
  155.   AllocMem mem = get_memory();
  156.   int* top = mem.p + mem.size;
  157.   compute_memory_sizes(mem.size);
  158.   partition_memory(mem);
  159.   TR0 += memory_sizes[TRAIL_SIZE] - 1;
  160.   B0 += memory_sizes[CP_SIZE] - 1;
  161. }
  162.  
  163. void Memory::init()
  164. {
  165.   Cell* NewE = E0 + E_TOP_OFFSET;
  166.   B0 -= FIXED_CP_SIZE;
  167.   NewE[B_ENV_OFFSET] = cell(B0);
  168.   NewE[E_ENV_OFFSET] = cell(E0);
  169.   NewE[P_ENV_OFFSET] = cell(CP0);
  170.   E0 = NewE;
  171.  
  172.   B0[E_CP_OFFSET] = cell(E0);
  173.   B0[H_CP_OFFSET] = cell(H0);
  174.   B0[TR_CP_OFFSET] = cell(TR0);
  175.   B0[P_CP_OFFSET] = cell(NP0);
  176.   B0[SIZE_CP_OFFSET] = 0;
  177. }  
  178.  
  179. int next_instruction;
  180. Cell NIL;
  181. Cell LIST_FUNCTOR;
  182.  
  183. Memory::Memory(StringTable& table)
  184. {
  185.   ST = &table;
  186.   NIL = make_atom(ST->intern("[]"));
  187.   LIST_FUNCTOR = make_atom(ST->intern("./2"));
  188. }
  189.