diff options
| author | Richard M. Stallman | 1992-10-24 04:39:49 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1992-10-24 04:39:49 +0000 |
| commit | 7516b7d5218575461fb4d1b15515a1174554f349 (patch) | |
| tree | 7d6c332b952cbf503c92d83602ac58b2a9a9270f /src/ralloc.c | |
| parent | 55b0b31972975be6d7dfbcd11efbfcbfd97026ab (diff) | |
| download | emacs-7516b7d5218575461fb4d1b15515a1174554f349.tar.gz emacs-7516b7d5218575461fb4d1b15515a1174554f349.zip | |
(relinquish): Adjust page_break_value by amount of memory actually given back.
(r_alloc_sbrk): Provide hysteresis in relocating the blocs.
(relinquish): Never free less than extra_bytes;
keep extra_bytes of empty space.
(obtain): Always get extra_bytes additional space.
(r_alloc_init): Set extra_bytes and page_size.
(ALIGNED, ROUNDUP, ROUND_TO_PAGE): Use page_size.
Diffstat (limited to 'src/ralloc.c')
| -rw-r--r-- | src/ralloc.c | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/src/ralloc.c b/src/ralloc.c index 71c867901cb..4a76ebfb4ac 100644 --- a/src/ralloc.c +++ b/src/ralloc.c | |||
| @@ -88,12 +88,18 @@ static POINTER break_value; | |||
| 88 | /* The REAL (i.e., page aligned) break value of the process. */ | 88 | /* The REAL (i.e., page aligned) break value of the process. */ |
| 89 | static POINTER page_break_value; | 89 | static POINTER page_break_value; |
| 90 | 90 | ||
| 91 | /* This is the size of a page. We round memory requests to this boundary. */ | ||
| 92 | static int page_size; | ||
| 93 | |||
| 94 | /* Whenever we get memory from the system, get this many extra bytes. */ | ||
| 95 | static int extra_bytes; | ||
| 96 | |||
| 91 | /* Macros for rounding. Note that rounding to any value is possible | 97 | /* Macros for rounding. Note that rounding to any value is possible |
| 92 | by changing the definition of PAGE. */ | 98 | by changing the definition of PAGE. */ |
| 93 | #define PAGE (getpagesize ()) | 99 | #define PAGE (getpagesize ()) |
| 94 | #define ALIGNED(addr) (((unsigned int) (addr) & (PAGE - 1)) == 0) | 100 | #define ALIGNED(addr) (((unsigned int) (addr) & (page_size - 1)) == 0) |
| 95 | #define ROUNDUP(size) (((unsigned int) (size) + PAGE - 1) & ~(PAGE - 1)) | 101 | #define ROUNDUP(size) (((unsigned int) (size) + page_size - 1) & ~(page_size - 1)) |
| 96 | #define ROUND_TO_PAGE(addr) (addr & (~(PAGE - 1))) | 102 | #define ROUND_TO_PAGE(addr) (addr & (~(page_size - 1))) |
| 97 | 103 | ||
| 98 | /* Functions to get and return memory from the system. */ | 104 | /* Functions to get and return memory from the system. */ |
| 99 | 105 | ||
| @@ -112,6 +118,8 @@ obtain (size) | |||
| 112 | if (already_available < size) | 118 | if (already_available < size) |
| 113 | { | 119 | { |
| 114 | SIZE get = ROUNDUP (size - already_available); | 120 | SIZE get = ROUNDUP (size - already_available); |
| 121 | /* Get some extra, so we can come here less often. */ | ||
| 122 | get += extra_bytes; | ||
| 115 | 123 | ||
| 116 | if ((*real_morecore) (get) == 0) | 124 | if ((*real_morecore) (get) == 0) |
| 117 | return 0; | 125 | return 0; |
| @@ -146,17 +154,20 @@ relinquish (size) | |||
| 146 | SIZE size; | 154 | SIZE size; |
| 147 | { | 155 | { |
| 148 | POINTER new_page_break; | 156 | POINTER new_page_break; |
| 157 | int excess; | ||
| 149 | 158 | ||
| 150 | break_value -= size; | 159 | break_value -= size; |
| 151 | new_page_break = (POINTER) ROUNDUP (break_value); | 160 | new_page_break = (POINTER) ROUNDUP (break_value); |
| 161 | excess = (char *) page_break_value - (char *) new_page_break; | ||
| 152 | 162 | ||
| 153 | if (new_page_break != page_break_value) | 163 | if (excess > extra_bytes * 2) |
| 154 | { | 164 | { |
| 155 | if ((*real_morecore) ((char *) new_page_break | 165 | /* Keep extra_bytes worth of empty space. |
| 156 | - (char *) page_break_value) == 0) | 166 | And don't free anything unless we can free at least extra_bytes. */ |
| 167 | if ((*real_morecore) (extra_bytes - excess) == 0) | ||
| 157 | abort (); | 168 | abort (); |
| 158 | 169 | ||
| 159 | page_break_value = new_page_break; | 170 | page_break_value += extra_bytes - excess; |
| 160 | } | 171 | } |
| 161 | 172 | ||
| 162 | /* Zero the space from the end of the "official" break to the actual | 173 | /* Zero the space from the end of the "official" break to the actual |
| @@ -312,6 +323,8 @@ static int use_relocatable_buffers; | |||
| 312 | them. This function gets plugged into the GNU malloc's __morecore | 323 | them. This function gets plugged into the GNU malloc's __morecore |
| 313 | hook. | 324 | hook. |
| 314 | 325 | ||
| 326 | We provide hysteresis, never relocating by less than extra_bytes. | ||
| 327 | |||
| 315 | If we're out of memory, we should return zero, to imitate the other | 328 | If we're out of memory, we should return zero, to imitate the other |
| 316 | __morecore hook values - in particular, __default_morecore in the | 329 | __morecore hook values - in particular, __default_morecore in the |
| 317 | GNU malloc package. */ | 330 | GNU malloc package. */ |
| @@ -320,34 +333,50 @@ POINTER | |||
| 320 | r_alloc_sbrk (size) | 333 | r_alloc_sbrk (size) |
| 321 | long size; | 334 | long size; |
| 322 | { | 335 | { |
| 336 | /* This is the first address not currently available for the heap. */ | ||
| 337 | POINTER top; | ||
| 338 | /* Amount of empty space below that. */ | ||
| 339 | SIZE already_available; | ||
| 323 | POINTER ptr; | 340 | POINTER ptr; |
| 324 | 341 | ||
| 325 | if (! use_relocatable_buffers) | 342 | if (! use_relocatable_buffers) |
| 326 | return (*real_morecore) (size); | 343 | return (*real_morecore) (size); |
| 327 | 344 | ||
| 328 | if (size > 0) | 345 | top = first_bloc ? first_bloc->data : page_break_value; |
| 346 | already_available = (char *) top - (char *) virtual_break_value; | ||
| 347 | |||
| 348 | /* Do we not have enough gap already? */ | ||
| 349 | if (size > 0 && already_available < size) | ||
| 329 | { | 350 | { |
| 330 | if (! obtain (size)) | 351 | /* Get what we need, plus some extra so we can come here less often. */ |
| 352 | SIZE get = size - already_available + extra_bytes; | ||
| 353 | |||
| 354 | if (! obtain (get)) | ||
| 331 | return 0; | 355 | return 0; |
| 332 | 356 | ||
| 333 | if (first_bloc) | 357 | if (first_bloc) |
| 334 | { | 358 | { |
| 335 | relocate_some_blocs (first_bloc, first_bloc->data + size); | 359 | relocate_some_blocs (first_bloc, first_bloc->data + get); |
| 336 | 360 | ||
| 337 | /* Zero out the space we just allocated, to help catch bugs | 361 | /* Zero out the space we just allocated, to help catch bugs |
| 338 | quickly. */ | 362 | quickly. */ |
| 339 | bzero (virtual_break_value, size); | 363 | bzero (virtual_break_value, get); |
| 340 | } | 364 | } |
| 341 | } | 365 | } |
| 342 | else if (size < 0) | 366 | /* Can we keep extra_bytes of gap while freeing at least extra_bytes? */ |
| 367 | else if (size < 0 && already_available - size > 2 * extra_bytes) | ||
| 343 | { | 368 | { |
| 369 | /* Ok, do so. This is how many to free. */ | ||
| 370 | SIZE give_back = already_available - size - extra_bytes; | ||
| 371 | |||
| 344 | if (first_bloc) | 372 | if (first_bloc) |
| 345 | relocate_some_blocs (first_bloc, first_bloc->data + size); | 373 | relocate_some_blocs (first_bloc, first_bloc->data - give_back); |
| 346 | relinquish (- size); | 374 | relinquish (give_back); |
| 347 | } | 375 | } |
| 348 | 376 | ||
| 349 | ptr = virtual_break_value; | 377 | ptr = virtual_break_value; |
| 350 | virtual_break_value += size; | 378 | virtual_break_value += size; |
| 379 | |||
| 351 | return ptr; | 380 | return ptr; |
| 352 | } | 381 | } |
| 353 | 382 | ||
| @@ -456,6 +485,9 @@ r_alloc_init () | |||
| 456 | if (break_value == NIL) | 485 | if (break_value == NIL) |
| 457 | abort (); | 486 | abort (); |
| 458 | 487 | ||
| 488 | page_size = PAGE; | ||
| 489 | extra_bytes = ROUNDUP (50000); | ||
| 490 | |||
| 459 | page_break_value = (POINTER) ROUNDUP (break_value); | 491 | page_break_value = (POINTER) ROUNDUP (break_value); |
| 460 | /* Clear the rest of the last page; this memory is in our address space | 492 | /* Clear the rest of the last page; this memory is in our address space |
| 461 | even though it is after the sbrk value. */ | 493 | even though it is after the sbrk value. */ |