123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- #include <limits.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <string.h>
- #include "malloc.h"
- #define MIN(A, B) ((A) < (B) ? (A) : (B))
- void *
- realloc (void *ptr, size_t size)
- {
- void *result, *previous;
- int block, blocks, type;
- int oldlimit;
- if (!ptr)
- return malloc(size);
- if (!size) {
- free(ptr);
- return malloc(0);
- }
- block = BLOCK(ptr);
- switch (type = _heapinfo[block].busy.type) {
- case 0:
-
- if (size <= BLOCKSIZE / 2) {
- if ((result = malloc(size)) != NULL) {
- memcpy(result, ptr, size);
- #if 1
- free(ptr);
- #else
- _free_internal(ptr);
- #endif
- }
- return result;
- }
-
- blocks = BLOCKIFY(size);
- if (blocks < _heapinfo[block].busy.info.size) {
-
- _heapinfo[block + blocks].busy.type = 0;
- _heapinfo[block + blocks].busy.info.size
- = _heapinfo[block].busy.info.size - blocks;
- _heapinfo[block].busy.info.size = blocks;
- #if 1
- free(ADDRESS(block + blocks));
- #else
- _free_internal(ADDRESS(block + blocks));
- #endif
- return ptr;
- } else if (blocks == _heapinfo[block].busy.info.size)
-
- return ptr;
- else {
-
- blocks = _heapinfo[block].busy.info.size;
-
- oldlimit = _heaplimit;
- _heaplimit = 0;
- #if 1
- free(ptr);
- #else
- _free_internal(ptr);
- #endif
- _heaplimit = oldlimit;
- result = malloc(size);
- if (!result) {
-
- if (_heapindex == block)
- malloc(blocks * BLOCKSIZE);
- else {
- previous = malloc((block - _heapindex) * BLOCKSIZE);
- malloc(blocks * BLOCKSIZE);
- #if 1
- free(previous);
- #else
- _free_internal(previous);
- #endif
- }
- return NULL;
- }
- if (ptr != result)
- memmove(result, ptr, blocks * BLOCKSIZE);
- return result;
- }
- break;
- default:
-
- if ((size > 1 << (type - 1)) && (size <= 1 << type))
-
- return ptr;
- else {
-
- result = malloc(size);
- if (!result)
- return NULL;
- memcpy(result, ptr, MIN(size, 1 << type));
- free(ptr);
- return result;
- }
- break;
- }
- }
|