Mercurial > emacs
comparison src/gmalloc.c @ 78051:2c30fdff6890
[HAVE_GTK_AND_PTHREAD] Check this after including config.h.
(_aligned_blocks_mutex) [USE_PTHREAD]: New variable.
(LOCK_ALIGNED_BLOCKS, UNLOCK_ALIGNED_BLOCKS): New macros.
(_free_internal, memalign): Use them.
(_malloc_mutex, _aligned_blocks_mutex) [USE_PTHREAD]:
Initialize to PTHREAD_MUTEX_INITIALIZER.
(malloc_initialize_1) [USE_PTHREAD]: Don't use recursive mutex.
(morecore_nolock): Rename from morecore. All uses changed.
Use only nolock versions of internal allocation functions.
(_malloc_internal_nolock, _realloc_internal_nolock)
(_free_internal_nolock): New functions created from
_malloc_internal, _realloc_internal, and _free_internal.
(_malloc_internal, _realloc_internal, _free_internal): Use them.
Copy hook value to automatic variable before its use.
(memalign): Copy hook value to automatic variable before its use.
| author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> |
|---|---|
| date | Tue, 26 Jun 2007 03:29:05 +0000 |
| parents | 2bb28b957639 |
| children | 77430fdfce38 |
comparison
equal
deleted
inserted
replaced
| 78050:74d45d6140ca | 78051:2c30fdff6890 |
|---|---|
| 1 /* This file is no longer automatically generated from libc. */ | 1 /* This file is no longer automatically generated from libc. */ |
| 2 | 2 |
| 3 #define _MALLOC_INTERNAL | 3 #define _MALLOC_INTERNAL |
| 4 #ifdef HAVE_GTK_AND_PTHREAD | |
| 5 #define USE_PTHREAD | |
| 6 #endif | |
| 7 | 4 |
| 8 /* The malloc headers and source files from the C library follow here. */ | 5 /* The malloc headers and source files from the C library follow here. */ |
| 9 | 6 |
| 10 /* Declarations for `malloc' and friends. | 7 /* Declarations for `malloc' and friends. |
| 11 Copyright (C) 1990, 1991, 1992, 1993, 1995, 1996, 1999, 2002, 2003, 2004, | 8 Copyright (C) 1990, 1991, 1992, 1993, 1995, 1996, 1999, 2002, 2003, 2004, |
| 36 | 33 |
| 37 #ifdef _MALLOC_INTERNAL | 34 #ifdef _MALLOC_INTERNAL |
| 38 | 35 |
| 39 #ifdef HAVE_CONFIG_H | 36 #ifdef HAVE_CONFIG_H |
| 40 #include <config.h> | 37 #include <config.h> |
| 38 #endif | |
| 39 | |
| 40 #ifdef HAVE_GTK_AND_PTHREAD | |
| 41 #define USE_PTHREAD | |
| 41 #endif | 42 #endif |
| 42 | 43 |
| 43 #if ((defined __cplusplus || (defined (__STDC__) && __STDC__) \ | 44 #if ((defined __cplusplus || (defined (__STDC__) && __STDC__) \ |
| 44 || defined STDC_HEADERS || defined PROTOTYPES) \ | 45 || defined STDC_HEADERS || defined PROTOTYPES) \ |
| 45 && ! defined (BROKEN_PROTOTYPES)) | 46 && ! defined (BROKEN_PROTOTYPES)) |
| 233 used when these functions need to call each other. | 234 used when these functions need to call each other. |
| 234 They are the same but don't call the hooks. */ | 235 They are the same but don't call the hooks. */ |
| 235 extern __ptr_t _malloc_internal PP ((__malloc_size_t __size)); | 236 extern __ptr_t _malloc_internal PP ((__malloc_size_t __size)); |
| 236 extern __ptr_t _realloc_internal PP ((__ptr_t __ptr, __malloc_size_t __size)); | 237 extern __ptr_t _realloc_internal PP ((__ptr_t __ptr, __malloc_size_t __size)); |
| 237 extern void _free_internal PP ((__ptr_t __ptr)); | 238 extern void _free_internal PP ((__ptr_t __ptr)); |
| 239 extern __ptr_t _malloc_internal_nolock PP ((__malloc_size_t __size)); | |
| 240 extern __ptr_t _realloc_internal_nolock PP ((__ptr_t __ptr, __malloc_size_t __size)); | |
| 241 extern void _free_internal_nolock PP ((__ptr_t __ptr)); | |
| 238 | 242 |
| 239 #ifdef USE_PTHREAD | 243 #ifdef USE_PTHREAD |
| 240 extern pthread_mutex_t _malloc_mutex; | 244 extern pthread_mutex_t _malloc_mutex, _aligned_blocks_mutex; |
| 241 #define LOCK() pthread_mutex_lock (&_malloc_mutex) | 245 #define LOCK() pthread_mutex_lock (&_malloc_mutex) |
| 242 #define UNLOCK() pthread_mutex_unlock (&_malloc_mutex) | 246 #define UNLOCK() pthread_mutex_unlock (&_malloc_mutex) |
| 247 #define LOCK_ALIGNED_BLOCKS() pthread_mutex_lock (&_aligned_blocks_mutex) | |
| 248 #define UNLOCK_ALIGNED_BLOCKS() pthread_mutex_unlock (&_aligned_blocks_mutex) | |
| 243 #else | 249 #else |
| 244 #define LOCK() | 250 #define LOCK() |
| 245 #define UNLOCK() | 251 #define UNLOCK() |
| 252 #define LOCK_ALIGNED_BLOCKS() | |
| 253 #define UNLOCK_ALIGNED_BLOCKS() | |
| 246 #endif | 254 #endif |
| 247 | 255 |
| 248 #endif /* _MALLOC_INTERNAL. */ | 256 #endif /* _MALLOC_INTERNAL. */ |
| 249 | 257 |
| 250 /* Given an address in the middle of a malloc'd object, | 258 /* Given an address in the middle of a malloc'd object, |
| 552 _heapinfo[block + blocks].busy.info.size = -blocks; | 560 _heapinfo[block + blocks].busy.info.size = -blocks; |
| 553 } | 561 } |
| 554 | 562 |
| 555 #ifdef USE_PTHREAD | 563 #ifdef USE_PTHREAD |
| 556 static pthread_once_t malloc_init_once_control = PTHREAD_ONCE_INIT; | 564 static pthread_once_t malloc_init_once_control = PTHREAD_ONCE_INIT; |
| 557 pthread_mutex_t _malloc_mutex; | 565 pthread_mutex_t _malloc_mutex = PTHREAD_MUTEX_INITIALIZER; |
| 566 pthread_mutex_t _aligned_blocks_mutex = PTHREAD_MUTEX_INITIALIZER; | |
| 558 #endif | 567 #endif |
| 559 | 568 |
| 560 static void | 569 static void |
| 561 malloc_initialize_1 () | 570 malloc_initialize_1 () |
| 562 { | 571 { |
| 565 #endif | 574 #endif |
| 566 | 575 |
| 567 if (__malloc_initialize_hook) | 576 if (__malloc_initialize_hook) |
| 568 (*__malloc_initialize_hook) (); | 577 (*__malloc_initialize_hook) (); |
| 569 | 578 |
| 570 #ifdef USE_PTHREAD | 579 /* We don't use recursive mutex because pthread_mutexattr_init may |
| 580 call malloc internally. */ | |
| 581 #if 0 /* defined (USE_PTHREAD) */ | |
| 571 { | 582 { |
| 572 pthread_mutexattr_t attr; | 583 pthread_mutexattr_t attr; |
| 573 | 584 |
| 574 pthread_mutexattr_init (&attr); | 585 pthread_mutexattr_init (&attr); |
| 575 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); | 586 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); |
| 614 | 625 |
| 615 static int morecore_recursing; | 626 static int morecore_recursing; |
| 616 | 627 |
| 617 /* Get neatly aligned memory, initializing or | 628 /* Get neatly aligned memory, initializing or |
| 618 growing the heap info table as necessary. */ | 629 growing the heap info table as necessary. */ |
| 619 static __ptr_t morecore PP ((__malloc_size_t)); | 630 static __ptr_t morecore_nolock PP ((__malloc_size_t)); |
| 620 static __ptr_t | 631 static __ptr_t |
| 621 morecore (size) | 632 morecore_nolock (size) |
| 622 __malloc_size_t size; | 633 __malloc_size_t size; |
| 623 { | 634 { |
| 624 __ptr_t result; | 635 __ptr_t result; |
| 625 malloc_info *newinfo, *oldinfo; | 636 malloc_info *newinfo, *oldinfo; |
| 626 __malloc_size_t newsize; | 637 __malloc_size_t newsize; |
| 659 extend it in place or relocate it to existing sufficient core, | 670 extend it in place or relocate it to existing sufficient core, |
| 660 we will get called again, and the code above will notice the | 671 we will get called again, and the code above will notice the |
| 661 `morecore_recursing' flag and return null. */ | 672 `morecore_recursing' flag and return null. */ |
| 662 int save = errno; /* Don't want to clobber errno with ENOMEM. */ | 673 int save = errno; /* Don't want to clobber errno with ENOMEM. */ |
| 663 morecore_recursing = 1; | 674 morecore_recursing = 1; |
| 664 newinfo = (malloc_info *) _realloc_internal | 675 newinfo = (malloc_info *) _realloc_internal_nolock |
| 665 (_heapinfo, newsize * sizeof (malloc_info)); | 676 (_heapinfo, newsize * sizeof (malloc_info)); |
| 666 morecore_recursing = 0; | 677 morecore_recursing = 0; |
| 667 if (newinfo == NULL) | 678 if (newinfo == NULL) |
| 668 errno = save; | 679 errno = save; |
| 669 else | 680 else |
| 715 register_heapinfo (); | 726 register_heapinfo (); |
| 716 | 727 |
| 717 /* Reset _heaplimit so _free_internal never decides | 728 /* Reset _heaplimit so _free_internal never decides |
| 718 it can relocate or resize the info table. */ | 729 it can relocate or resize the info table. */ |
| 719 _heaplimit = 0; | 730 _heaplimit = 0; |
| 720 _free_internal (oldinfo); | 731 _free_internal_nolock (oldinfo); |
| 721 PROTECT_MALLOC_STATE (0); | 732 PROTECT_MALLOC_STATE (0); |
| 722 | 733 |
| 723 /* The new heap limit includes the new table just allocated. */ | 734 /* The new heap limit includes the new table just allocated. */ |
| 724 _heaplimit = BLOCK ((char *) newinfo + heapsize * sizeof (malloc_info)); | 735 _heaplimit = BLOCK ((char *) newinfo + heapsize * sizeof (malloc_info)); |
| 725 return result; | 736 return result; |
| 730 return result; | 741 return result; |
| 731 } | 742 } |
| 732 | 743 |
| 733 /* Allocate memory from the heap. */ | 744 /* Allocate memory from the heap. */ |
| 734 __ptr_t | 745 __ptr_t |
| 735 _malloc_internal (size) | 746 _malloc_internal_nolock (size) |
| 736 __malloc_size_t size; | 747 __malloc_size_t size; |
| 737 { | 748 { |
| 738 __ptr_t result; | 749 __ptr_t result; |
| 739 __malloc_size_t block, blocks, lastblocks, start; | 750 __malloc_size_t block, blocks, lastblocks, start; |
| 740 register __malloc_size_t i; | 751 register __malloc_size_t i; |
| 750 #if 0 | 761 #if 0 |
| 751 if (size == 0) | 762 if (size == 0) |
| 752 return NULL; | 763 return NULL; |
| 753 #endif | 764 #endif |
| 754 | 765 |
| 755 LOCK (); | |
| 756 PROTECT_MALLOC_STATE (0); | 766 PROTECT_MALLOC_STATE (0); |
| 757 | 767 |
| 758 if (size < sizeof (struct list)) | 768 if (size < sizeof (struct list)) |
| 759 size = sizeof (struct list); | 769 size = sizeof (struct list); |
| 760 | 770 |
| 800 else | 810 else |
| 801 { | 811 { |
| 802 /* No free fragments of the desired size, so get a new block | 812 /* No free fragments of the desired size, so get a new block |
| 803 and break it into fragments, returning the first. */ | 813 and break it into fragments, returning the first. */ |
| 804 #ifdef GC_MALLOC_CHECK | 814 #ifdef GC_MALLOC_CHECK |
| 805 result = _malloc_internal (BLOCKSIZE); | 815 result = _malloc_internal_nolock (BLOCKSIZE); |
| 806 PROTECT_MALLOC_STATE (0); | 816 PROTECT_MALLOC_STATE (0); |
| 817 #elif defined (USE_PTHREAD) | |
| 818 result = _malloc_internal_nolock (BLOCKSIZE); | |
| 807 #else | 819 #else |
| 808 result = malloc (BLOCKSIZE); | 820 result = malloc (BLOCKSIZE); |
| 809 #endif | 821 #endif |
| 810 if (result == NULL) | 822 if (result == NULL) |
| 811 { | 823 { |
| 872 _heapinfo[block].free.size += (wantblocks - lastblocks); | 884 _heapinfo[block].free.size += (wantblocks - lastblocks); |
| 873 _bytes_free += (wantblocks - lastblocks) * BLOCKSIZE; | 885 _bytes_free += (wantblocks - lastblocks) * BLOCKSIZE; |
| 874 _heaplimit += wantblocks - lastblocks; | 886 _heaplimit += wantblocks - lastblocks; |
| 875 continue; | 887 continue; |
| 876 } | 888 } |
| 877 result = morecore (wantblocks * BLOCKSIZE); | 889 result = morecore_nolock (wantblocks * BLOCKSIZE); |
| 878 if (result == NULL) | 890 if (result == NULL) |
| 879 goto out; | 891 goto out; |
| 880 block = BLOCK (result); | 892 block = BLOCK (result); |
| 881 /* Put the new block at the end of the free list. */ | 893 /* Put the new block at the end of the free list. */ |
| 882 _heapinfo[block].free.size = wantblocks; | 894 _heapinfo[block].free.size = wantblocks; |
| 930 _heapinfo[block + blocks].busy.info.size = -blocks; | 942 _heapinfo[block + blocks].busy.info.size = -blocks; |
| 931 } | 943 } |
| 932 | 944 |
| 933 PROTECT_MALLOC_STATE (1); | 945 PROTECT_MALLOC_STATE (1); |
| 934 out: | 946 out: |
| 947 return result; | |
| 948 } | |
| 949 | |
| 950 __ptr_t | |
| 951 _malloc_internal (size) | |
| 952 __malloc_size_t size; | |
| 953 { | |
| 954 __ptr_t result; | |
| 955 | |
| 956 LOCK (); | |
| 957 result = _malloc_internal_nolock (size); | |
| 935 UNLOCK (); | 958 UNLOCK (); |
| 959 | |
| 936 return result; | 960 return result; |
| 937 } | 961 } |
| 938 | 962 |
| 939 __ptr_t | 963 __ptr_t |
| 940 malloc (size) | 964 malloc (size) |
| 941 __malloc_size_t size; | 965 __malloc_size_t size; |
| 942 { | 966 { |
| 967 __ptr_t (*hook) (__malloc_size_t); | |
| 968 | |
| 943 if (!__malloc_initialized && !__malloc_initialize ()) | 969 if (!__malloc_initialized && !__malloc_initialize ()) |
| 944 return NULL; | 970 return NULL; |
| 945 | 971 |
| 946 return (__malloc_hook != NULL ? *__malloc_hook : _malloc_internal) (size); | 972 /* Copy the value of __malloc_hook to an automatic variable in case |
| 973 __malloc_hook is modified in another thread between its | |
| 974 NULL-check and the use. | |
| 975 | |
| 976 Note: Strictly speaking, this is not a right solution. We should | |
| 977 use mutexes to access non-read-only variables that are shared | |
| 978 among multiple threads. We just leave it for compatibility with | |
| 979 glibc malloc (i.e., assignments to __malloc_hook) for now. */ | |
| 980 hook = __malloc_hook; | |
| 981 return (hook != NULL ? *hook : _malloc_internal) (size); | |
| 947 } | 982 } |
| 948 | 983 |
| 949 #ifndef _LIBC | 984 #ifndef _LIBC |
| 950 | 985 |
| 951 /* On some ANSI C systems, some libc functions call _malloc, _free | 986 /* On some ANSI C systems, some libc functions call _malloc, _free |
| 1022 | 1057 |
| 1023 /* List of blocks allocated by memalign. */ | 1058 /* List of blocks allocated by memalign. */ |
| 1024 struct alignlist *_aligned_blocks = NULL; | 1059 struct alignlist *_aligned_blocks = NULL; |
| 1025 | 1060 |
| 1026 /* Return memory to the heap. | 1061 /* Return memory to the heap. |
| 1027 Like `free' but don't call a __free_hook if there is one. */ | 1062 Like `_free_internal' but don't lock mutex. */ |
| 1028 void | 1063 void |
| 1029 _free_internal (ptr) | 1064 _free_internal_nolock (ptr) |
| 1030 __ptr_t ptr; | 1065 __ptr_t ptr; |
| 1031 { | 1066 { |
| 1032 int type; | 1067 int type; |
| 1033 __malloc_size_t block, blocks; | 1068 __malloc_size_t block, blocks; |
| 1034 register __malloc_size_t i; | 1069 register __malloc_size_t i; |
| 1041 register struct alignlist *l; | 1076 register struct alignlist *l; |
| 1042 | 1077 |
| 1043 if (ptr == NULL) | 1078 if (ptr == NULL) |
| 1044 return; | 1079 return; |
| 1045 | 1080 |
| 1046 LOCK (); | |
| 1047 PROTECT_MALLOC_STATE (0); | 1081 PROTECT_MALLOC_STATE (0); |
| 1048 | 1082 |
| 1083 LOCK_ALIGNED_BLOCKS (); | |
| 1049 for (l = _aligned_blocks; l != NULL; l = l->next) | 1084 for (l = _aligned_blocks; l != NULL; l = l->next) |
| 1050 if (l->aligned == ptr) | 1085 if (l->aligned == ptr) |
| 1051 { | 1086 { |
| 1052 l->aligned = NULL; /* Mark the slot in the list as free. */ | 1087 l->aligned = NULL; /* Mark the slot in the list as free. */ |
| 1053 ptr = l->exact; | 1088 ptr = l->exact; |
| 1054 break; | 1089 break; |
| 1055 } | 1090 } |
| 1091 UNLOCK_ALIGNED_BLOCKS (); | |
| 1056 | 1092 |
| 1057 block = BLOCK (ptr); | 1093 block = BLOCK (ptr); |
| 1058 | 1094 |
| 1059 type = _heapinfo[block].busy.type; | 1095 type = _heapinfo[block].busy.type; |
| 1060 switch (type) | 1096 switch (type) |
| 1156 /* Free the old info table, clearing _heaplimit to avoid | 1192 /* Free the old info table, clearing _heaplimit to avoid |
| 1157 recursion into this code. We don't want to return the | 1193 recursion into this code. We don't want to return the |
| 1158 table's blocks to the system before we have copied them to | 1194 table's blocks to the system before we have copied them to |
| 1159 the new location. */ | 1195 the new location. */ |
| 1160 _heaplimit = 0; | 1196 _heaplimit = 0; |
| 1161 _free_internal (_heapinfo); | 1197 _free_internal_nolock (_heapinfo); |
| 1162 _heaplimit = oldlimit; | 1198 _heaplimit = oldlimit; |
| 1163 | 1199 |
| 1164 /* Tell malloc to search from the beginning of the heap for | 1200 /* Tell malloc to search from the beginning of the heap for |
| 1165 free blocks, so it doesn't reuse the ones just freed. */ | 1201 free blocks, so it doesn't reuse the ones just freed. */ |
| 1166 _heapindex = 0; | 1202 _heapindex = 0; |
| 1167 | 1203 |
| 1168 /* Allocate new space for the info table and move its data. */ | 1204 /* Allocate new space for the info table and move its data. */ |
| 1169 newinfo = (malloc_info *) _malloc_internal (info_blocks | 1205 newinfo = (malloc_info *) _malloc_internal_nolock (info_blocks |
| 1170 * BLOCKSIZE); | 1206 * BLOCKSIZE); |
| 1171 PROTECT_MALLOC_STATE (0); | 1207 PROTECT_MALLOC_STATE (0); |
| 1172 memmove (newinfo, _heapinfo, info_blocks * BLOCKSIZE); | 1208 memmove (newinfo, _heapinfo, info_blocks * BLOCKSIZE); |
| 1173 _heapinfo = newinfo; | 1209 _heapinfo = newinfo; |
| 1174 | 1210 |
| 1175 /* We should now have coalesced the free block with the | 1211 /* We should now have coalesced the free block with the |
| 1228 ++_chunks_used; | 1264 ++_chunks_used; |
| 1229 _bytes_used += BLOCKSIZE; | 1265 _bytes_used += BLOCKSIZE; |
| 1230 _chunks_free -= BLOCKSIZE >> type; | 1266 _chunks_free -= BLOCKSIZE >> type; |
| 1231 _bytes_free -= BLOCKSIZE; | 1267 _bytes_free -= BLOCKSIZE; |
| 1232 | 1268 |
| 1233 #ifdef GC_MALLOC_CHECK | 1269 #if defined (GC_MALLOC_CHECK) || defined (USE_PTHREAD) |
| 1234 _free_internal (ADDRESS (block)); | 1270 _free_internal_nolock (ADDRESS (block)); |
| 1235 #else | 1271 #else |
| 1236 free (ADDRESS (block)); | 1272 free (ADDRESS (block)); |
| 1237 #endif | 1273 #endif |
| 1238 } | 1274 } |
| 1239 else if (_heapinfo[block].busy.info.frag.nfree != 0) | 1275 else if (_heapinfo[block].busy.info.frag.nfree != 0) |
| 1267 } | 1303 } |
| 1268 break; | 1304 break; |
| 1269 } | 1305 } |
| 1270 | 1306 |
| 1271 PROTECT_MALLOC_STATE (1); | 1307 PROTECT_MALLOC_STATE (1); |
| 1308 } | |
| 1309 | |
| 1310 /* Return memory to the heap. | |
| 1311 Like `free' but don't call a __free_hook if there is one. */ | |
| 1312 void | |
| 1313 _free_internal (ptr) | |
| 1314 __ptr_t ptr; | |
| 1315 { | |
| 1316 LOCK (); | |
| 1317 _free_internal_nolock (ptr); | |
| 1272 UNLOCK (); | 1318 UNLOCK (); |
| 1273 } | 1319 } |
| 1274 | 1320 |
| 1275 /* Return memory to the heap. */ | 1321 /* Return memory to the heap. */ |
| 1276 | 1322 |
| 1277 FREE_RETURN_TYPE | 1323 FREE_RETURN_TYPE |
| 1278 free (ptr) | 1324 free (ptr) |
| 1279 __ptr_t ptr; | 1325 __ptr_t ptr; |
| 1280 { | 1326 { |
| 1281 if (__free_hook != NULL) | 1327 void (*hook) (__ptr_t) = __free_hook; |
| 1282 (*__free_hook) (ptr); | 1328 |
| 1329 if (hook != NULL) | |
| 1330 (*hook) (ptr); | |
| 1283 else | 1331 else |
| 1284 _free_internal (ptr); | 1332 _free_internal (ptr); |
| 1285 } | 1333 } |
| 1286 | 1334 |
| 1287 /* Define the `cfree' alias for `free'. */ | 1335 /* Define the `cfree' alias for `free'. */ |
| 1413 some benchmarks seem to indicate that greater compactness is | 1461 some benchmarks seem to indicate that greater compactness is |
| 1414 achieved by unconditionally allocating and copying to a | 1462 achieved by unconditionally allocating and copying to a |
| 1415 new region. This module has incestuous knowledge of the | 1463 new region. This module has incestuous knowledge of the |
| 1416 internals of both free and malloc. */ | 1464 internals of both free and malloc. */ |
| 1417 __ptr_t | 1465 __ptr_t |
| 1418 _realloc_internal (ptr, size) | 1466 _realloc_internal_nolock (ptr, size) |
| 1419 __ptr_t ptr; | 1467 __ptr_t ptr; |
| 1420 __malloc_size_t size; | 1468 __malloc_size_t size; |
| 1421 { | 1469 { |
| 1422 __ptr_t result; | 1470 __ptr_t result; |
| 1423 int type; | 1471 int type; |
| 1424 __malloc_size_t block, blocks, oldlimit; | 1472 __malloc_size_t block, blocks, oldlimit; |
| 1425 | 1473 |
| 1426 if (size == 0) | 1474 if (size == 0) |
| 1427 { | 1475 { |
| 1428 _free_internal (ptr); | 1476 _free_internal_nolock (ptr); |
| 1429 return _malloc_internal (0); | 1477 return _malloc_internal_nolock (0); |
| 1430 } | 1478 } |
| 1431 else if (ptr == NULL) | 1479 else if (ptr == NULL) |
| 1432 return _malloc_internal (size); | 1480 return _malloc_internal_nolock (size); |
| 1433 | 1481 |
| 1434 block = BLOCK (ptr); | 1482 block = BLOCK (ptr); |
| 1435 | 1483 |
| 1436 LOCK (); | |
| 1437 PROTECT_MALLOC_STATE (0); | 1484 PROTECT_MALLOC_STATE (0); |
| 1438 | 1485 |
| 1439 type = _heapinfo[block].busy.type; | 1486 type = _heapinfo[block].busy.type; |
| 1440 switch (type) | 1487 switch (type) |
| 1441 { | 1488 { |
| 1442 case 0: | 1489 case 0: |
| 1443 /* Maybe reallocate a large block to a small fragment. */ | 1490 /* Maybe reallocate a large block to a small fragment. */ |
| 1444 if (size <= BLOCKSIZE / 2) | 1491 if (size <= BLOCKSIZE / 2) |
| 1445 { | 1492 { |
| 1446 result = _malloc_internal (size); | 1493 result = _malloc_internal_nolock (size); |
| 1447 if (result != NULL) | 1494 if (result != NULL) |
| 1448 { | 1495 { |
| 1449 memcpy (result, ptr, size); | 1496 memcpy (result, ptr, size); |
| 1450 _free_internal (ptr); | 1497 _free_internal_nolock (ptr); |
| 1451 goto out; | 1498 goto out; |
| 1452 } | 1499 } |
| 1453 } | 1500 } |
| 1454 | 1501 |
| 1455 /* The new size is a large allocation as well; | 1502 /* The new size is a large allocation as well; |
| 1465 _heapinfo[block].busy.info.size = blocks; | 1512 _heapinfo[block].busy.info.size = blocks; |
| 1466 /* We have just created a new chunk by splitting a chunk in two. | 1513 /* We have just created a new chunk by splitting a chunk in two. |
| 1467 Now we will free this chunk; increment the statistics counter | 1514 Now we will free this chunk; increment the statistics counter |
| 1468 so it doesn't become wrong when _free_internal decrements it. */ | 1515 so it doesn't become wrong when _free_internal decrements it. */ |
| 1469 ++_chunks_used; | 1516 ++_chunks_used; |
| 1470 _free_internal (ADDRESS (block + blocks)); | 1517 _free_internal_nolock (ADDRESS (block + blocks)); |
| 1471 result = ptr; | 1518 result = ptr; |
| 1472 } | 1519 } |
| 1473 else if (blocks == _heapinfo[block].busy.info.size) | 1520 else if (blocks == _heapinfo[block].busy.info.size) |
| 1474 /* No size change necessary. */ | 1521 /* No size change necessary. */ |
| 1475 result = ptr; | 1522 result = ptr; |
| 1480 adjacent free space to grow without moving. */ | 1527 adjacent free space to grow without moving. */ |
| 1481 blocks = _heapinfo[block].busy.info.size; | 1528 blocks = _heapinfo[block].busy.info.size; |
| 1482 /* Prevent free from actually returning memory to the system. */ | 1529 /* Prevent free from actually returning memory to the system. */ |
| 1483 oldlimit = _heaplimit; | 1530 oldlimit = _heaplimit; |
| 1484 _heaplimit = 0; | 1531 _heaplimit = 0; |
| 1485 _free_internal (ptr); | 1532 _free_internal_nolock (ptr); |
| 1486 result = _malloc_internal (size); | 1533 result = _malloc_internal_nolock (size); |
| 1487 PROTECT_MALLOC_STATE (0); | 1534 PROTECT_MALLOC_STATE (0); |
| 1488 if (_heaplimit == 0) | 1535 if (_heaplimit == 0) |
| 1489 _heaplimit = oldlimit; | 1536 _heaplimit = oldlimit; |
| 1490 if (result == NULL) | 1537 if (result == NULL) |
| 1491 { | 1538 { |
| 1492 /* Now we're really in trouble. We have to unfree | 1539 /* Now we're really in trouble. We have to unfree |
| 1493 the thing we just freed. Unfortunately it might | 1540 the thing we just freed. Unfortunately it might |
| 1494 have been coalesced with its neighbors. */ | 1541 have been coalesced with its neighbors. */ |
| 1495 if (_heapindex == block) | 1542 if (_heapindex == block) |
| 1496 (void) _malloc_internal (blocks * BLOCKSIZE); | 1543 (void) _malloc_internal_nolock (blocks * BLOCKSIZE); |
| 1497 else | 1544 else |
| 1498 { | 1545 { |
| 1499 __ptr_t previous | 1546 __ptr_t previous |
| 1500 = _malloc_internal ((block - _heapindex) * BLOCKSIZE); | 1547 = _malloc_internal_nolock ((block - _heapindex) * BLOCKSIZE); |
| 1501 (void) _malloc_internal (blocks * BLOCKSIZE); | 1548 (void) _malloc_internal_nolock (blocks * BLOCKSIZE); |
| 1502 _free_internal (previous); | 1549 _free_internal_nolock (previous); |
| 1503 } | 1550 } |
| 1504 goto out; | 1551 goto out; |
| 1505 } | 1552 } |
| 1506 if (ptr != result) | 1553 if (ptr != result) |
| 1507 memmove (result, ptr, blocks * BLOCKSIZE); | 1554 memmove (result, ptr, blocks * BLOCKSIZE); |
| 1517 result = ptr; | 1564 result = ptr; |
| 1518 else | 1565 else |
| 1519 { | 1566 { |
| 1520 /* The new size is different; allocate a new space, | 1567 /* The new size is different; allocate a new space, |
| 1521 and copy the lesser of the new size and the old. */ | 1568 and copy the lesser of the new size and the old. */ |
| 1522 result = _malloc_internal (size); | 1569 result = _malloc_internal_nolock (size); |
| 1523 if (result == NULL) | 1570 if (result == NULL) |
| 1524 goto out; | 1571 goto out; |
| 1525 memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type)); | 1572 memcpy (result, ptr, min (size, (__malloc_size_t) 1 << type)); |
| 1526 _free_internal (ptr); | 1573 _free_internal_nolock (ptr); |
| 1527 } | 1574 } |
| 1528 break; | 1575 break; |
| 1529 } | 1576 } |
| 1530 | 1577 |
| 1531 PROTECT_MALLOC_STATE (1); | 1578 PROTECT_MALLOC_STATE (1); |
| 1532 out: | 1579 out: |
| 1580 return result; | |
| 1581 } | |
| 1582 | |
| 1583 __ptr_t | |
| 1584 _realloc_internal (ptr, size) | |
| 1585 __ptr_t ptr; | |
| 1586 __malloc_size_t size; | |
| 1587 { | |
| 1588 __ptr_t result; | |
| 1589 | |
| 1590 LOCK(); | |
| 1591 result = _realloc_internal_nolock (ptr, size); | |
| 1533 UNLOCK (); | 1592 UNLOCK (); |
| 1593 | |
| 1534 return result; | 1594 return result; |
| 1535 } | 1595 } |
| 1536 | 1596 |
| 1537 __ptr_t | 1597 __ptr_t |
| 1538 realloc (ptr, size) | 1598 realloc (ptr, size) |
| 1539 __ptr_t ptr; | 1599 __ptr_t ptr; |
| 1540 __malloc_size_t size; | 1600 __malloc_size_t size; |
| 1541 { | 1601 { |
| 1602 __ptr_t (*hook) (__ptr_t, __malloc_size_t); | |
| 1603 | |
| 1542 if (!__malloc_initialized && !__malloc_initialize ()) | 1604 if (!__malloc_initialized && !__malloc_initialize ()) |
| 1543 return NULL; | 1605 return NULL; |
| 1544 | 1606 |
| 1545 return (__realloc_hook != NULL ? *__realloc_hook : _realloc_internal) | 1607 hook = __realloc_hook; |
| 1546 (ptr, size); | 1608 return (hook != NULL ? *hook : _realloc_internal) (ptr, size); |
| 1547 } | 1609 } |
| 1548 /* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. | 1610 /* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. |
| 1549 | 1611 |
| 1550 This library is free software; you can redistribute it and/or | 1612 This library is free software; you can redistribute it and/or |
| 1551 modify it under the terms of the GNU General Public License as | 1613 modify it under the terms of the GNU General Public License as |
| 1679 __malloc_size_t alignment; | 1741 __malloc_size_t alignment; |
| 1680 __malloc_size_t size; | 1742 __malloc_size_t size; |
| 1681 { | 1743 { |
| 1682 __ptr_t result; | 1744 __ptr_t result; |
| 1683 unsigned long int adj, lastadj; | 1745 unsigned long int adj, lastadj; |
| 1684 | 1746 __ptr_t (*hook) (__malloc_size_t, __malloc_size_t) = __memalign_hook; |
| 1685 if (__memalign_hook) | 1747 |
| 1686 return (*__memalign_hook) (alignment, size); | 1748 if (hook) |
| 1749 return (*hook) (alignment, size); | |
| 1687 | 1750 |
| 1688 /* Allocate a block with enough extra space to pad the block with up to | 1751 /* Allocate a block with enough extra space to pad the block with up to |
| 1689 (ALIGNMENT - 1) bytes if necessary. */ | 1752 (ALIGNMENT - 1) bytes if necessary. */ |
| 1690 result = malloc (size + alignment - 1); | 1753 result = malloc (size + alignment - 1); |
| 1691 if (result == NULL) | 1754 if (result == NULL) |
| 1716 /* Record this block in the list of aligned blocks, so that `free' | 1779 /* Record this block in the list of aligned blocks, so that `free' |
| 1717 can identify the pointer it is passed, which will be in the middle | 1780 can identify the pointer it is passed, which will be in the middle |
| 1718 of an allocated block. */ | 1781 of an allocated block. */ |
| 1719 | 1782 |
| 1720 struct alignlist *l; | 1783 struct alignlist *l; |
| 1784 LOCK_ALIGNED_BLOCKS (); | |
| 1721 for (l = _aligned_blocks; l != NULL; l = l->next) | 1785 for (l = _aligned_blocks; l != NULL; l = l->next) |
| 1722 if (l->aligned == NULL) | 1786 if (l->aligned == NULL) |
| 1723 /* This slot is free. Use it. */ | 1787 /* This slot is free. Use it. */ |
| 1724 break; | 1788 break; |
| 1725 if (l == NULL) | 1789 if (l == NULL) |
| 1726 { | 1790 { |
| 1727 l = (struct alignlist *) malloc (sizeof (struct alignlist)); | 1791 l = (struct alignlist *) malloc (sizeof (struct alignlist)); |
| 1728 if (l == NULL) | 1792 if (l != NULL) |
| 1729 { | 1793 { |
| 1730 free (result); | 1794 l->next = _aligned_blocks; |
| 1731 return NULL; | 1795 _aligned_blocks = l; |
| 1732 } | 1796 } |
| 1733 l->next = _aligned_blocks; | 1797 } |
| 1734 _aligned_blocks = l; | 1798 if (l != NULL) |
| 1735 } | 1799 { |
| 1736 l->exact = result; | 1800 l->exact = result; |
| 1737 result = l->aligned = (char *) result + alignment - adj; | 1801 result = l->aligned = (char *) result + alignment - adj; |
| 1802 } | |
| 1803 UNLOCK_ALIGNED_BLOCKS (); | |
| 1804 if (l == NULL) | |
| 1805 { | |
| 1806 free (result); | |
| 1807 result = NULL; | |
| 1808 } | |
| 1738 } | 1809 } |
| 1739 | 1810 |
| 1740 return result; | 1811 return result; |
| 1741 } | 1812 } |
| 1742 | 1813 |
