diff options
| author | Jim Blandy | 1992-09-29 01:08:33 +0000 |
|---|---|---|
| committer | Jim Blandy | 1992-09-29 01:08:33 +0000 |
| commit | 98b7fe026f670a7500bb379fea168fff4155b05c (patch) | |
| tree | 015ad9fcdca6d08879400ba89643c756edf3368d /src/ralloc.c | |
| parent | 350bce561c76197979c747bcab73ffa6fa5aee2b (diff) | |
| download | emacs-98b7fe026f670a7500bb379fea168fff4155b05c.tar.gz emacs-98b7fe026f670a7500bb379fea168fff4155b05c.zip | |
* ralloc.c: Since the users of the relocating allocation code
handle memory exhaustion, it's better to return an error code to
them than to call abort.
(obtain): If we cannot allocate more memory, don't call
abort. Instead, return non-zero iff the allocation is successful.
(get_more_space): If obtain fails, return zero.
(get_bloc): Return zero if we can't allocate the new bloc.
(r_alloc_sbrk): Return zero if we can't allocate more memory.
(r_alloc): If we can't allocate more memory, set *PTR to zero and
return zero.
(r_re_alloc): If we can't allocate more memory, leave *PTR
unchanged, and return zero.
* ralloc.c (warnfunction): Renamed to warn_function; users changed.
Diffstat (limited to 'src/ralloc.c')
| -rw-r--r-- | src/ralloc.c | 93 |
1 files changed, 64 insertions, 29 deletions
diff --git a/src/ralloc.c b/src/ralloc.c index b746d8c85e8..c43218eaefc 100644 --- a/src/ralloc.c +++ b/src/ralloc.c | |||
| @@ -60,7 +60,7 @@ static int warnlevel; | |||
| 60 | 60 | ||
| 61 | /* Function to call to issue a warning; | 61 | /* Function to call to issue a warning; |
| 62 | 0 means don't issue them. */ | 62 | 0 means don't issue them. */ |
| 63 | static void (*warnfunction) (); | 63 | static void (*warn_function) (); |
| 64 | 64 | ||
| 65 | static void | 65 | static void |
| 66 | check_memory_limits (address) | 66 | check_memory_limits (address) |
| @@ -74,7 +74,7 @@ check_memory_limits (address) | |||
| 74 | if (data_size > (lim_data / 4) * 3) | 74 | if (data_size > (lim_data / 4) * 3) |
| 75 | { | 75 | { |
| 76 | warnlevel++; | 76 | warnlevel++; |
| 77 | (*warnfunction) ("Warning: past 75% of memory limit"); | 77 | (*warn_function) ("Warning: past 75% of memory limit"); |
| 78 | } | 78 | } |
| 79 | break; | 79 | break; |
| 80 | 80 | ||
| @@ -82,7 +82,7 @@ check_memory_limits (address) | |||
| 82 | if (data_size > (lim_data / 20) * 17) | 82 | if (data_size > (lim_data / 20) * 17) |
| 83 | { | 83 | { |
| 84 | warnlevel++; | 84 | warnlevel++; |
| 85 | (*warnfunction) ("Warning: past 85% of memory limit"); | 85 | (*warn_function) ("Warning: past 85% of memory limit"); |
| 86 | } | 86 | } |
| 87 | break; | 87 | break; |
| 88 | 88 | ||
| @@ -90,12 +90,12 @@ check_memory_limits (address) | |||
| 90 | if (data_size > (lim_data / 20) * 19) | 90 | if (data_size > (lim_data / 20) * 19) |
| 91 | { | 91 | { |
| 92 | warnlevel++; | 92 | warnlevel++; |
| 93 | (*warnfunction) ("Warning: past 95% of memory limit"); | 93 | (*warn_function) ("Warning: past 95% of memory limit"); |
| 94 | } | 94 | } |
| 95 | break; | 95 | break; |
| 96 | 96 | ||
| 97 | default: | 97 | default: |
| 98 | (*warnfunction) ("Warning: past acceptable memory limits"); | 98 | (*warn_function) ("Warning: past acceptable memory limits"); |
| 99 | break; | 99 | break; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| @@ -107,9 +107,11 @@ check_memory_limits (address) | |||
| 107 | 107 | ||
| 108 | /* Obtain SIZE bytes of space. If enough space is not presently available | 108 | /* Obtain SIZE bytes of space. If enough space is not presently available |
| 109 | in our process reserve, (i.e., (page_break_value - break_value)), | 109 | in our process reserve, (i.e., (page_break_value - break_value)), |
| 110 | this means getting more page-aligned space from the system. */ | 110 | this means getting more page-aligned space from the system. |
| 111 | 111 | ||
| 112 | static void | 112 | Return non-zero if all went well, or zero if we couldn't allocate |
| 113 | the memory. */ | ||
| 114 | static int | ||
| 113 | obtain (size) | 115 | obtain (size) |
| 114 | SIZE size; | 116 | SIZE size; |
| 115 | { | 117 | { |
| @@ -119,27 +121,32 @@ obtain (size) | |||
| 119 | { | 121 | { |
| 120 | SIZE get = ROUNDUP (size - already_available); | 122 | SIZE get = ROUNDUP (size - already_available); |
| 121 | 123 | ||
| 122 | if (warnfunction) | 124 | if (warn_function) |
| 123 | check_memory_limits (page_break_value); | 125 | check_memory_limits (page_break_value); |
| 124 | 126 | ||
| 125 | if (((int) sbrk (get)) < 0) | 127 | if (((int) sbrk (get)) < 0) |
| 126 | abort (); | 128 | return 0; |
| 127 | 129 | ||
| 128 | page_break_value += get; | 130 | page_break_value += get; |
| 129 | } | 131 | } |
| 130 | 132 | ||
| 131 | break_value += size; | 133 | break_value += size; |
| 134 | |||
| 135 | return 1; | ||
| 132 | } | 136 | } |
| 133 | 137 | ||
| 134 | /* Obtain SIZE bytes of space and return a pointer to the new area. */ | 138 | /* Obtain SIZE bytes of space and return a pointer to the new area. |
| 139 | If we could not allocate the space, return zero. */ | ||
| 135 | 140 | ||
| 136 | static POINTER | 141 | static POINTER |
| 137 | get_more_space (size) | 142 | get_more_space (size) |
| 138 | SIZE size; | 143 | SIZE size; |
| 139 | { | 144 | { |
| 140 | POINTER ptr = break_value; | 145 | POINTER ptr = break_value; |
| 141 | obtain (size); | 146 | if (obtain (size)) |
| 142 | return ptr; | 147 | return ptr; |
| 148 | else | ||
| 149 | return 0; | ||
| 143 | } | 150 | } |
| 144 | 151 | ||
| 145 | /* Note that SIZE bytes of space have been relinquished by the process. | 152 | /* Note that SIZE bytes of space have been relinquished by the process. |
| @@ -214,15 +221,24 @@ find_bloc (ptr) | |||
| 214 | } | 221 | } |
| 215 | 222 | ||
| 216 | /* Allocate a bloc of SIZE bytes and append it to the chain of blocs. | 223 | /* Allocate a bloc of SIZE bytes and append it to the chain of blocs. |
| 217 | Returns a pointer to the new bloc. */ | 224 | Returns a pointer to the new bloc, or zero if we couldn't allocate |
| 225 | memory for the new block. */ | ||
| 218 | 226 | ||
| 219 | static bloc_ptr | 227 | static bloc_ptr |
| 220 | get_bloc (size) | 228 | get_bloc (size) |
| 221 | SIZE size; | 229 | SIZE size; |
| 222 | { | 230 | { |
| 223 | register bloc_ptr new_bloc = (bloc_ptr) malloc (BLOC_PTR_SIZE); | 231 | register bloc_ptr new_bloc; |
| 232 | |||
| 233 | if (! (new_bloc = (bloc_ptr) malloc (BLOC_PTR_SIZE)) | ||
| 234 | || ! (new_bloc->data = get_more_space (size))) | ||
| 235 | { | ||
| 236 | if (new_bloc) | ||
| 237 | free (new_bloc); | ||
| 238 | |||
| 239 | return 0; | ||
| 240 | } | ||
| 224 | 241 | ||
| 225 | new_bloc->data = get_more_space (size); | ||
| 226 | new_bloc->size = size; | 242 | new_bloc->size = size; |
| 227 | new_bloc->next = NIL_BLOC; | 243 | new_bloc->next = NIL_BLOC; |
| 228 | new_bloc->variable = (POINTER *) NIL; | 244 | new_bloc->variable = (POINTER *) NIL; |
| @@ -306,9 +322,14 @@ free_bloc (bloc) | |||
| 306 | 322 | ||
| 307 | static int use_relocatable_buffers; | 323 | static int use_relocatable_buffers; |
| 308 | 324 | ||
| 309 | /* Obtain SIZE bytes of storage from the free pool, or the system, | 325 | /* Obtain SIZE bytes of storage from the free pool, or the system, as |
| 310 | as neccessary. If relocatable blocs are in use, this means | 326 | neccessary. If relocatable blocs are in use, this means relocating |
| 311 | relocating them. */ | 327 | them. This function gets plugged into the GNU malloc's __morecore |
| 328 | hook. | ||
| 329 | |||
| 330 | If we're out of memory, we should return zero, to imitate the other | ||
| 331 | __morecore hook values - in particular, __default_morecore in the | ||
| 332 | GNU malloc package. */ | ||
| 312 | 333 | ||
| 313 | POINTER | 334 | POINTER |
| 314 | r_alloc_sbrk (size) | 335 | r_alloc_sbrk (size) |
| @@ -321,7 +342,9 @@ r_alloc_sbrk (size) | |||
| 321 | 342 | ||
| 322 | if (size > 0) | 343 | if (size > 0) |
| 323 | { | 344 | { |
| 324 | obtain (size); | 345 | if (! obtain (size)) |
| 346 | return 0; | ||
| 347 | |||
| 325 | if (first_bloc) | 348 | if (first_bloc) |
| 326 | { | 349 | { |
| 327 | relocate_some_blocs (first_bloc, first_bloc->data + size); | 350 | relocate_some_blocs (first_bloc, first_bloc->data + size); |
| @@ -345,7 +368,10 @@ r_alloc_sbrk (size) | |||
| 345 | 368 | ||
| 346 | /* Allocate a relocatable bloc of storage of size SIZE. A pointer to | 369 | /* Allocate a relocatable bloc of storage of size SIZE. A pointer to |
| 347 | the data is returned in *PTR. PTR is thus the address of some variable | 370 | the data is returned in *PTR. PTR is thus the address of some variable |
| 348 | which will use the data area. */ | 371 | which will use the data area. |
| 372 | |||
| 373 | If we can't allocate the necessary memory, set *PTR to zero, and | ||
| 374 | return zero. */ | ||
| 349 | 375 | ||
| 350 | POINTER | 376 | POINTER |
| 351 | r_alloc (ptr, size) | 377 | r_alloc (ptr, size) |
| @@ -355,8 +381,13 @@ r_alloc (ptr, size) | |||
| 355 | register bloc_ptr new_bloc; | 381 | register bloc_ptr new_bloc; |
| 356 | 382 | ||
| 357 | new_bloc = get_bloc (size); | 383 | new_bloc = get_bloc (size); |
| 358 | new_bloc->variable = ptr; | 384 | if (new_bloc) |
| 359 | *ptr = new_bloc->data; | 385 | { |
| 386 | new_bloc->variable = ptr; | ||
| 387 | *ptr = new_bloc->data; | ||
| 388 | } | ||
| 389 | else | ||
| 390 | *ptr = 0; | ||
| 360 | 391 | ||
| 361 | return *ptr; | 392 | return *ptr; |
| 362 | } | 393 | } |
| @@ -377,12 +408,14 @@ r_alloc_free (ptr) | |||
| 377 | } | 408 | } |
| 378 | 409 | ||
| 379 | /* Given a pointer at address PTR to relocatable data, resize it to SIZE. | 410 | /* Given a pointer at address PTR to relocatable data, resize it to SIZE. |
| 380 | This is done by shifting all blocks above this one up in memory, | 411 | Do this by shifting all blocks above this one up in memory, unless |
| 381 | unless SIZE is less than or equal to the current bloc size, in | 412 | SIZE is less than or equal to the current bloc size, in which case |
| 382 | which case nothing happens and the current value is returned. | 413 | do nothing. |
| 383 | 414 | ||
| 384 | The contents of PTR is changed to reflect the new bloc, and this | 415 | Change *PTR to reflect the new bloc, and return this value. |
| 385 | value is returned. */ | 416 | |
| 417 | If more memory cannot be allocated, then leave *PTR unchanged, and | ||
| 418 | return zero. */ | ||
| 386 | 419 | ||
| 387 | POINTER | 420 | POINTER |
| 388 | r_re_alloc (ptr, size) | 421 | r_re_alloc (ptr, size) |
| @@ -399,7 +432,9 @@ r_re_alloc (ptr, size) | |||
| 399 | /* Wouldn't it be useful to actually resize the bloc here? */ | 432 | /* Wouldn't it be useful to actually resize the bloc here? */ |
| 400 | return *ptr; | 433 | return *ptr; |
| 401 | 434 | ||
| 402 | obtain (size - bloc->size); | 435 | if (! obtain (size - bloc->size)) |
| 436 | return 0; | ||
| 437 | |||
| 403 | relocate_some_blocs (bloc->next, bloc->data + size); | 438 | relocate_some_blocs (bloc->next, bloc->data + size); |
| 404 | 439 | ||
| 405 | /* Zero out the new space in the bloc, to help catch bugs faster. */ | 440 | /* Zero out the new space in the bloc, to help catch bugs faster. */ |
| @@ -450,7 +485,7 @@ malloc_init (start, warn_func) | |||
| 450 | 485 | ||
| 451 | lim_data = 0; | 486 | lim_data = 0; |
| 452 | warnlevel = 0; | 487 | warnlevel = 0; |
| 453 | warnfunction = warn_func; | 488 | warn_function = warn_func; |
| 454 | 489 | ||
| 455 | get_lim_data (); | 490 | get_lim_data (); |
| 456 | } | 491 | } |