00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #define malloc mm_malloc
00016 #define free mm_free
00017 #define calloc mm_calloc
00018 #define cfree mm_cfree
00019 #define realloc mm_realloc
00020 #define memalign mm_memalign
00021 #define valloc mm_valloc
00022
00023 extern CMK_TYPEDEF_UINT8 _memory_allocated;
00024 extern CMK_TYPEDEF_UINT8 _memory_allocated_max;
00025 extern CMK_TYPEDEF_UINT8 _memory_allocated_min;
00026
00027 #define UPDATE_MEMUSAGE \
00028 if(_memory_allocated > _memory_allocated_max) \
00029 _memory_allocated_max=_memory_allocated; \
00030 if(_memory_allocated < _memory_allocated_min) \
00031 _memory_allocated_min=_memory_allocated;
00032
00033 #define HAVE_MMAP CMK_HAS_MMAP
00034 #ifndef __USE_GNU
00035 # define __USE_GNU 1
00036 #endif
00037
00038 #define attribute_hidden
00039
00040 #if 0
00041
00042
00043
00044
00045
00046
00047
00048
00049 #define RETURN_ADDRESS(x) (void *)x
00050
00051 #endif
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 #ifndef __STD_C
00283 #if defined(__STDC__) || defined(__cplusplus)
00284 #define __STD_C 1
00285 #else
00286 #define __STD_C 0
00287 #endif
00288 #endif
00289
00290 #if __STD_C && !__STDC__
00291 #define __STDC__ 1
00292 #endif
00293
00294
00295
00296
00297
00298 #ifndef Void_t
00299 #if (__STD_C || defined(WIN32))
00300 #define Void_t void
00301 #else
00302 #define Void_t char
00303 #endif
00304 #endif
00305
00306 #if __STD_C
00307 #include <stddef.h>
00308 #include <stdlib.h>
00309 #else
00310 #include <sys/types.h>
00311 #endif
00312
00313 #ifdef __cplusplus
00314 extern "C" {
00315 #endif
00316
00317
00318
00319
00320
00321 #ifndef LACKS_UNISTD_H
00322 #include <unistd.h>
00323 #endif
00324
00325
00326
00327
00328
00329
00330 #include <stdio.h>
00331 #include <errno.h>
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 #if MALLOC_DEBUG
00363 #include <assert.h>
00364 #else
00365 #undef assert
00366 #define assert(x) ((void)0)
00367 #endif
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 #ifndef INTERNAL_SIZE_T
00402 #define INTERNAL_SIZE_T size_t
00403 #endif
00404
00405
00406 #define SIZE_SZ (sizeof(INTERNAL_SIZE_T))
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 #ifndef MALLOC_ALIGNMENT
00419 #define MALLOC_ALIGNMENT (4 * SIZE_SZ)
00420 #endif
00421
00422
00423 #define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 #ifndef REALLOC_ZERO_BYTES_FREES
00435 #define REALLOC_ZERO_BYTES_FREES 1
00436 #endif
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 #ifndef TRIM_FASTBINS
00455 #define TRIM_FASTBINS 0
00456 #endif
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 #ifdef USE_DL_PREFIX
00476 #define public_cALLOc dlcalloc
00477 #define public_fREe dlfree
00478 #define public_cFREe dlcfree
00479 #define public_mALLOc dlmalloc
00480 #define public_mEMALIGn dlmemalign
00481 #define public_rEALLOc dlrealloc
00482 #define public_vALLOc dlvalloc
00483 #define public_pVALLOc dlpvalloc
00484 #define public_mALLINFo dlmallinfo
00485 #define public_mALLOPt dlmallopt
00486 #define public_mTRIm dlmalloc_trim
00487 #define public_mSTATs dlmalloc_stats
00488 #define public_mUSABLe dlmalloc_usable_size
00489 #define public_iCALLOc dlindependent_calloc
00490 #define public_iCOMALLOc dlindependent_comalloc
00491 #define public_gET_STATe dlget_state
00492 #define public_sET_STATe dlset_state
00493 #else
00494 #ifdef _LIBC
00495
00496
00497 #define public_cALLOc __libc_calloc
00498 #define public_fREe __libc_free
00499 #define public_cFREe __libc_cfree
00500 #define public_mALLOc __libc_malloc
00501 #define public_mEMALIGn __libc_memalign
00502 #define public_rEALLOc __libc_realloc
00503 #define public_vALLOc __libc_valloc
00504 #define public_pVALLOc __libc_pvalloc
00505 #define public_mALLINFo __libc_mallinfo
00506 #define public_mALLOPt __libc_mallopt
00507 #define public_mTRIm __malloc_trim
00508 #define public_mSTATs __malloc_stats
00509 #define public_mUSABLe __malloc_usable_size
00510 #define public_iCALLOc __libc_independent_calloc
00511 #define public_iCOMALLOc __libc_independent_comalloc
00512 #define public_gET_STATe __malloc_get_state
00513 #define public_sET_STATe __malloc_set_state
00514 #define malloc_getpagesize __getpagesize()
00515 #define open __open
00516 #define mmap __mmap
00517 #define munmap __munmap
00518 #define mremap __mremap
00519 #define mprotect __mprotect
00520 #define MORECORE (*__morecore)
00521 #define MORECORE_FAILURE 0
00522
00523 Void_t * __default_morecore (ptrdiff_t);
00524 Void_t *(*__morecore)(ptrdiff_t) = __default_morecore;
00525
00526 #else
00527 #define public_cALLOc calloc
00528 #define public_fREe free
00529 #define public_cFREe cfree
00530 #define public_mALLOc malloc
00531 #define public_mEMALIGn memalign
00532 #define public_rEALLOc realloc
00533 #define public_vALLOc valloc
00534 #define public_pVALLOc pvalloc
00535 #define public_mALLINFo mallinfo
00536 #define public_mALLOPt mallopt
00537 #define public_mTRIm malloc_trim
00538 #define public_mSTATs malloc_stats
00539 #define public_mUSABLe malloc_usable_size
00540 #define public_iCALLOc independent_calloc
00541 #define public_iCOMALLOc independent_comalloc
00542 #define public_gET_STATe malloc_get_state
00543 #define public_sET_STATe malloc_set_state
00544 #endif
00545 #endif
00546
00547 #ifndef _LIBC
00548 #define __builtin_expect(expr, val) (expr)
00549
00550 #define fwrite(buf, size, count, fp) _IO_fwrite (buf, size, count, fp)
00551 #endif
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 #include <string.h>
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 #ifndef MALLOC_FAILURE_ACTION
00578 #if __STD_C
00579 #define MALLOC_FAILURE_ACTION \
00580 errno = ENOMEM;
00581
00582 #else
00583 #define MALLOC_FAILURE_ACTION
00584 #endif
00585 #endif
00586
00587
00588
00589
00590
00591
00592 #ifdef LACKS_UNISTD_H
00593 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
00594 #if __STD_C
00595 extern Void_t* sbrk(ptrdiff_t);
00596 #else
00597 extern Void_t* sbrk();
00598 #endif
00599 #endif
00600 #endif
00601
00602
00603
00604
00605
00606
00607
00608
00609 #ifndef MORECORE
00610 #define MORECORE sbrk
00611 #endif
00612
00613
00614
00615
00616
00617
00618
00619
00620 #ifndef MORECORE_FAILURE
00621 #define MORECORE_FAILURE (-1)
00622 #endif
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 #ifndef MORECORE_CONTIGUOUS
00635 #define MORECORE_CONTIGUOUS 1
00636 #endif
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 #ifndef MORECORE_CLEARS
00657 #define MORECORE_CLEARS 1
00658 #endif
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673 #ifndef HAVE_MMAP
00674 #define HAVE_MMAP 1
00675
00676
00677
00678
00679
00680
00681 #ifndef MMAP_CLEARS
00682 #define MMAP_CLEARS 1
00683 #endif
00684
00685 #else
00686 #ifndef MMAP_CLEARS
00687 #define MMAP_CLEARS 0
00688 #endif
00689 #endif
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 #ifndef MMAP_AS_MORECORE_SIZE
00707 #define MMAP_AS_MORECORE_SIZE (1024 * 1024)
00708 #endif
00709
00710
00711
00712
00713
00714
00715
00716 #ifndef HAVE_MREMAP
00717 #ifdef linux
00718 #define HAVE_MREMAP 1
00719 #else
00720 #define HAVE_MREMAP 0
00721 #endif
00722
00723 #endif
00724
00725
00726
00727
00728
00729
00730 #ifndef USE_ARENAS
00731 #define USE_ARENAS HAVE_MMAP
00732 #endif
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748 #ifndef malloc_getpagesize
00749
00750 #ifndef LACKS_UNISTD_H
00751 # include <unistd.h>
00752 #endif
00753
00754 # ifdef _SC_PAGESIZE
00755 # ifndef _SC_PAGE_SIZE
00756 # define _SC_PAGE_SIZE _SC_PAGESIZE
00757 # endif
00758 # endif
00759
00760 # ifdef _SC_PAGE_SIZE
00761 # define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
00762 # else
00763 # if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
00764 extern size_t getpagesize();
00765 # define malloc_getpagesize getpagesize()
00766 # else
00767 # ifdef WIN32
00768 # define malloc_getpagesize getpagesize()
00769 # else
00770 # ifndef LACKS_SYS_PARAM_H
00771 # include <sys/param.h>
00772 # endif
00773 # ifdef EXEC_PAGESIZE
00774 # define malloc_getpagesize EXEC_PAGESIZE
00775 # else
00776 # ifdef NBPG
00777 # ifndef CLSIZE
00778 # define malloc_getpagesize NBPG
00779 # else
00780 # define malloc_getpagesize (NBPG * CLSIZE)
00781 # endif
00782 # else
00783 # ifdef NBPC
00784 # define malloc_getpagesize NBPC
00785 # else
00786 # ifdef PAGESIZE
00787 # define malloc_getpagesize PAGESIZE
00788 # else
00789 # define malloc_getpagesize (4096)
00790 # endif
00791 # endif
00792 # endif
00793 # endif
00794 # endif
00795 # endif
00796 # endif
00797 #endif
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828 #ifdef HAVE_USR_INCLUDE_MALLOC_H
00829 #include "/usr/include/malloc.h"
00830 #endif
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 #if __STD_C
00850 Void_t* public_mALLOc(size_t);
00851 #else
00852 Void_t* public_mALLOc();
00853 #endif
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 #if __STD_C
00867 void public_fREe(Void_t*);
00868 #else
00869 void public_fREe();
00870 #endif
00871
00872
00873
00874
00875
00876
00877 #if __STD_C
00878 Void_t* public_cALLOc(size_t, size_t);
00879 #else
00880 Void_t* public_cALLOc();
00881 #endif
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910 #if __STD_C
00911 Void_t* public_rEALLOc(Void_t*, size_t);
00912 #else
00913 Void_t* public_rEALLOc();
00914 #endif
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928 #if __STD_C
00929 Void_t* public_mEMALIGn(size_t, size_t);
00930 #else
00931 Void_t* public_mEMALIGn();
00932 #endif
00933
00934
00935
00936
00937
00938
00939 #if __STD_C
00940 Void_t* public_vALLOc(size_t);
00941 #else
00942 Void_t* public_vALLOc();
00943 #endif
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 #if __STD_C
00969 int public_mALLOPt(int, int);
00970 #else
00971 int public_mALLOPt();
00972 #endif
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 #if __STD_C
00999 struct mallinfo public_mALLINFo(void);
01000 #else
01001 struct mallinfo public_mALLINFo();
01002 #endif
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056 #if __STD_C
01057 Void_t** public_iCALLOc(size_t, size_t, Void_t**);
01058 #else
01059 Void_t** public_iCALLOc();
01060 #endif
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121 #if __STD_C
01122 Void_t** public_iCOMALLOc(size_t, size_t*, Void_t**);
01123 #else
01124 Void_t** public_iCOMALLOc();
01125 #endif
01126
01127
01128
01129
01130
01131
01132
01133 #if __STD_C
01134 Void_t* public_pVALLOc(size_t);
01135 #else
01136 Void_t* public_pVALLOc();
01137 #endif
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 #if __STD_C
01148 void public_cFREe(Void_t*);
01149 #else
01150 void public_cFREe();
01151 #endif
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177 #if __STD_C
01178 int public_mTRIm(size_t);
01179 #else
01180 int public_mTRIm();
01181 #endif
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198 #if __STD_C
01199 size_t public_mUSABLe(Void_t*);
01200 #else
01201 size_t public_mUSABLe();
01202 #endif
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224 #if __STD_C
01225 void public_mSTATs(void);
01226 #else
01227 void public_mSTATs();
01228 #endif
01229
01230
01231
01232
01233
01234
01235
01236 #if __STD_C
01237 Void_t* public_gET_STATe(void);
01238 #else
01239 Void_t* public_gET_STATe();
01240 #endif
01241
01242
01243
01244
01245
01246
01247
01248 #if __STD_C
01249 int public_sET_STATe(Void_t*);
01250 #else
01251 int public_sET_STATe();
01252 #endif
01253
01254 #ifdef _LIBC
01255
01256
01257
01258
01259
01260 int __posix_memalign(void **, size_t, size_t);
01261 #endif
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292 #ifndef M_MXFAST
01293 #define M_MXFAST 1
01294 #endif
01295
01296 #ifndef DEFAULT_MXFAST
01297 #define DEFAULT_MXFAST 128
01298 #endif
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361 #define M_TRIM_THRESHOLD -1
01362
01363 #ifndef DEFAULT_TRIM_THRESHOLD
01364 #define DEFAULT_TRIM_THRESHOLD (256 * 1024)
01365 #endif
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394 #define M_TOP_PAD -2
01395
01396 #ifndef DEFAULT_TOP_PAD
01397 #define DEFAULT_TOP_PAD (0)
01398 #endif
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441 #define M_MMAP_THRESHOLD -3
01442
01443 #ifndef DEFAULT_MMAP_THRESHOLD
01444 #define DEFAULT_MMAP_THRESHOLD (512 * 1024)
01445 #endif
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460 #define M_MMAP_MAX -4
01461
01462 #ifndef DEFAULT_MMAP_MAX
01463 #if HAVE_MMAP
01464 #define DEFAULT_MMAP_MAX (131072)
01465 #else
01466 #define DEFAULT_MMAP_MAX (0)
01467 #endif
01468 #endif
01469
01470 #ifdef __cplusplus
01471 };
01472 #endif
01473
01474 #include "memory-gnu.h"
01475 #include "memory-gnu-threads.h"
01476
01477 #ifndef BOUNDED_N
01478 #define BOUNDED_N(ptr, sz) (ptr)
01479 #endif
01480 #ifndef RETURN_ADDRESS
01481 #define RETURN_ADDRESS(X_) (NULL)
01482 #endif
01483
01484
01485
01486
01487 #ifndef internal_function
01488 # define internal_function
01489 #endif
01490
01491
01492 struct malloc_chunk;
01493 typedef struct malloc_chunk* mchunkptr;
01494
01495
01496
01497 #if __STD_C
01498
01499 Void_t* _int_malloc(mstate, size_t);
01500 void _int_free(mstate, Void_t*);
01501 Void_t* _int_realloc(mstate, Void_t*, size_t);
01502 Void_t* _int_memalign(mstate, size_t, size_t);
01503 Void_t* _int_valloc(mstate, size_t);
01504 static Void_t* _int_pvalloc(mstate, size_t);
01505
01506 static Void_t** _int_icalloc(mstate, size_t, size_t, Void_t**);
01507 static Void_t** _int_icomalloc(mstate, size_t, size_t*, Void_t**);
01508 static int mTRIm(size_t);
01509 static size_t mUSABLe(Void_t*);
01510 static void mSTATs(void);
01511 static int mALLOPt(int, int);
01512 static struct mallinfo mALLINFo(mstate);
01513
01514 static Void_t* internal_function mem2mem_check(Void_t *p, size_t sz);
01515 static int internal_function top_check(void);
01516 static void internal_function munmap_chunk(mchunkptr p);
01517 #if HAVE_MREMAP
01518 static mchunkptr internal_function mremap_chunk(mchunkptr p, size_t new_size);
01519 #endif
01520
01521 static Void_t* malloc_check(size_t sz, const Void_t *caller);
01522 static void free_check(Void_t* mem, const Void_t *caller);
01523 static Void_t* realloc_check(Void_t* oldmem, size_t bytes,
01524 const Void_t *caller);
01525 static Void_t* memalign_check(size_t alignment, size_t bytes,
01526 const Void_t *caller);
01527 #ifndef NO_THREADS
01528 # ifdef _LIBC
01529 # if USE___THREAD || (defined USE_TLS && !defined SHARED)
01530
01531 # define NO_STARTER
01532 # endif
01533 # endif
01534 # ifdef NO_STARTER
01535 # undef NO_STARTER
01536 # else
01537 static Void_t* malloc_starter(size_t sz, const Void_t *caller);
01538 static Void_t* memalign_starter(size_t aln, size_t sz, const Void_t *caller);
01539 static void free_starter(Void_t* mem, const Void_t *caller);
01540 # endif
01541 static Void_t* malloc_atfork(size_t sz, const Void_t *caller);
01542 static void free_atfork(Void_t* mem, const Void_t *caller);
01543 #endif
01544
01545 #else
01546
01547 Void_t* _int_malloc();
01548 void _int_free();
01549 Void_t* _int_realloc();
01550 Void_t* _int_memalign();
01551 Void_t* _int_valloc();
01552 Void_t* _int_pvalloc();
01553
01554 static Void_t** _int_icalloc();
01555 static Void_t** _int_icomalloc();
01556 static int mTRIm();
01557 static size_t mUSABLe();
01558 static void mSTATs();
01559 static int mALLOPt();
01560 static struct mallinfo mALLINFo();
01561
01562 #endif
01563
01564
01565
01566
01567
01568
01569
01570 #if USE_MEMCPY
01571
01572
01573
01574
01575
01576
01577 #define MALLOC_COPY(dest, src, nbytes) memcpy(dest, src, nbytes)
01578 #define MALLOC_ZERO(dest, nbytes) memset(dest, 0, nbytes)
01579
01580 #else
01581
01582
01583
01584 #define MALLOC_ZERO(charp, nbytes) \
01585 do { \
01586 INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp); \
01587 unsigned long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T); \
01588 long mcn; \
01589 if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \
01590 switch (mctmp) { \
01591 case 0: for(;;) { *mzp++ = 0; \
01592 case 7: *mzp++ = 0; \
01593 case 6: *mzp++ = 0; \
01594 case 5: *mzp++ = 0; \
01595 case 4: *mzp++ = 0; \
01596 case 3: *mzp++ = 0; \
01597 case 2: *mzp++ = 0; \
01598 case 1: *mzp++ = 0; if(mcn <= 0) break; mcn--; } \
01599 } \
01600 } while(0)
01601
01602 #define MALLOC_COPY(dest,src,nbytes) \
01603 do { \
01604 INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src; \
01605 INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest; \
01606 unsigned long mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T); \
01607 long mcn; \
01608 if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \
01609 switch (mctmp) { \
01610 case 0: for(;;) { *mcdst++ = *mcsrc++; \
01611 case 7: *mcdst++ = *mcsrc++; \
01612 case 6: *mcdst++ = *mcsrc++; \
01613 case 5: *mcdst++ = *mcsrc++; \
01614 case 4: *mcdst++ = *mcsrc++; \
01615 case 3: *mcdst++ = *mcsrc++; \
01616 case 2: *mcdst++ = *mcsrc++; \
01617 case 1: *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; } \
01618 } \
01619 } while(0)
01620
01621 #endif
01622
01623
01624
01625
01626 #if HAVE_MMAP
01627
01628 #include <fcntl.h>
01629 #ifndef LACKS_SYS_MMAN_H
01630 #include <sys/mman.h>
01631 #endif
01632
01633 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
01634 # define MAP_ANONYMOUS MAP_ANON
01635 #endif
01636 #if !defined(MAP_FAILED)
01637 # define MAP_FAILED ((char*)-1)
01638 #endif
01639
01640 #ifndef MAP_NORESERVE
01641 # ifdef MAP_AUTORESRV
01642 # define MAP_NORESERVE MAP_AUTORESRV
01643 # else
01644 # define MAP_NORESERVE 0
01645 # endif
01646 #endif
01647
01648
01649
01650
01651
01652
01653
01654 #ifndef MAP_ANONYMOUS
01655
01656 static int dev_zero_fd = -1;
01657
01658 #define MMAP(addr, size, prot, flags) ((dev_zero_fd < 0) ? \
01659 (dev_zero_fd = open("/dev/zero", O_RDWR), \
01660 mmap((addr), (size), (prot), (flags), dev_zero_fd, 0)) : \
01661 mmap((addr), (size), (prot), (flags), dev_zero_fd, 0))
01662
01663 #else
01664
01665 #define MMAP(addr, size, prot, flags) \
01666 (mmap((addr), (size), (prot), (flags)|MAP_ANONYMOUS, -1, 0))
01667
01668 #endif
01669
01670
01671 #endif
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685 struct malloc_chunk {
01686
01687 INTERNAL_SIZE_T prev_size;
01688 INTERNAL_SIZE_T size;
01689
01690 struct malloc_chunk* fd;
01691 struct malloc_chunk* bk;
01692 };
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788 #define chunk2mem(p) ((Void_t*)((char*)(p) + 2*SIZE_SZ))
01789 #define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
01790
01791
01792 #define MIN_CHUNK_SIZE (sizeof(struct malloc_chunk))
01793
01794
01795
01796 #define MINSIZE \
01797 (unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))
01798
01799
01800
01801 #define aligned_OK(m) (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
01802
01803
01804
01805
01806
01807
01808
01809
01810 #define REQUEST_OUT_OF_RANGE(req) \
01811 ((unsigned long)(req) >= \
01812 (unsigned long)(INTERNAL_SIZE_T)(-2 * MINSIZE))
01813
01814
01815
01816 #define request2size(req) \
01817 (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \
01818 MINSIZE : \
01819 ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
01820
01821
01822
01823 #define checked_request2size(req, sz) \
01824 if (REQUEST_OUT_OF_RANGE(req)) { \
01825 MALLOC_FAILURE_ACTION; \
01826 return 0; \
01827 } \
01828 (sz) = request2size(req);
01829
01830
01831
01832
01833
01834
01835
01836 #define PREV_INUSE 0x1
01837
01838
01839 #define prev_inuse(p) ((p)->size & PREV_INUSE)
01840
01841
01842
01843 #define IS_MMAPPED 0x2
01844
01845
01846 #define chunk_is_mmapped(p) ((p)->size & IS_MMAPPED)
01847
01848
01849
01850
01851
01852 #define NON_MAIN_ARENA 0x4
01853
01854
01855 #define chunk_non_main_arena(p) ((p)->size & NON_MAIN_ARENA)
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866 #define SIZE_BITS (PREV_INUSE|IS_MMAPPED|NON_MAIN_ARENA)
01867
01868
01869 #define chunksize(p) ((p)->size & ~(SIZE_BITS))
01870
01871
01872
01873 #define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~SIZE_BITS) ))
01874
01875
01876 #define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
01877
01878
01879 #define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s)))
01880
01881
01882 #define inuse(p)\
01883 ((((mchunkptr)(((char*)(p))+((p)->size & ~SIZE_BITS)))->size) & PREV_INUSE)
01884
01885
01886 #define set_inuse(p)\
01887 ((mchunkptr)(((char*)(p)) + ((p)->size & ~SIZE_BITS)))->size |= PREV_INUSE
01888
01889 #define clear_inuse(p)\
01890 ((mchunkptr)(((char*)(p)) + ((p)->size & ~SIZE_BITS)))->size &= ~(PREV_INUSE)
01891
01892
01893
01894 #define inuse_bit_at_offset(p, s)\
01895 (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE)
01896
01897 #define set_inuse_bit_at_offset(p, s)\
01898 (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE)
01899
01900 #define clear_inuse_bit_at_offset(p, s)\
01901 (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
01902
01903
01904
01905 #define set_head_size(p, s) ((p)->size = (((p)->size & SIZE_BITS) | (s)))
01906
01907
01908 #define set_head(p, s) ((p)->size = (s))
01909
01910
01911 #define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965 typedef struct malloc_chunk* mbinptr;
01966
01967
01968 #define bin_at(m, i) ((mbinptr)((char*)&((m)->bins[(i)<<1]) - (SIZE_SZ<<1)))
01969
01970
01971 #define next_bin(b) ((mbinptr)((char*)(b) + (sizeof(mchunkptr)<<1)))
01972
01973
01974 #define first(b) ((b)->fd)
01975 #define last(b) ((b)->bk)
01976
01977
01978 #define unlink(P, BK, FD) { \
01979 FD = P->fd; \
01980 BK = P->bk; \
01981 FD->bk = BK; \
01982 BK->fd = FD; \
01983 }
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006 #define NBINS 128
02007 #define NSMALLBINS 64
02008 #define SMALLBIN_WIDTH 8
02009 #define MIN_LARGE_SIZE 512
02010
02011 #define in_smallbin_range(sz) \
02012 ((unsigned long)(sz) < (unsigned long)MIN_LARGE_SIZE)
02013
02014 #define smallbin_index(sz) (((unsigned)(sz)) >> 3)
02015
02016 #define largebin_index(sz) \
02017 (((((unsigned long)(sz)) >> 6) <= 32)? 56 + (((unsigned long)(sz)) >> 6): \
02018 ((((unsigned long)(sz)) >> 9) <= 20)? 91 + (((unsigned long)(sz)) >> 9): \
02019 ((((unsigned long)(sz)) >> 12) <= 10)? 110 + (((unsigned long)(sz)) >> 12): \
02020 ((((unsigned long)(sz)) >> 15) <= 4)? 119 + (((unsigned long)(sz)) >> 15): \
02021 ((((unsigned long)(sz)) >> 18) <= 2)? 124 + (((unsigned long)(sz)) >> 18): \
02022 126)
02023
02024 #define bin_index(sz) \
02025 ((in_smallbin_range(sz)) ? smallbin_index(sz) : largebin_index(sz))
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043 #define unsorted_chunks(M) (bin_at(M, 1))
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064 #define initial_top(M) (unsorted_chunks(M))
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078 #define BINMAPSHIFT 5
02079 #define BITSPERMAP (1U << BINMAPSHIFT)
02080 #define BINMAPSIZE (NBINS / BITSPERMAP)
02081
02082 #define idx2block(i) ((i) >> BINMAPSHIFT)
02083 #define idx2bit(i) ((1U << ((i) & ((1U << BINMAPSHIFT)-1))))
02084
02085 #define mark_bin(m,i) ((m)->binmap[idx2block(i)] |= idx2bit(i))
02086 #define unmark_bin(m,i) ((m)->binmap[idx2block(i)] &= ~(idx2bit(i)))
02087 #define get_binmap(m,i) ((m)->binmap[idx2block(i)] & idx2bit(i))
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106 typedef struct malloc_chunk* mfastbinptr;
02107
02108
02109 #define fastbin_index(sz) ((((unsigned int)(sz)) >> 3) - 2)
02110
02111
02112 #define MAX_FAST_SIZE 144
02113
02114 #define NFASTBINS (fastbin_index(request2size(MAX_FAST_SIZE))+1)
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127 #define FASTBIN_CONSOLIDATION_THRESHOLD (262144UL)
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144 #define FASTCHUNKS_BIT (1U)
02145
02146 #define have_fastchunks(M) (((M)->max_fast & FASTCHUNKS_BIT) == 0)
02147 #define clear_fastchunks(M) ((M)->max_fast |= FASTCHUNKS_BIT)
02148 #define set_fastchunks(M) ((M)->max_fast &= ~FASTCHUNKS_BIT)
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159 #define NONCONTIGUOUS_BIT (2U)
02160
02161 #define contiguous(M) (((M)->max_fast & NONCONTIGUOUS_BIT) == 0)
02162 #define noncontiguous(M) (((M)->max_fast & NONCONTIGUOUS_BIT) != 0)
02163 #define set_noncontiguous(M) ((M)->max_fast |= NONCONTIGUOUS_BIT)
02164 #define set_contiguous(M) ((M)->max_fast &= ~NONCONTIGUOUS_BIT)
02165
02166
02167
02168
02169
02170
02171
02172
02173 #define set_max_fast(M, s) \
02174 (M)->max_fast = (((s) == 0)? SMALLBIN_WIDTH: request2size(s)) | \
02175 FASTCHUNKS_BIT | \
02176 ((M)->max_fast & NONCONTIGUOUS_BIT)
02177
02178
02179
02180
02181
02182
02183 struct malloc_state {
02184
02185 mutex_t mutex;
02186
02187
02188 long stat_lock_direct, stat_lock_loop, stat_lock_wait;
02189 long pad0_[1];
02190
02191
02192 INTERNAL_SIZE_T max_fast;
02193
02194
02195 mfastbinptr fastbins[NFASTBINS];
02196
02197
02198 mchunkptr top;
02199
02200
02201 mchunkptr last_remainder;
02202
02203
02204 mchunkptr bins[NBINS * 2];
02205
02206
02207 unsigned int binmap[BINMAPSIZE];
02208
02209
02210 struct malloc_state *next;
02211
02212
02213 INTERNAL_SIZE_T system_mem;
02214 INTERNAL_SIZE_T max_system_mem;
02215 };
02216
02217 struct malloc_par {
02218
02219 unsigned long trim_threshold;
02220 INTERNAL_SIZE_T top_pad;
02221 INTERNAL_SIZE_T mmap_threshold;
02222
02223
02224 int n_mmaps;
02225 int n_mmaps_max;
02226 int max_n_mmaps;
02227
02228
02229 unsigned int pagesize;
02230
02231
02232 INTERNAL_SIZE_T mmapped_mem;
02233
02234
02235 INTERNAL_SIZE_T max_mmapped_mem;
02236 INTERNAL_SIZE_T max_total_mem;
02237
02238
02239 char* sbrk_base;
02240 };
02241
02242
02243
02244
02245
02246
02247
02248 static struct malloc_state main_arena;
02249
02250
02251
02252 static struct malloc_par mp_;
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264 #if __STD_C
02265 static void malloc_init_state(mstate av)
02266 #else
02267 static void malloc_init_state(av) mstate av;
02268 #endif
02269 {
02270 int i;
02271 mbinptr bin;
02272
02273
02274 for (i = 1; i < NBINS; ++i) {
02275 bin = bin_at(av,i);
02276 bin->fd = bin->bk = bin;
02277 }
02278
02279 #if MORECORE_CONTIGUOUS
02280 if (av != &main_arena)
02281 #endif
02282 set_noncontiguous(av);
02283
02284 set_max_fast(av, DEFAULT_MXFAST);
02285
02286 av->top = initial_top(av);
02287 }
02288
02289
02290
02291
02292
02293 #if __STD_C
02294 static Void_t* sYSMALLOc(INTERNAL_SIZE_T, mstate);
02295 static int sYSTRIm(size_t, mstate);
02296 static void malloc_consolidate(mstate);
02297 static Void_t** iALLOc(mstate, size_t, size_t*, int, Void_t**);
02298 #else
02299 static Void_t* sYSMALLOc();
02300 static int sYSTRIm();
02301 static void malloc_consolidate();
02302 static Void_t** iALLOc();
02303 #endif
02304
02305
02306
02307
02308
02309
02310 #ifndef weak_variable
02311 #ifndef _LIBC
02312 #define weak_variable
02313 #else
02314
02315
02316 #define weak_variable weak_function
02317 #endif
02318 #endif
02319
02320
02321 static Void_t* malloc_hook_ini __MALLOC_P ((size_t sz,
02322 const __malloc_ptr_t caller));
02323 static Void_t* realloc_hook_ini __MALLOC_P ((Void_t* ptr, size_t sz,
02324 const __malloc_ptr_t caller));
02325 static Void_t* memalign_hook_ini __MALLOC_P ((size_t alignment, size_t sz,
02326 const __malloc_ptr_t caller));
02327
02328 void weak_variable (*__malloc_initialize_hook) __MALLOC_P ((void)) = NULL;
02329 void weak_variable (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
02330 const __malloc_ptr_t)) = NULL;
02331 __malloc_ptr_t weak_variable (*__malloc_hook)
02332 __MALLOC_P ((size_t __size, const __malloc_ptr_t)) = malloc_hook_ini;
02333 __malloc_ptr_t weak_variable (*__realloc_hook)
02334 __MALLOC_P ((__malloc_ptr_t __ptr, size_t __size, const __malloc_ptr_t))
02335 = realloc_hook_ini;
02336 __malloc_ptr_t weak_variable (*__memalign_hook)
02337 __MALLOC_P ((size_t __alignment, size_t __size, const __malloc_ptr_t))
02338 = memalign_hook_ini;
02339 void weak_variable (*__after_morecore_hook) __MALLOC_P ((void)) = NULL;
02340
02341
02342
02343 #include "memory-gnu-arena.c"
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355 #if ! MALLOC_DEBUG
02356
02357 #define check_chunk(A,P)
02358 #define check_free_chunk(A,P)
02359 #define check_inuse_chunk(A,P)
02360 #define check_remalloced_chunk(A,P,N)
02361 #define check_malloced_chunk(A,P,N)
02362 #define check_malloc_state(A)
02363
02364 #else
02365
02366 #define check_chunk(A,P) do_check_chunk(A,P)
02367 #define check_free_chunk(A,P) do_check_free_chunk(A,P)
02368 #define check_inuse_chunk(A,P) do_check_inuse_chunk(A,P)
02369 #define check_remalloced_chunk(A,P,N) do_check_remalloced_chunk(A,P,N)
02370 #define check_malloced_chunk(A,P,N) do_check_malloced_chunk(A,P,N)
02371 #define check_malloc_state(A) do_check_malloc_state(A)
02372
02373
02374
02375
02376
02377 #if __STD_C
02378 static void do_check_chunk(mstate av, mchunkptr p)
02379 #else
02380 static void do_check_chunk(av, p) mstate av; mchunkptr p;
02381 #endif
02382 {
02383 unsigned long sz = chunksize(p);
02384
02385 char* max_address = (char*)(av->top) + chunksize(av->top);
02386 char* min_address = max_address - av->system_mem;
02387
02388 if (!chunk_is_mmapped(p)) {
02389
02390
02391 if (p != av->top) {
02392 if (contiguous(av)) {
02393 assert(((char*)p) >= min_address);
02394 assert(((char*)p + sz) <= ((char*)(av->top)));
02395 }
02396 }
02397 else {
02398
02399 assert((unsigned long)(sz) >= MINSIZE);
02400
02401 assert(prev_inuse(p));
02402 }
02403
02404 }
02405 else {
02406 #if HAVE_MMAP
02407
02408 if (contiguous(av) && av->top != initial_top(av)) {
02409 assert(((char*)p) < min_address || ((char*)p) > max_address);
02410 }
02411
02412 assert(((p->prev_size + sz) & (mp_.pagesize-1)) == 0);
02413
02414 assert(aligned_OK(chunk2mem(p)));
02415 #else
02416
02417 assert(!chunk_is_mmapped(p));
02418 #endif
02419 }
02420 }
02421
02422
02423
02424
02425
02426 #if __STD_C
02427 static void do_check_free_chunk(mstate av, mchunkptr p)
02428 #else
02429 static void do_check_free_chunk(av, p) mstate av; mchunkptr p;
02430 #endif
02431 {
02432 INTERNAL_SIZE_T sz = p->size & ~(PREV_INUSE|NON_MAIN_ARENA);
02433 mchunkptr next = chunk_at_offset(p, sz);
02434
02435 do_check_chunk(av, p);
02436
02437
02438 assert(!inuse(p));
02439 assert (!chunk_is_mmapped(p));
02440
02441
02442 if ((unsigned long)(sz) >= MINSIZE)
02443 {
02444 assert((sz & MALLOC_ALIGN_MASK) == 0);
02445 assert(aligned_OK(chunk2mem(p)));
02446
02447 assert(next->prev_size == sz);
02448
02449 assert(prev_inuse(p));
02450 assert (next == av->top || inuse(next));
02451
02452
02453 assert(p->fd->bk == p);
02454 assert(p->bk->fd == p);
02455 }
02456 else
02457 assert(sz == SIZE_SZ);
02458 }
02459
02460
02461
02462
02463
02464 #if __STD_C
02465 static void do_check_inuse_chunk(mstate av, mchunkptr p)
02466 #else
02467 static void do_check_inuse_chunk(av, p) mstate av; mchunkptr p;
02468 #endif
02469 {
02470 mchunkptr next;
02471
02472 do_check_chunk(av, p);
02473
02474 if (chunk_is_mmapped(p))
02475 return;
02476
02477
02478 assert(inuse(p));
02479
02480 next = next_chunk(p);
02481
02482
02483
02484
02485
02486 if (!prev_inuse(p)) {
02487
02488 mchunkptr prv = prev_chunk(p);
02489 assert(next_chunk(prv) == p);
02490 do_check_free_chunk(av, prv);
02491 }
02492
02493 if (next == av->top) {
02494 assert(prev_inuse(next));
02495 assert(chunksize(next) >= MINSIZE);
02496 }
02497 else if (!inuse(next))
02498 do_check_free_chunk(av, next);
02499 }
02500
02501
02502
02503
02504
02505 #if __STD_C
02506 static void do_check_remalloced_chunk(mstate av, mchunkptr p, INTERNAL_SIZE_T s)
02507 #else
02508 static void do_check_remalloced_chunk(av, p, s)
02509 mstate av; mchunkptr p; INTERNAL_SIZE_T s;
02510 #endif
02511 {
02512 INTERNAL_SIZE_T sz = p->size & ~(PREV_INUSE|NON_MAIN_ARENA);
02513
02514 if (!chunk_is_mmapped(p)) {
02515 assert(av == arena_for_chunk(p));
02516 if (chunk_non_main_arena(p))
02517 assert(av != &main_arena);
02518 else
02519 assert(av == &main_arena);
02520 }
02521
02522 do_check_inuse_chunk(av, p);
02523
02524
02525 assert((sz & MALLOC_ALIGN_MASK) == 0);
02526 assert((unsigned long)(sz) >= MINSIZE);
02527
02528 assert(aligned_OK(chunk2mem(p)));
02529
02530 assert((long)(sz) - (long)(s) >= 0);
02531 assert((long)(sz) - (long)(s + MINSIZE) < 0);
02532 }
02533
02534
02535
02536
02537
02538 #if __STD_C
02539 static void do_check_malloced_chunk(mstate av, mchunkptr p, INTERNAL_SIZE_T s)
02540 #else
02541 static void do_check_malloced_chunk(av, p, s)
02542 mstate av; mchunkptr p; INTERNAL_SIZE_T s;
02543 #endif
02544 {
02545
02546 do_check_remalloced_chunk(av, p, s);
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558 assert(prev_inuse(p));
02559 }
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573 static void do_check_malloc_state(mstate av)
02574 {
02575 int i;
02576 mchunkptr p;
02577 mchunkptr q;
02578 mbinptr b;
02579 unsigned int binbit;
02580 int empty;
02581 unsigned int idx;
02582 INTERNAL_SIZE_T size;
02583 unsigned long total = 0;
02584 int max_fast_bin;
02585
02586
02587 assert(sizeof(INTERNAL_SIZE_T) <= sizeof(char*));
02588
02589
02590 assert((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-1)) == 0);
02591
02592
02593 if (av->top == 0 || av->top == initial_top(av))
02594 return;
02595
02596
02597 assert((mp_.pagesize & (mp_.pagesize-1)) == 0);
02598
02599
02600 if (av == &main_arena && contiguous(av))
02601 assert((char*)mp_.sbrk_base + av->system_mem ==
02602 (char*)av->top + chunksize(av->top));
02603
02604
02605
02606
02607 assert((av->max_fast & ~1) <= request2size(MAX_FAST_SIZE));
02608
02609 max_fast_bin = fastbin_index(av->max_fast);
02610
02611 for (i = 0; i < NFASTBINS; ++i) {
02612 p = av->fastbins[i];
02613
02614
02615 if (i > max_fast_bin)
02616 assert(p == 0);
02617
02618 while (p != 0) {
02619
02620 do_check_inuse_chunk(av, p);
02621 total += chunksize(p);
02622
02623 assert(fastbin_index(chunksize(p)) == i);
02624 p = p->fd;
02625 }
02626 }
02627
02628 if (total != 0)
02629 assert(have_fastchunks(av));
02630 else if (!have_fastchunks(av))
02631 assert(total == 0);
02632
02633
02634 for (i = 1; i < NBINS; ++i) {
02635 b = bin_at(av,i);
02636
02637
02638 if (i >= 2) {
02639 binbit = get_binmap(av,i);
02640 empty = last(b) == b;
02641 if (!binbit)
02642 assert(empty);
02643 else if (!empty)
02644 assert(binbit);
02645 }
02646
02647 for (p = last(b); p != b; p = p->bk) {
02648
02649 do_check_free_chunk(av, p);
02650 size = chunksize(p);
02651 total += size;
02652 if (i >= 2) {
02653
02654 idx = bin_index(size);
02655 assert(idx == i);
02656
02657 assert(p->bk == b ||
02658 (unsigned long)chunksize(p->bk) >= (unsigned long)chunksize(p));
02659 }
02660
02661 for (q = next_chunk(p);
02662 (q != av->top && inuse(q) &&
02663 (unsigned long)(chunksize(q)) >= MINSIZE);
02664 q = next_chunk(q))
02665 do_check_inuse_chunk(av, q);
02666 }
02667 }
02668
02669
02670 check_chunk(av, av->top);
02671
02672
02673
02674 #ifdef NO_THREADS
02675 assert(total <= (unsigned long)(mp_.max_total_mem));
02676 assert(mp_.n_mmaps >= 0);
02677 #endif
02678 assert(mp_.n_mmaps <= mp_.n_mmaps_max);
02679 assert(mp_.n_mmaps <= mp_.max_n_mmaps);
02680
02681 assert((unsigned long)(av->system_mem) <=
02682 (unsigned long)(av->max_system_mem));
02683
02684 assert((unsigned long)(mp_.mmapped_mem) <=
02685 (unsigned long)(mp_.max_mmapped_mem));
02686
02687 #ifdef NO_THREADS
02688 assert((unsigned long)(mp_.max_total_mem) >=
02689 (unsigned long)(mp_.mmapped_mem) + (unsigned long)(av->system_mem));
02690 #endif
02691 }
02692 #endif
02693
02694
02695
02696 #include "memory-gnu-hooks.c"
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708 #if __STD_C
02709 static Void_t* sYSMALLOc(INTERNAL_SIZE_T nb, mstate av)
02710 #else
02711 static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
02712 #endif
02713 {
02714 mchunkptr old_top;
02715 INTERNAL_SIZE_T old_size;
02716 char* old_end;
02717
02718 long size;
02719 char* brk;
02720
02721 long correction;
02722 char* snd_brk;
02723
02724 INTERNAL_SIZE_T front_misalign;
02725 INTERNAL_SIZE_T end_misalign;
02726 char* aligned_brk;
02727
02728 mchunkptr p;
02729 mchunkptr remainder;
02730 unsigned long remainder_size;
02731
02732 unsigned long sum;
02733
02734 size_t pagemask = mp_.pagesize - 1;
02735
02736
02737 #if HAVE_MMAP
02738
02739
02740
02741
02742
02743
02744
02745
02746 if ((unsigned long)(nb) >= (unsigned long)(mp_.mmap_threshold) &&
02747 (mp_.n_mmaps < mp_.n_mmaps_max)) {
02748
02749 char* mm;
02750
02751
02752
02753
02754
02755
02756 size = (nb + SIZE_SZ + MALLOC_ALIGN_MASK + pagemask) & ~pagemask;
02757
02758
02759 if ((unsigned long)(size) > (unsigned long)(nb)) {
02760
02761 mm = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE));
02762
02763 if (mm != MAP_FAILED) {
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773 front_misalign = (INTERNAL_SIZE_T)chunk2mem(mm) & MALLOC_ALIGN_MASK;
02774 if (front_misalign > 0) {
02775 correction = MALLOC_ALIGNMENT - front_misalign;
02776 p = (mchunkptr)(mm + correction);
02777 p->prev_size = correction;
02778 set_head(p, (size - correction) |IS_MMAPPED);
02779 }
02780 else {
02781 p = (mchunkptr)mm;
02782 set_head(p, size|IS_MMAPPED);
02783 }
02784
02785
02786
02787 if (++mp_.n_mmaps > mp_.max_n_mmaps)
02788 mp_.max_n_mmaps = mp_.n_mmaps;
02789
02790 sum = mp_.mmapped_mem += size;
02791 if (sum > (unsigned long)(mp_.max_mmapped_mem))
02792 mp_.max_mmapped_mem = sum;
02793 #ifdef NO_THREADS
02794 sum += av->system_mem;
02795 if (sum > (unsigned long)(mp_.max_total_mem))
02796 mp_.max_total_mem = sum;
02797 #endif
02798
02799 check_chunk(av, p);
02800
02801 return chunk2mem(p);
02802 }
02803 }
02804 }
02805 #endif
02806
02807
02808
02809 old_top = av->top;
02810 old_size = chunksize(old_top);
02811 old_end = (char*)(chunk_at_offset(old_top, old_size));
02812
02813 brk = snd_brk = (char*)(MORECORE_FAILURE);
02814
02815
02816
02817
02818
02819
02820 assert((old_top == initial_top(av) && old_size == 0) ||
02821 ((unsigned long) (old_size) >= MINSIZE &&
02822 prev_inuse(old_top) &&
02823 ((unsigned long)old_end & pagemask) == 0));
02824
02825
02826 assert((unsigned long)(old_size) < (unsigned long)(nb + MINSIZE));
02827
02828
02829 assert(!have_fastchunks(av));
02830
02831
02832 if (av != &main_arena) {
02833
02834 heap_info *old_heap, *heap;
02835 size_t old_heap_size;
02836
02837
02838 old_heap = heap_for_ptr(old_top);
02839 old_heap_size = old_heap->size;
02840 if (grow_heap(old_heap, MINSIZE + nb - old_size) == 0) {
02841 av->system_mem += old_heap->size - old_heap_size;
02842 arena_mem += old_heap->size - old_heap_size;
02843 #if 0
02844 if(mmapped_mem + arena_mem + sbrked_mem > max_total_mem)
02845 max_total_mem = mmapped_mem + arena_mem + sbrked_mem;
02846 #endif
02847 set_head(old_top, (((char *)old_heap + old_heap->size) - (char *)old_top)
02848 | PREV_INUSE);
02849 }
02850 else if ((heap = new_heap(nb + (MINSIZE + sizeof(*heap)), mp_.top_pad))) {
02851
02852 heap->ar_ptr = av;
02853 heap->prev = old_heap;
02854 av->system_mem += heap->size;
02855 arena_mem += heap->size;
02856 #if 0
02857 if((unsigned long)(mmapped_mem + arena_mem + sbrked_mem) > max_total_mem)
02858 max_total_mem = mmapped_mem + arena_mem + sbrked_mem;
02859 #endif
02860
02861 top(av) = chunk_at_offset(heap, sizeof(*heap));
02862 set_head(top(av), (heap->size - sizeof(*heap)) | PREV_INUSE);
02863
02864
02865
02866
02867
02868 old_size -= MINSIZE;
02869 set_head(chunk_at_offset(old_top, old_size + 2*SIZE_SZ), 0|PREV_INUSE);
02870 if (old_size >= MINSIZE) {
02871 set_head(chunk_at_offset(old_top, old_size), (2*SIZE_SZ)|PREV_INUSE);
02872 set_foot(chunk_at_offset(old_top, old_size), (2*SIZE_SZ));
02873 set_head(old_top, old_size|PREV_INUSE|NON_MAIN_ARENA);
02874 _int_free(av, chunk2mem(old_top));
02875 } else {
02876 set_head(old_top, (old_size + 2*SIZE_SZ)|PREV_INUSE);
02877 set_foot(old_top, (old_size + 2*SIZE_SZ));
02878 }
02879 }
02880
02881 } else {
02882
02883
02884
02885
02886 size = nb + mp_.top_pad + MINSIZE;
02887
02888
02889
02890
02891
02892
02893
02894 if (contiguous(av))
02895 size -= old_size;
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905 size = (size + pagemask) & ~pagemask;
02906
02907
02908
02909
02910
02911
02912
02913 if (size > 0)
02914 brk = (char*)(MORECORE(size));
02915
02916 if (brk != (char*)(MORECORE_FAILURE)) {
02917
02918 if (__after_morecore_hook)
02919 (*__after_morecore_hook) ();
02920 } else {
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930 #if HAVE_MMAP
02931
02932 if (contiguous(av))
02933 size = (size + old_size + pagemask) & ~pagemask;
02934
02935
02936 if ((unsigned long)(size) < (unsigned long)(MMAP_AS_MORECORE_SIZE))
02937 size = MMAP_AS_MORECORE_SIZE;
02938
02939
02940 if ((unsigned long)(size) > (unsigned long)(nb)) {
02941
02942 char *mbrk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE));
02943
02944 if (mbrk != MAP_FAILED) {
02945
02946
02947 brk = mbrk;
02948 snd_brk = brk + size;
02949
02950
02951
02952
02953
02954
02955
02956 set_noncontiguous(av);
02957 }
02958 }
02959 #endif
02960 }
02961
02962 if (brk != (char*)(MORECORE_FAILURE)) {
02963 if (mp_.sbrk_base == 0)
02964 mp_.sbrk_base = brk;
02965 av->system_mem += size;
02966
02967
02968
02969
02970
02971 if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE))
02972 set_head(old_top, (size + old_size) | PREV_INUSE);
02973
02974 else if (contiguous(av) && old_size && brk < old_end) {
02975
02976 assert(0);
02977 }
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998 else {
02999
03000 if (old_size)
03001 av->system_mem += brk - old_end;
03002 front_misalign = 0;
03003 end_misalign = 0;
03004 correction = 0;
03005 aligned_brk = brk;
03006
03007
03008 if (contiguous(av)) {
03009
03010
03011
03012 front_misalign = (INTERNAL_SIZE_T)chunk2mem(brk) & MALLOC_ALIGN_MASK;
03013 if (front_misalign > 0) {
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023 correction = MALLOC_ALIGNMENT - front_misalign;
03024 aligned_brk += correction;
03025 }
03026
03027
03028
03029
03030
03031
03032 correction += old_size;
03033
03034
03035 end_misalign = (INTERNAL_SIZE_T)(brk + size + correction);
03036 correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign;
03037
03038 assert(correction >= 0);
03039 snd_brk = (char*)(MORECORE(correction));
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051 if (snd_brk == (char*)(MORECORE_FAILURE)) {
03052 correction = 0;
03053 snd_brk = (char*)(MORECORE(0));
03054 } else
03055
03056 if (__after_morecore_hook)
03057 (*__after_morecore_hook) ();
03058 }
03059
03060
03061 else {
03062
03063 assert(((unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK) == 0);
03064
03065
03066 if (snd_brk == (char*)(MORECORE_FAILURE)) {
03067 snd_brk = (char*)(MORECORE(0));
03068 }
03069 }
03070
03071
03072 if (snd_brk != (char*)(MORECORE_FAILURE)) {
03073 av->top = (mchunkptr)aligned_brk;
03074 set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE);
03075 av->system_mem += correction;
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086 if (old_size != 0) {
03087
03088
03089
03090
03091
03092 old_size = (old_size - 4*SIZE_SZ) & ~MALLOC_ALIGN_MASK;
03093 set_head(old_top, old_size | PREV_INUSE);
03094
03095
03096
03097
03098
03099
03100
03101 chunk_at_offset(old_top, old_size )->size =
03102 (2*SIZE_SZ)|PREV_INUSE;
03103
03104 chunk_at_offset(old_top, old_size + 2*SIZE_SZ)->size =
03105 (2*SIZE_SZ)|PREV_INUSE;
03106
03107
03108 if (old_size >= MINSIZE) {
03109 _int_free(av, chunk2mem(old_top));
03110 }
03111
03112 }
03113 }
03114 }
03115
03116
03117 #ifdef NO_THREADS
03118 sum = av->system_mem + mp_.mmapped_mem;
03119 if (sum > (unsigned long)(mp_.max_total_mem))
03120 mp_.max_total_mem = sum;
03121 #endif
03122
03123 }
03124
03125 }
03126
03127 if ((unsigned long)av->system_mem > (unsigned long)(av->max_system_mem))
03128 av->max_system_mem = av->system_mem;
03129 check_malloc_state(av);
03130
03131
03132 p = av->top;
03133 size = chunksize(p);
03134
03135
03136 if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) {
03137 remainder_size = size - nb;
03138 remainder = chunk_at_offset(p, nb);
03139 av->top = remainder;
03140 set_head(p, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0));
03141 set_head(remainder, remainder_size | PREV_INUSE);
03142 check_malloced_chunk(av, p, nb);
03143 return chunk2mem(p);
03144 }
03145
03146
03147 MALLOC_FAILURE_ACTION;
03148 return 0;
03149 }
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161 #if __STD_C
03162 static int sYSTRIm(size_t pad, mstate av)
03163 #else
03164 static int sYSTRIm(pad, av) size_t pad; mstate av;
03165 #endif
03166 {
03167 long top_size;
03168 long extra;
03169 long released;
03170 char* current_brk;
03171 char* new_brk;
03172 size_t pagesz;
03173
03174 pagesz = mp_.pagesize;
03175 top_size = chunksize(av->top);
03176
03177
03178 extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz;
03179
03180 if (extra > 0) {
03181
03182
03183
03184
03185
03186 current_brk = (char*)(MORECORE(0));
03187 if (current_brk == (char*)(av->top) + top_size) {
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199 MORECORE(-extra);
03200
03201 if (__after_morecore_hook)
03202 (*__after_morecore_hook) ();
03203 new_brk = (char*)(MORECORE(0));
03204
03205 if (new_brk != (char*)MORECORE_FAILURE) {
03206 released = (long)(current_brk - new_brk);
03207
03208 if (released != 0) {
03209
03210 av->system_mem -= released;
03211 set_head(av->top, (top_size - released) | PREV_INUSE);
03212 check_malloc_state(av);
03213 return 1;
03214 }
03215 }
03216 }
03217 }
03218 return 0;
03219 }
03220
03221 #ifdef HAVE_MMAP
03222
03223 static void
03224 internal_function
03225 #if __STD_C
03226 munmap_chunk(mchunkptr p)
03227 #else
03228 munmap_chunk(p) mchunkptr p;
03229 #endif
03230 {
03231 INTERNAL_SIZE_T size = chunksize(p);
03232 int ret;
03233
03234 assert (chunk_is_mmapped(p));
03235 #if 0
03236 assert(! ((char*)p >= mp_.sbrk_base && (char*)p < mp_.sbrk_base + mp_.sbrked_mem));
03237 assert((mp_.n_mmaps > 0));
03238 #endif
03239 assert(((p->prev_size + size) & (mp_.pagesize-1)) == 0);
03240
03241 mp_.n_mmaps--;
03242 mp_.mmapped_mem -= (size + p->prev_size);
03243
03244 ret = munmap((char *)p - p->prev_size, size + p->prev_size);
03245
03246
03247 assert(ret == 0);
03248 }
03249
03250 #if HAVE_MREMAP
03251
03252 static mchunkptr
03253 internal_function
03254 #if __STD_C
03255 mremap_chunk(mchunkptr p, size_t new_size)
03256 #else
03257 mremap_chunk(p, new_size) mchunkptr p; size_t new_size;
03258 #endif
03259 {
03260 size_t page_mask = mp_.pagesize - 1;
03261 INTERNAL_SIZE_T offset = p->prev_size;
03262 INTERNAL_SIZE_T size = chunksize(p);
03263 char *cp;
03264
03265 assert (chunk_is_mmapped(p));
03266 #if 0
03267 assert(! ((char*)p >= mp_.sbrk_base && (char*)p < mp_.sbrk_base + mp_.sbrked_mem));
03268 assert((mp_.n_mmaps > 0));
03269 #endif
03270 assert(((size + offset) & (mp_.pagesize-1)) == 0);
03271
03272
03273 new_size = (new_size + offset + SIZE_SZ + page_mask) & ~page_mask;
03274
03275 cp = (char *)mremap((char *)p - offset, size + offset, new_size,
03276 MREMAP_MAYMOVE);
03277
03278 if (cp == MAP_FAILED) return 0;
03279
03280 p = (mchunkptr)(cp + offset);
03281
03282 assert(aligned_OK(chunk2mem(p)));
03283
03284 assert((p->prev_size == offset));
03285 set_head(p, (new_size - offset)|IS_MMAPPED);
03286
03287 mp_.mmapped_mem -= size + offset;
03288 mp_.mmapped_mem += new_size;
03289 if ((unsigned long)mp_.mmapped_mem > (unsigned long)mp_.max_mmapped_mem)
03290 mp_.max_mmapped_mem = mp_.mmapped_mem;
03291 #ifdef NO_THREADS
03292 if ((unsigned long)(mp_.mmapped_mem + arena_mem + main_arena.system_mem) >
03293 mp_.max_total_mem)
03294 mp_.max_total_mem = mp_.mmapped_mem + arena_mem + main_arena.system_mem;
03295 #endif
03296 return p;
03297 }
03298
03299 #endif
03300
03301 #endif
03302
03303
03304
03305 Void_t*
03306 public_mALLOc(size_t bytes)
03307 {
03308 mstate ar_ptr;
03309 Void_t *victim;
03310
03311 __malloc_ptr_t (*hook) __MALLOC_P ((size_t, const __malloc_ptr_t)) =
03312 __malloc_hook;
03313 if (hook != NULL)
03314 return (*hook)(bytes, RETURN_ADDRESS (0));
03315
03316 arena_get(ar_ptr, bytes);
03317 if(!ar_ptr)
03318 return 0;
03319 victim = _int_malloc(ar_ptr, bytes);
03320 if(!victim) {
03321
03322 if(ar_ptr != &main_arena) {
03323 (void)mutex_unlock(&ar_ptr->mutex);
03324 (void)mutex_lock(&main_arena.mutex);
03325 victim = _int_malloc(&main_arena, bytes);
03326 (void)mutex_unlock(&main_arena.mutex);
03327 } else {
03328 #if USE_ARENAS
03329
03330 ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes);
03331 (void)mutex_unlock(&main_arena.mutex);
03332 if(ar_ptr) {
03333 victim = _int_malloc(ar_ptr, bytes);
03334 (void)mutex_unlock(&ar_ptr->mutex);
03335 }
03336 #endif
03337 }
03338 } else
03339 (void)mutex_unlock(&ar_ptr->mutex);
03340 assert(!victim || chunk_is_mmapped(mem2chunk(victim)) ||
03341 ar_ptr == arena_for_chunk(mem2chunk(victim)));
03342
03343 if (victim!=NULL) {
03344 _memory_allocated += chunksize(mem2chunk(victim));
03345
03346 UPDATE_MEMUSAGE
03347 }
03348
03349 return victim;
03350 }
03351
03352 void
03353 public_fREe(Void_t* mem)
03354 {
03355 mstate ar_ptr;
03356 mchunkptr p;
03357
03358 void (*hook) __MALLOC_P ((__malloc_ptr_t, const __malloc_ptr_t)) =
03359 __free_hook;
03360 if (hook != NULL) {
03361 (*hook)(mem, RETURN_ADDRESS (0));
03362 return;
03363 }
03364
03365 if (mem == 0)
03366 return;
03367
03368 p = mem2chunk(mem);
03369 _memory_allocated -= chunksize(p);
03370
03371 #if HAVE_MMAP
03372 if (chunk_is_mmapped(p))
03373 {
03374 munmap_chunk(p);
03375 return;
03376 }
03377 #endif
03378
03379 ar_ptr = arena_for_chunk(p);
03380 #if THREAD_STATS
03381 if(!mutex_trylock(&ar_ptr->mutex))
03382 ++(ar_ptr->stat_lock_direct);
03383 else {
03384 (void)mutex_lock(&ar_ptr->mutex);
03385 ++(ar_ptr->stat_lock_wait);
03386 }
03387 #else
03388 (void)mutex_lock(&ar_ptr->mutex);
03389 #endif
03390 _int_free(ar_ptr, mem);
03391 (void)mutex_unlock(&ar_ptr->mutex);
03392 }
03393
03394 Void_t*
03395 public_rEALLOc(Void_t* oldmem, size_t bytes)
03396 {
03397 mstate ar_ptr;
03398 INTERNAL_SIZE_T nb;
03399
03400 mchunkptr oldp;
03401 INTERNAL_SIZE_T oldsize;
03402
03403 Void_t* newp;
03404
03405 __malloc_ptr_t (*hook) __MALLOC_P ((__malloc_ptr_t, size_t,
03406 const __malloc_ptr_t)) =
03407 __realloc_hook;
03408 if (hook != NULL)
03409 return (*hook)(oldmem, bytes, RETURN_ADDRESS (0));
03410
03411 #if REALLOC_ZERO_BYTES_FREES
03412 if (bytes == 0 && oldmem != NULL) { public_fREe(oldmem); return 0; }
03413 #endif
03414
03415
03416 if (oldmem == 0) return public_mALLOc(bytes);
03417
03418 oldp = mem2chunk(oldmem);
03419 oldsize = chunksize(oldp);
03420
03421 checked_request2size(bytes, nb);
03422
03423 _memory_allocated -= oldsize;
03424 _memory_allocated += nb;
03425
03426 UPDATE_MEMUSAGE
03427
03428 #if HAVE_MMAP
03429 if (chunk_is_mmapped(oldp))
03430 {
03431 Void_t* newmem;
03432
03433 #if HAVE_MREMAP
03434 newp = mremap_chunk(oldp, nb);
03435 if(newp) {
03436 return chunk2mem(newp);
03437 }
03438 #endif
03439
03440 if(oldsize - SIZE_SZ >= nb) return oldmem;
03441
03442 newmem = public_mALLOc(bytes);
03443 if (newmem == 0) return 0;
03444 MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
03445 munmap_chunk(oldp);
03446 return newmem;
03447 }
03448 #endif
03449
03450 ar_ptr = arena_for_chunk(oldp);
03451 #if THREAD_STATS
03452 if(!mutex_trylock(&ar_ptr->mutex))
03453 ++(ar_ptr->stat_lock_direct);
03454 else {
03455 (void)mutex_lock(&ar_ptr->mutex);
03456 ++(ar_ptr->stat_lock_wait);
03457 }
03458 #else
03459 (void)mutex_lock(&ar_ptr->mutex);
03460 #endif
03461
03462 #ifndef NO_THREADS
03463
03464 tsd_setspecific(arena_key, (Void_t *)ar_ptr);
03465 #endif
03466
03467 newp = _int_realloc(ar_ptr, oldmem, bytes);
03468
03469 (void)mutex_unlock(&ar_ptr->mutex);
03470 assert(!newp || chunk_is_mmapped(mem2chunk(newp)) ||
03471 ar_ptr == arena_for_chunk(mem2chunk(newp)));
03472 return newp;
03473 }
03474
03475 Void_t*
03476 public_mEMALIGn(size_t alignment, size_t bytes)
03477 {
03478 mstate ar_ptr;
03479 Void_t *p;
03480
03481 __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, size_t,
03482 const __malloc_ptr_t)) =
03483 __memalign_hook;
03484 if (hook != NULL)
03485 return (*hook)(alignment, bytes, RETURN_ADDRESS (0));
03486
03487
03488 if (alignment <= MALLOC_ALIGNMENT) return public_mALLOc(bytes);
03489
03490
03491 if (alignment < MINSIZE) alignment = MINSIZE;
03492
03493 arena_get(ar_ptr, bytes + alignment + MINSIZE);
03494 if(!ar_ptr)
03495 return 0;
03496 p = _int_memalign(ar_ptr, alignment, bytes);
03497 (void)mutex_unlock(&ar_ptr->mutex);
03498 if(!p) {
03499
03500 if(ar_ptr != &main_arena) {
03501 (void)mutex_lock(&main_arena.mutex);
03502 p = _int_memalign(&main_arena, alignment, bytes);
03503 (void)mutex_unlock(&main_arena.mutex);
03504 } else {
03505 #if USE_ARENAS
03506
03507 ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes);
03508 if(ar_ptr) {
03509 p = _int_memalign(ar_ptr, alignment, bytes);
03510 (void)mutex_unlock(&ar_ptr->mutex);
03511 }
03512 #endif
03513 }
03514 }
03515 assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
03516 ar_ptr == arena_for_chunk(mem2chunk(p)));
03517 _memory_allocated += chunksize(mem2chunk(p));
03518
03519 UPDATE_MEMUSAGE
03520
03521 return p;
03522 }
03523
03524 Void_t*
03525 public_vALLOc(size_t bytes)
03526 {
03527 mstate ar_ptr;
03528 Void_t *p;
03529
03530 if(__malloc_initialized < 0)
03531 ptmalloc_init ();
03532 arena_get(ar_ptr, bytes + mp_.pagesize + MINSIZE);
03533 if(!ar_ptr)
03534 return 0;
03535 p = _int_valloc(ar_ptr, bytes);
03536 (void)mutex_unlock(&ar_ptr->mutex);
03537 _memory_allocated += chunksize(mem2chunk(p));
03538
03539 UPDATE_MEMUSAGE
03540
03541 return p;
03542 }
03543
03544 Void_t*
03545 public_pVALLOc(size_t bytes)
03546 {
03547 mstate ar_ptr;
03548 Void_t *p;
03549
03550 if(__malloc_initialized < 0)
03551 ptmalloc_init ();
03552 arena_get(ar_ptr, bytes + 2*mp_.pagesize + MINSIZE);
03553 p = _int_pvalloc(ar_ptr, bytes);
03554 (void)mutex_unlock(&ar_ptr->mutex);
03555 _memory_allocated += chunksize(mem2chunk(p));
03556
03557 UPDATE_MEMUSAGE
03558
03559 return p;
03560 }
03561
03562 Void_t*
03563 public_cALLOc(size_t n, size_t elem_size)
03564 {
03565 mstate av;
03566 mchunkptr oldtop, p;
03567 INTERNAL_SIZE_T bytes, sz, csz, oldtopsize;
03568 Void_t* mem;
03569 unsigned long clearsize;
03570 unsigned long nclears;
03571 INTERNAL_SIZE_T* d;
03572 __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, const __malloc_ptr_t)) =
03573 __malloc_hook;
03574
03575
03576 bytes = n * elem_size;
03577 #define HALF_INTERNAL_SIZE_T \
03578 (((INTERNAL_SIZE_T) 1) << (8 * sizeof (INTERNAL_SIZE_T) / 2))
03579 if (__builtin_expect ((n | elem_size) >= HALF_INTERNAL_SIZE_T, 0)) {
03580 if (elem_size != 0 && bytes / elem_size != n) {
03581 MALLOC_FAILURE_ACTION;
03582 return 0;
03583 }
03584 }
03585
03586 if (hook != NULL) {
03587 sz = bytes;
03588 mem = (*hook)(sz, RETURN_ADDRESS (0));
03589 if(mem == 0)
03590 return 0;
03591 #ifdef HAVE_MEMCPY
03592 return memset(mem, 0, sz);
03593 #else
03594 while(sz > 0) ((char*)mem)[--sz] = 0;
03595 return mem;
03596 #endif
03597 }
03598
03599 sz = bytes;
03600
03601 arena_get(av, sz);
03602 if(!av)
03603 return 0;
03604
03605
03606
03607 #if MORECORE_CLEARS
03608 oldtop = top(av);
03609 oldtopsize = chunksize(top(av));
03610 #if MORECORE_CLEARS < 2
03611
03612 if (av == &main_arena &&
03613 oldtopsize < mp_.sbrk_base + av->max_system_mem - (char *)oldtop)
03614 oldtopsize = (mp_.sbrk_base + av->max_system_mem - (char *)oldtop);
03615 #endif
03616 #endif
03617 mem = _int_malloc(av, sz);
03618
03619
03620 (void)mutex_unlock(&av->mutex);
03621
03622 assert(!mem || chunk_is_mmapped(mem2chunk(mem)) ||
03623 av == arena_for_chunk(mem2chunk(mem)));
03624
03625 if (mem == 0) {
03626
03627 if(av != &main_arena) {
03628 (void)mutex_lock(&main_arena.mutex);
03629 mem = _int_malloc(&main_arena, sz);
03630 (void)mutex_unlock(&main_arena.mutex);
03631 } else {
03632 #if USE_ARENAS
03633
03634 (void)mutex_lock(&main_arena.mutex);
03635 av = arena_get2(av->next ? av : 0, sz);
03636 (void)mutex_unlock(&main_arena.mutex);
03637 if(av) {
03638 mem = _int_malloc(av, sz);
03639 (void)mutex_unlock(&av->mutex);
03640 }
03641 #endif
03642 }
03643 if (mem == 0) return 0;
03644 }
03645 p = mem2chunk(mem);
03646 _memory_allocated += chunksize(p);
03647
03648 UPDATE_MEMUSAGE
03649
03650
03651 #if HAVE_MMAP
03652 if (chunk_is_mmapped(p))
03653 return mem;
03654 #endif
03655
03656 csz = chunksize(p);
03657
03658 #if MORECORE_CLEARS
03659 if (p == oldtop && csz > oldtopsize) {
03660
03661 csz = oldtopsize;
03662 }
03663 #endif
03664
03665
03666
03667
03668 d = (INTERNAL_SIZE_T*)mem;
03669 clearsize = csz - SIZE_SZ;
03670 nclears = clearsize / sizeof(INTERNAL_SIZE_T);
03671 assert(nclears >= 3);
03672
03673 if (nclears > 9)
03674 MALLOC_ZERO(d, clearsize);
03675
03676 else {
03677 *(d+0) = 0;
03678 *(d+1) = 0;
03679 *(d+2) = 0;
03680 if (nclears > 4) {
03681 *(d+3) = 0;
03682 *(d+4) = 0;
03683 if (nclears > 6) {
03684 *(d+5) = 0;
03685 *(d+6) = 0;
03686 if (nclears > 8) {
03687 *(d+7) = 0;
03688 *(d+8) = 0;
03689 }
03690 }
03691 }
03692 }
03693
03694 return mem;
03695 }
03696
03697 Void_t**
03698 public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks)
03699 {
03700 mstate ar_ptr;
03701 Void_t** m;
03702
03703 arena_get(ar_ptr, n*elem_size);
03704 if(!ar_ptr)
03705 return 0;
03706
03707 m = _int_icalloc(ar_ptr, n, elem_size, chunks);
03708 (void)mutex_unlock(&ar_ptr->mutex);
03709 _memory_allocated += chunksize(mem2chunk(m));
03710
03711 UPDATE_MEMUSAGE
03712
03713 return m;
03714 }
03715
03716 Void_t**
03717 public_iCOMALLOc(size_t n, size_t sizes[], Void_t** chunks)
03718 {
03719 mstate ar_ptr;
03720 Void_t** m;
03721
03722 arena_get(ar_ptr, 0);
03723 if(!ar_ptr)
03724 return 0;
03725
03726 m = _int_icomalloc(ar_ptr, n, sizes, chunks);
03727 (void)mutex_unlock(&ar_ptr->mutex);
03728 _memory_allocated += chunksize(mem2chunk(m));
03729
03730 UPDATE_MEMUSAGE
03731
03732 return m;
03733 }
03734
03735 #ifndef _LIBC
03736
03737 void
03738 public_cFREe(Void_t* m)
03739 {
03740 public_fREe(m);
03741 }
03742
03743 #endif
03744
03745 int
03746 public_mTRIm(size_t s)
03747 {
03748 int result;
03749
03750 (void)mutex_lock(&main_arena.mutex);
03751 result = mTRIm(s);
03752 (void)mutex_unlock(&main_arena.mutex);
03753 return result;
03754 }
03755
03756 size_t
03757 public_mUSABLe(Void_t* m)
03758 {
03759 size_t result;
03760
03761 result = mUSABLe(m);
03762 return result;
03763 }
03764
03765 void
03766 public_mSTATs()
03767 {
03768 mSTATs();
03769 }
03770
03771 struct mallinfo public_mALLINFo()
03772 {
03773 struct mallinfo m;
03774
03775 (void)mutex_lock(&main_arena.mutex);
03776 m = mALLINFo(&main_arena);
03777 (void)mutex_unlock(&main_arena.mutex);
03778 return m;
03779 }
03780
03781 int
03782 public_mALLOPt(int p, int v)
03783 {
03784 int result;
03785 result = mALLOPt(p, v);
03786 return result;
03787 }
03788
03789
03790
03791
03792
03793 Void_t*
03794 _int_malloc(mstate av, size_t bytes)
03795 {
03796 INTERNAL_SIZE_T nb;
03797 unsigned int idx;
03798 mbinptr bin;
03799 mfastbinptr* fb;
03800
03801 mchunkptr victim;
03802 INTERNAL_SIZE_T size;
03803 int victim_index;
03804
03805 mchunkptr remainder;
03806 unsigned long remainder_size;
03807
03808 unsigned int block;
03809 unsigned int bit;
03810 unsigned int map;
03811
03812 mchunkptr fwd;
03813 mchunkptr bck;
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824 checked_request2size(bytes, nb);
03825
03826
03827
03828
03829
03830
03831
03832 if ((unsigned long)(nb) <= (unsigned long)(av->max_fast)) {
03833 fb = &(av->fastbins[(fastbin_index(nb))]);
03834 if ( (victim = *fb) != 0) {
03835 *fb = victim->fd;
03836 check_remalloced_chunk(av, victim, nb);
03837 return chunk2mem(victim);
03838 }
03839 }
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849 if (in_smallbin_range(nb)) {
03850 idx = smallbin_index(nb);
03851 bin = bin_at(av,idx);
03852
03853 if ( (victim = last(bin)) != bin) {
03854 if (victim == 0)
03855 malloc_consolidate(av);
03856 else {
03857 bck = victim->bk;
03858 set_inuse_bit_at_offset(victim, nb);
03859 bin->bk = bck;
03860 bck->fd = bin;
03861
03862 if (av != &main_arena)
03863 victim->size |= NON_MAIN_ARENA;
03864 check_malloced_chunk(av, victim, nb);
03865 return chunk2mem(victim);
03866 }
03867 }
03868 }
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881 else {
03882 idx = largebin_index(nb);
03883 if (have_fastchunks(av))
03884 malloc_consolidate(av);
03885 }
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900 for(;;) {
03901
03902 while ( (victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) {
03903 bck = victim->bk;
03904 size = chunksize(victim);
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914 if (in_smallbin_range(nb) &&
03915 bck == unsorted_chunks(av) &&
03916 victim == av->last_remainder &&
03917 (unsigned long)(size) > (unsigned long)(nb + MINSIZE)) {
03918
03919
03920 remainder_size = size - nb;
03921 remainder = chunk_at_offset(victim, nb);
03922 unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
03923 av->last_remainder = remainder;
03924 remainder->bk = remainder->fd = unsorted_chunks(av);
03925
03926 set_head(victim, nb | PREV_INUSE |
03927 (av != &main_arena ? NON_MAIN_ARENA : 0));
03928 set_head(remainder, remainder_size | PREV_INUSE);
03929 set_foot(remainder, remainder_size);
03930
03931 check_malloced_chunk(av, victim, nb);
03932 return chunk2mem(victim);
03933 }
03934
03935
03936 unsorted_chunks(av)->bk = bck;
03937 bck->fd = unsorted_chunks(av);
03938
03939
03940
03941 if (size == nb) {
03942 set_inuse_bit_at_offset(victim, size);
03943 if (av != &main_arena)
03944 victim->size |= NON_MAIN_ARENA;
03945 check_malloced_chunk(av, victim, nb);
03946 return chunk2mem(victim);
03947 }
03948
03949
03950
03951 if (in_smallbin_range(size)) {
03952 victim_index = smallbin_index(size);
03953 bck = bin_at(av, victim_index);
03954 fwd = bck->fd;
03955 }
03956 else {
03957 victim_index = largebin_index(size);
03958 bck = bin_at(av, victim_index);
03959 fwd = bck->fd;
03960
03961
03962 if (fwd != bck) {
03963
03964 size |= PREV_INUSE;
03965
03966 assert((bck->bk->size & NON_MAIN_ARENA) == 0);
03967 if ((unsigned long)(size) <= (unsigned long)(bck->bk->size)) {
03968 fwd = bck;
03969 bck = bck->bk;
03970 }
03971 else {
03972 assert((fwd->size & NON_MAIN_ARENA) == 0);
03973 while ((unsigned long)(size) < (unsigned long)(fwd->size)) {
03974 fwd = fwd->fd;
03975 assert((fwd->size & NON_MAIN_ARENA) == 0);
03976 }
03977 bck = fwd->bk;
03978 }
03979 }
03980 }
03981
03982 mark_bin(av, victim_index);
03983 victim->bk = bck;
03984 victim->fd = fwd;
03985 fwd->bk = victim;
03986 bck->fd = victim;
03987 }
03988
03989
03990
03991
03992
03993
03994
03995
03996 if (!in_smallbin_range(nb)) {
03997 bin = bin_at(av, idx);
03998
03999
04000 if ((victim = last(bin)) != bin &&
04001 (unsigned long)(first(bin)->size) >= (unsigned long)(nb)) {
04002
04003 while (((unsigned long)(size = chunksize(victim)) <
04004 (unsigned long)(nb)))
04005 victim = victim->bk;
04006
04007 remainder_size = size - nb;
04008 unlink(victim, bck, fwd);
04009
04010
04011 if (remainder_size < MINSIZE) {
04012 set_inuse_bit_at_offset(victim, size);
04013 if (av != &main_arena)
04014 victim->size |= NON_MAIN_ARENA;
04015 check_malloced_chunk(av, victim, nb);
04016 return chunk2mem(victim);
04017 }
04018
04019 else {
04020 remainder = chunk_at_offset(victim, nb);
04021 unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
04022 remainder->bk = remainder->fd = unsorted_chunks(av);
04023 set_head(victim, nb | PREV_INUSE |
04024 (av != &main_arena ? NON_MAIN_ARENA : 0));
04025 set_head(remainder, remainder_size | PREV_INUSE);
04026 set_foot(remainder, remainder_size);
04027 check_malloced_chunk(av, victim, nb);
04028 return chunk2mem(victim);
04029 }
04030 }
04031 }
04032
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044 ++idx;
04045 bin = bin_at(av,idx);
04046 block = idx2block(idx);
04047 map = av->binmap[block];
04048 bit = idx2bit(idx);
04049
04050 for (;;) {
04051
04052
04053 if (bit > map || bit == 0) {
04054 do {
04055 if (++block >= BINMAPSIZE)
04056 goto use_top;
04057 } while ( (map = av->binmap[block]) == 0);
04058
04059 bin = bin_at(av, (block << BINMAPSHIFT));
04060 bit = 1;
04061 }
04062
04063
04064 while ((bit & map) == 0) {
04065 bin = next_bin(bin);
04066 bit <<= 1;
04067 assert(bit != 0);
04068 }
04069
04070
04071 victim = last(bin);
04072
04073
04074 if (victim == bin) {
04075 av->binmap[block] = map &= ~bit;
04076 bin = next_bin(bin);
04077 bit <<= 1;
04078 }
04079
04080 else {
04081 size = chunksize(victim);
04082
04083
04084 assert((unsigned long)(size) >= (unsigned long)(nb));
04085
04086 remainder_size = size - nb;
04087
04088
04089 bck = victim->bk;
04090 bin->bk = bck;
04091 bck->fd = bin;
04092
04093
04094 if (remainder_size < MINSIZE) {
04095 set_inuse_bit_at_offset(victim, size);
04096 if (av != &main_arena)
04097 victim->size |= NON_MAIN_ARENA;
04098 check_malloced_chunk(av, victim, nb);
04099 return chunk2mem(victim);
04100 }
04101
04102
04103 else {
04104 remainder = chunk_at_offset(victim, nb);
04105
04106 unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
04107 remainder->bk = remainder->fd = unsorted_chunks(av);
04108
04109 if (in_smallbin_range(nb))
04110 av->last_remainder = remainder;
04111
04112 set_head(victim, nb | PREV_INUSE |
04113 (av != &main_arena ? NON_MAIN_ARENA : 0));
04114 set_head(remainder, remainder_size | PREV_INUSE);
04115 set_foot(remainder, remainder_size);
04116 check_malloced_chunk(av, victim, nb);
04117 return chunk2mem(victim);
04118 }
04119 }
04120 }
04121
04122 use_top:
04123
04124
04125
04126
04127
04128
04129
04130
04131
04132
04133
04134
04135
04136
04137
04138 victim = av->top;
04139 size = chunksize(victim);
04140
04141 if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) {
04142 remainder_size = size - nb;
04143 remainder = chunk_at_offset(victim, nb);
04144 av->top = remainder;
04145 set_head(victim, nb | PREV_INUSE |
04146 (av != &main_arena ? NON_MAIN_ARENA : 0));
04147 set_head(remainder, remainder_size | PREV_INUSE);
04148
04149 check_malloced_chunk(av, victim, nb);
04150 return chunk2mem(victim);
04151 }
04152
04153
04154
04155
04156
04157
04158
04159 else if (have_fastchunks(av)) {
04160 assert(in_smallbin_range(nb));
04161 malloc_consolidate(av);
04162 idx = smallbin_index(nb);
04163 }
04164
04165
04166
04167
04168 else
04169 return sYSMALLOc(nb, av);
04170 }
04171 }
04172
04173
04174
04175
04176
04177 void
04178 _int_free(mstate av, Void_t* mem)
04179 {
04180 mchunkptr p;
04181 INTERNAL_SIZE_T size;
04182 mfastbinptr* fb;
04183 mchunkptr nextchunk;
04184 INTERNAL_SIZE_T nextsize;
04185 int nextinuse;
04186 INTERNAL_SIZE_T prevsize;
04187 mchunkptr bck;
04188 mchunkptr fwd;
04189
04190
04191
04192 if (mem != 0) {
04193 p = mem2chunk(mem);
04194 size = chunksize(p);
04195
04196 check_inuse_chunk(av, p);
04197
04198
04199
04200
04201
04202
04203 if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
04204
04205 #if TRIM_FASTBINS
04206
04207
04208
04209
04210 && (chunk_at_offset(p, size) != av->top)
04211 #endif
04212 ) {
04213
04214 set_fastchunks(av);
04215 fb = &(av->fastbins[fastbin_index(size)]);
04216 p->fd = *fb;
04217 *fb = p;
04218 }
04219
04220
04221
04222
04223
04224 else if (!chunk_is_mmapped(p)) {
04225 nextchunk = chunk_at_offset(p, size);
04226 nextsize = chunksize(nextchunk);
04227 assert(nextsize > 0);
04228
04229
04230 if (!prev_inuse(p)) {
04231 prevsize = p->prev_size;
04232 size += prevsize;
04233 p = chunk_at_offset(p, -((long) prevsize));
04234 unlink(p, bck, fwd);
04235 }
04236
04237 if (nextchunk != av->top) {
04238
04239 nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
04240
04241
04242 if (!nextinuse) {
04243 unlink(nextchunk, bck, fwd);
04244 size += nextsize;
04245 } else
04246 clear_inuse_bit_at_offset(nextchunk, 0);
04247
04248
04249
04250
04251
04252
04253
04254 bck = unsorted_chunks(av);
04255 fwd = bck->fd;
04256 p->bk = bck;
04257 p->fd = fwd;
04258 bck->fd = p;
04259 fwd->bk = p;
04260
04261 set_head(p, size | PREV_INUSE);
04262 set_foot(p, size);
04263
04264 check_free_chunk(av, p);
04265 }
04266
04267
04268
04269
04270
04271
04272 else {
04273 size += nextsize;
04274 set_head(p, size | PREV_INUSE);
04275 av->top = p;
04276 check_chunk(av, p);
04277 }
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290
04291
04292 if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
04293 if (have_fastchunks(av))
04294 malloc_consolidate(av);
04295
04296 if (av == &main_arena) {
04297 #ifndef MORECORE_CANNOT_TRIM
04298 if ((unsigned long)(chunksize(av->top)) >=
04299 (unsigned long)(mp_.trim_threshold))
04300 sYSTRIm(mp_.top_pad, av);
04301 #endif
04302 } else {
04303
04304
04305 heap_info *heap = heap_for_ptr(top(av));
04306
04307 assert(heap->ar_ptr == av);
04308 heap_trim(heap, mp_.top_pad);
04309 }
04310 }
04311
04312 }
04313
04314
04315
04316
04317
04318
04319
04320
04321 else {
04322 #if HAVE_MMAP
04323 int ret;
04324 INTERNAL_SIZE_T offset = p->prev_size;
04325 mp_.n_mmaps--;
04326 mp_.mmapped_mem -= (size + offset);
04327 ret = munmap((char*)p - offset, size + offset);
04328
04329 assert(ret == 0);
04330 #endif
04331 }
04332 }
04333 }
04334
04335
04336
04337
04338
04339
04340
04341
04342
04343
04344
04345
04346
04347
04348
04349 #if __STD_C
04350 static void malloc_consolidate(mstate av)
04351 #else
04352 static void malloc_consolidate(av) mstate av;
04353 #endif
04354 {
04355 mfastbinptr* fb;
04356 mfastbinptr* maxfb;
04357 mchunkptr p;
04358 mchunkptr nextp;
04359 mchunkptr unsorted_bin;
04360 mchunkptr first_unsorted;
04361
04362
04363 mchunkptr nextchunk;
04364 INTERNAL_SIZE_T size;
04365 INTERNAL_SIZE_T nextsize;
04366 INTERNAL_SIZE_T prevsize;
04367 int nextinuse;
04368 mchunkptr bck;
04369 mchunkptr fwd;
04370
04371
04372
04373
04374
04375
04376 if (av->max_fast != 0) {
04377 clear_fastchunks(av);
04378
04379 unsorted_bin = unsorted_chunks(av);
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389 maxfb = &(av->fastbins[fastbin_index(av->max_fast)]);
04390 fb = &(av->fastbins[0]);
04391 do {
04392 if ( (p = *fb) != 0) {
04393 *fb = 0;
04394
04395 do {
04396 check_inuse_chunk(av, p);
04397 nextp = p->fd;
04398
04399
04400 size = p->size & ~(PREV_INUSE|NON_MAIN_ARENA);
04401 nextchunk = chunk_at_offset(p, size);
04402 nextsize = chunksize(nextchunk);
04403
04404 if (!prev_inuse(p)) {
04405 prevsize = p->prev_size;
04406 size += prevsize;
04407 p = chunk_at_offset(p, -((long) prevsize));
04408 unlink(p, bck, fwd);
04409 }
04410
04411 if (nextchunk != av->top) {
04412 nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
04413
04414 if (!nextinuse) {
04415 size += nextsize;
04416 unlink(nextchunk, bck, fwd);
04417 } else
04418 clear_inuse_bit_at_offset(nextchunk, 0);
04419
04420 first_unsorted = unsorted_bin->fd;
04421 unsorted_bin->fd = p;
04422 first_unsorted->bk = p;
04423
04424 set_head(p, size | PREV_INUSE);
04425 p->bk = unsorted_bin;
04426 p->fd = first_unsorted;
04427 set_foot(p, size);
04428 }
04429
04430 else {
04431 size += nextsize;
04432 set_head(p, size | PREV_INUSE);
04433 av->top = p;
04434 }
04435
04436 } while ( (p = nextp) != 0);
04437
04438 }
04439 } while (fb++ != maxfb);
04440 }
04441 else {
04442 malloc_init_state(av);
04443 check_malloc_state(av);
04444 }
04445 }
04446
04447
04448
04449
04450
04451 Void_t*
04452 _int_realloc(mstate av, Void_t* oldmem, size_t bytes)
04453 {
04454 INTERNAL_SIZE_T nb;
04455
04456 mchunkptr oldp;
04457 INTERNAL_SIZE_T oldsize;
04458
04459 mchunkptr newp;
04460 INTERNAL_SIZE_T newsize;
04461 Void_t* newmem;
04462
04463 mchunkptr next;
04464
04465 mchunkptr remainder;
04466 unsigned long remainder_size;
04467
04468 mchunkptr bck;
04469 mchunkptr fwd;
04470
04471 unsigned long copysize;
04472 unsigned int ncopies;
04473 INTERNAL_SIZE_T* s;
04474 INTERNAL_SIZE_T* d;
04475
04476
04477 #if REALLOC_ZERO_BYTES_FREES
04478 if (bytes == 0) {
04479 _int_free(av, oldmem);
04480 return 0;
04481 }
04482 #endif
04483
04484
04485 if (oldmem == 0) return _int_malloc(av, bytes);
04486
04487 checked_request2size(bytes, nb);
04488
04489 oldp = mem2chunk(oldmem);
04490 oldsize = chunksize(oldp);
04491
04492 check_inuse_chunk(av, oldp);
04493
04494 if (!chunk_is_mmapped(oldp)) {
04495
04496 if ((unsigned long)(oldsize) >= (unsigned long)(nb)) {
04497
04498 newp = oldp;
04499 newsize = oldsize;
04500 }
04501
04502 else {
04503 next = chunk_at_offset(oldp, oldsize);
04504
04505
04506 if (next == av->top &&
04507 (unsigned long)(newsize = oldsize + chunksize(next)) >=
04508 (unsigned long)(nb + MINSIZE)) {
04509 set_head_size(oldp, nb | (av != &main_arena ? NON_MAIN_ARENA : 0));
04510 av->top = chunk_at_offset(oldp, nb);
04511 set_head(av->top, (newsize - nb) | PREV_INUSE);
04512 check_inuse_chunk(av, oldp);
04513 return chunk2mem(oldp);
04514 }
04515
04516
04517 else if (next != av->top &&
04518 !inuse(next) &&
04519 (unsigned long)(newsize = oldsize + chunksize(next)) >=
04520 (unsigned long)(nb)) {
04521 newp = oldp;
04522 unlink(next, bck, fwd);
04523 }
04524
04525
04526 else {
04527 newmem = _int_malloc(av, nb - MALLOC_ALIGN_MASK);
04528 if (newmem == 0)
04529 return 0;
04530
04531 newp = mem2chunk(newmem);
04532 newsize = chunksize(newp);
04533
04534
04535
04536
04537 if (newp == next) {
04538 newsize += oldsize;
04539 newp = oldp;
04540 }
04541 else {
04542
04543
04544
04545
04546
04547
04548 copysize = oldsize - SIZE_SZ;
04549 s = (INTERNAL_SIZE_T*)(oldmem);
04550 d = (INTERNAL_SIZE_T*)(newmem);
04551 ncopies = copysize / sizeof(INTERNAL_SIZE_T);
04552 assert(ncopies >= 3);
04553
04554 if (ncopies > 9)
04555 MALLOC_COPY(d, s, copysize);
04556
04557 else {
04558 *(d+0) = *(s+0);
04559 *(d+1) = *(s+1);
04560 *(d+2) = *(s+2);
04561 if (ncopies > 4) {
04562 *(d+3) = *(s+3);
04563 *(d+4) = *(s+4);
04564 if (ncopies > 6) {
04565 *(d+5) = *(s+5);
04566 *(d+6) = *(s+6);
04567 if (ncopies > 8) {
04568 *(d+7) = *(s+7);
04569 *(d+8) = *(s+8);
04570 }
04571 }
04572 }
04573 }
04574
04575 _int_free(av, oldmem);
04576 check_inuse_chunk(av, newp);
04577 return chunk2mem(newp);
04578 }
04579 }
04580 }
04581
04582
04583
04584 assert((unsigned long)(newsize) >= (unsigned long)(nb));
04585
04586 remainder_size = newsize - nb;
04587
04588 if (remainder_size < MINSIZE) {
04589 set_head_size(newp, newsize | (av != &main_arena ? NON_MAIN_ARENA : 0));
04590 set_inuse_bit_at_offset(newp, newsize);
04591 }
04592 else {
04593 remainder = chunk_at_offset(newp, nb);
04594 set_head_size(newp, nb | (av != &main_arena ? NON_MAIN_ARENA : 0));
04595 set_head(remainder, remainder_size | PREV_INUSE |
04596 (av != &main_arena ? NON_MAIN_ARENA : 0));
04597
04598 set_inuse_bit_at_offset(remainder, remainder_size);
04599 _int_free(av, chunk2mem(remainder));
04600 }
04601
04602 check_inuse_chunk(av, newp);
04603 return chunk2mem(newp);
04604 }
04605
04606
04607
04608
04609
04610 else {
04611 #if HAVE_MMAP
04612
04613 #if HAVE_MREMAP
04614 INTERNAL_SIZE_T offset = oldp->prev_size;
04615 size_t pagemask = mp_.pagesize - 1;
04616 char *cp;
04617 unsigned long sum;
04618
04619
04620 newsize = (nb + offset + SIZE_SZ + pagemask) & ~pagemask;
04621
04622
04623 if (oldsize == newsize - offset)
04624 return oldmem;
04625
04626 cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1);
04627
04628 if (cp != MAP_FAILED) {
04629
04630 newp = (mchunkptr)(cp + offset);
04631 set_head(newp, (newsize - offset)|IS_MMAPPED);
04632
04633 assert(aligned_OK(chunk2mem(newp)));
04634 assert((newp->prev_size == offset));
04635
04636
04637 sum = mp_.mmapped_mem += newsize - oldsize;
04638 if (sum > (unsigned long)(mp_.max_mmapped_mem))
04639 mp_.max_mmapped_mem = sum;
04640 #ifdef NO_THREADS
04641 sum += main_arena.system_mem;
04642 if (sum > (unsigned long)(mp_.max_total_mem))
04643 mp_.max_total_mem = sum;
04644 #endif
04645
04646 return chunk2mem(newp);
04647 }
04648 #endif
04649
04650
04651 if ((unsigned long)(oldsize) >= (unsigned long)(nb + SIZE_SZ))
04652 newmem = oldmem;
04653 else {
04654
04655 newmem = _int_malloc(av, nb - MALLOC_ALIGN_MASK);
04656 if (newmem != 0) {
04657 MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
04658 _int_free(av, oldmem);
04659 }
04660 }
04661 return newmem;
04662
04663 #else
04664
04665 check_malloc_state(av);
04666 MALLOC_FAILURE_ACTION;
04667 return 0;
04668 #endif
04669 }
04670 }
04671
04672
04673
04674
04675
04676 Void_t*
04677 _int_memalign(mstate av, size_t alignment, size_t bytes)
04678 {
04679 INTERNAL_SIZE_T nb;
04680 char* m;
04681 mchunkptr p;
04682 char* brk;
04683 mchunkptr newp;
04684 INTERNAL_SIZE_T newsize;
04685 INTERNAL_SIZE_T leadsize;
04686 mchunkptr remainder;
04687 unsigned long remainder_size;
04688 INTERNAL_SIZE_T size;
04689
04690
04691
04692 if (alignment <= MALLOC_ALIGNMENT) return _int_malloc(av, bytes);
04693
04694
04695
04696 if (alignment < MINSIZE) alignment = MINSIZE;
04697
04698
04699 if ((alignment & (alignment - 1)) != 0) {
04700 size_t a = MALLOC_ALIGNMENT * 2;
04701 while ((unsigned long)a < (unsigned long)alignment) a <<= 1;
04702 alignment = a;
04703 }
04704
04705 checked_request2size(bytes, nb);
04706
04707
04708
04709
04710
04711
04712
04713
04714
04715 m = (char*)(_int_malloc(av, nb + alignment + MINSIZE));
04716
04717 if (m == 0) return 0;
04718
04719 p = mem2chunk(m);
04720
04721 if ((((unsigned long)(m)) % alignment) != 0) {
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731 brk = (char*)mem2chunk(((unsigned long)(m + alignment - 1)) &
04732 -((signed long) alignment));
04733 if ((unsigned long)(brk - (char*)(p)) < MINSIZE)
04734 brk += alignment;
04735
04736 newp = (mchunkptr)brk;
04737 leadsize = brk - (char*)(p);
04738 newsize = chunksize(p) - leadsize;
04739
04740
04741 if (chunk_is_mmapped(p)) {
04742 newp->prev_size = p->prev_size + leadsize;
04743 set_head(newp, newsize|IS_MMAPPED);
04744 return chunk2mem(newp);
04745 }
04746
04747
04748 set_head(newp, newsize | PREV_INUSE |
04749 (av != &main_arena ? NON_MAIN_ARENA : 0));
04750 set_inuse_bit_at_offset(newp, newsize);
04751 set_head_size(p, leadsize | (av != &main_arena ? NON_MAIN_ARENA : 0));
04752 _int_free(av, chunk2mem(p));
04753 p = newp;
04754
04755 assert (newsize >= nb &&
04756 (((unsigned long)(chunk2mem(p))) % alignment) == 0);
04757 }
04758
04759
04760 if (!chunk_is_mmapped(p)) {
04761 size = chunksize(p);
04762 if ((unsigned long)(size) > (unsigned long)(nb + MINSIZE)) {
04763 remainder_size = size - nb;
04764 remainder = chunk_at_offset(p, nb);
04765 set_head(remainder, remainder_size | PREV_INUSE |
04766 (av != &main_arena ? NON_MAIN_ARENA : 0));
04767 set_head_size(p, nb);
04768 _int_free(av, chunk2mem(remainder));
04769 }
04770 }
04771
04772 check_inuse_chunk(av, p);
04773 return chunk2mem(p);
04774 }
04775
04776 #if 0
04777
04778
04779
04780
04781 #if __STD_C
04782 Void_t* cALLOc(size_t n_elements, size_t elem_size)
04783 #else
04784 Void_t* cALLOc(n_elements, elem_size) size_t n_elements; size_t elem_size;
04785 #endif
04786 {
04787 mchunkptr p;
04788 unsigned long clearsize;
04789 unsigned long nclears;
04790 INTERNAL_SIZE_T* d;
04791
04792 Void_t* mem = mALLOc(n_elements * elem_size);
04793
04794 if (mem != 0) {
04795 p = mem2chunk(mem);
04796
04797 #if MMAP_CLEARS
04798 if (!chunk_is_mmapped(p))
04799 #endif
04800 {
04801
04802
04803
04804
04805
04806
04807 d = (INTERNAL_SIZE_T*)mem;
04808 clearsize = chunksize(p) - SIZE_SZ;
04809 nclears = clearsize / sizeof(INTERNAL_SIZE_T);
04810 assert(nclears >= 3);
04811
04812 if (nclears > 9)
04813 MALLOC_ZERO(d, clearsize);
04814
04815 else {
04816 *(d+0) = 0;
04817 *(d+1) = 0;
04818 *(d+2) = 0;
04819 if (nclears > 4) {
04820 *(d+3) = 0;
04821 *(d+4) = 0;
04822 if (nclears > 6) {
04823 *(d+5) = 0;
04824 *(d+6) = 0;
04825 if (nclears > 8) {
04826 *(d+7) = 0;
04827 *(d+8) = 0;
04828 }
04829 }
04830 }
04831 }
04832 }
04833 }
04834 return mem;
04835 }
04836 #endif
04837
04838
04839
04840
04841
04842 Void_t**
04843 #if __STD_C
04844 _int_icalloc(mstate av, size_t n_elements, size_t elem_size, Void_t* chunks[])
04845 #else
04846 _int_icalloc(av, n_elements, elem_size, chunks)
04847 mstate av; size_t n_elements; size_t elem_size; Void_t* chunks[];
04848 #endif
04849 {
04850 size_t sz = elem_size;
04851
04852 return iALLOc(av, n_elements, &sz, 3, chunks);
04853 }
04854
04855
04856
04857
04858
04859 Void_t**
04860 #if __STD_C
04861 _int_icomalloc(mstate av, size_t n_elements, size_t sizes[], Void_t* chunks[])
04862 #else
04863 _int_icomalloc(av, n_elements, sizes, chunks)
04864 mstate av; size_t n_elements; size_t sizes[]; Void_t* chunks[];
04865 #endif
04866 {
04867 return iALLOc(av, n_elements, sizes, 0, chunks);
04868 }
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880
04881
04882 static Void_t**
04883 #if __STD_C
04884 iALLOc(mstate av, size_t n_elements, size_t* sizes, int opts, Void_t* chunks[])
04885 #else
04886 iALLOc(av, n_elements, sizes, opts, chunks)
04887 mstate av; size_t n_elements; size_t* sizes; int opts; Void_t* chunks[];
04888 #endif
04889 {
04890 INTERNAL_SIZE_T element_size;
04891 INTERNAL_SIZE_T contents_size;
04892 INTERNAL_SIZE_T array_size;
04893 Void_t* mem;
04894 mchunkptr p;
04895 INTERNAL_SIZE_T remainder_size;
04896 Void_t** marray;
04897 mchunkptr array_chunk;
04898 int mmx;
04899 INTERNAL_SIZE_T size;
04900 INTERNAL_SIZE_T size_flags;
04901 size_t i;
04902
04903
04904 if (have_fastchunks(av)) malloc_consolidate(av);
04905
04906
04907 if (chunks != 0) {
04908 if (n_elements == 0)
04909 return chunks;
04910 marray = chunks;
04911 array_size = 0;
04912 }
04913 else {
04914
04915 if (n_elements == 0)
04916 return (Void_t**) _int_malloc(av, 0);
04917 marray = 0;
04918 array_size = request2size(n_elements * (sizeof(Void_t*)));
04919 }
04920
04921
04922 if (opts & 0x1) {
04923 element_size = request2size(*sizes);
04924 contents_size = n_elements * element_size;
04925 }
04926 else {
04927 element_size = 0;
04928 contents_size = 0;
04929 for (i = 0; i != n_elements; ++i)
04930 contents_size += request2size(sizes[i]);
04931 }
04932
04933
04934 size = contents_size + array_size - MALLOC_ALIGN_MASK;
04935
04936
04937
04938
04939
04940
04941
04942 mmx = mp_.n_mmaps_max;
04943 mp_.n_mmaps_max = 0;
04944 mem = _int_malloc(av, size);
04945 mp_.n_mmaps_max = mmx;
04946 if (mem == 0)
04947 return 0;
04948
04949 p = mem2chunk(mem);
04950 assert(!chunk_is_mmapped(p));
04951 remainder_size = chunksize(p);
04952
04953 if (opts & 0x2) {
04954 MALLOC_ZERO(mem, remainder_size - SIZE_SZ - array_size);
04955 }
04956
04957 size_flags = PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0);
04958
04959
04960 if (marray == 0) {
04961 array_chunk = chunk_at_offset(p, contents_size);
04962 marray = (Void_t**) (chunk2mem(array_chunk));
04963 set_head(array_chunk, (remainder_size - contents_size) | size_flags);
04964 remainder_size = contents_size;
04965 }
04966
04967
04968 for (i = 0; ; ++i) {
04969 marray[i] = chunk2mem(p);
04970 if (i != n_elements-1) {
04971 if (element_size != 0)
04972 size = element_size;
04973 else
04974 size = request2size(sizes[i]);
04975 remainder_size -= size;
04976 set_head(p, size | size_flags);
04977 p = chunk_at_offset(p, size);
04978 }
04979 else {
04980 set_head(p, remainder_size | size_flags);
04981 break;
04982 }
04983 }
04984
04985 #if MALLOC_DEBUG
04986 if (marray != chunks) {
04987
04988 if (element_size != 0)
04989 assert(remainder_size == element_size);
04990 else
04991 assert(remainder_size == request2size(sizes[i]));
04992 check_inuse_chunk(av, mem2chunk(marray));
04993 }
04994
04995 for (i = 0; i != n_elements; ++i)
04996 check_inuse_chunk(av, mem2chunk(marray[i]));
04997 #endif
04998
04999 return marray;
05000 }
05001
05002
05003
05004
05005
05006
05007 Void_t*
05008 #if __STD_C
05009 _int_valloc(mstate av, size_t bytes)
05010 #else
05011 _int_valloc(av, bytes) mstate av; size_t bytes;
05012 #endif
05013 {
05014
05015 if (have_fastchunks(av)) malloc_consolidate(av);
05016 return _int_memalign(av, mp_.pagesize, bytes);
05017 }
05018
05019
05020
05021
05022
05023
05024 Void_t*
05025 #if __STD_C
05026 _int_pvalloc(mstate av, size_t bytes)
05027 #else
05028 _int_pvalloc(av, bytes) mstate av; size_t bytes;
05029 #endif
05030 {
05031 size_t pagesz;
05032
05033
05034 if (have_fastchunks(av)) malloc_consolidate(av);
05035 pagesz = mp_.pagesize;
05036 return _int_memalign(av, pagesz, (bytes + pagesz - 1) & ~(pagesz - 1));
05037 }
05038
05039
05040
05041
05042
05043
05044 #if __STD_C
05045 int mTRIm(size_t pad)
05046 #else
05047 int mTRIm(pad) size_t pad;
05048 #endif
05049 {
05050 mstate av = &main_arena;
05051
05052
05053 malloc_consolidate(av);
05054
05055 #ifndef MORECORE_CANNOT_TRIM
05056 return sYSTRIm(pad, av);
05057 #else
05058 return 0;
05059 #endif
05060 }
05061
05062
05063
05064
05065
05066
05067 #if __STD_C
05068 size_t mUSABLe(Void_t* mem)
05069 #else
05070 size_t mUSABLe(mem) Void_t* mem;
05071 #endif
05072 {
05073 mchunkptr p;
05074 if (mem != 0) {
05075 p = mem2chunk(mem);
05076 if (chunk_is_mmapped(p))
05077 return chunksize(p) - 2*SIZE_SZ;
05078 else if (inuse(p))
05079 return chunksize(p) - SIZE_SZ;
05080 }
05081 return 0;
05082 }
05083
05084
05085
05086
05087
05088 struct mallinfo mALLINFo(mstate av)
05089 {
05090 struct mallinfo mi;
05091 size_t i;
05092 mbinptr b;
05093 mchunkptr p;
05094 INTERNAL_SIZE_T avail;
05095 INTERNAL_SIZE_T fastavail;
05096 int nblocks;
05097 int nfastblocks;
05098
05099
05100 if (av->top == 0) malloc_consolidate(av);
05101
05102 check_malloc_state(av);
05103
05104
05105 avail = chunksize(av->top);
05106 nblocks = 1;
05107
05108
05109 nfastblocks = 0;
05110 fastavail = 0;
05111
05112 for (i = 0; i < NFASTBINS; ++i) {
05113 for (p = av->fastbins[i]; p != 0; p = p->fd) {
05114 ++nfastblocks;
05115 fastavail += chunksize(p);
05116 }
05117 }
05118
05119 avail += fastavail;
05120
05121
05122 for (i = 1; i < NBINS; ++i) {
05123 b = bin_at(av, i);
05124 for (p = last(b); p != b; p = p->bk) {
05125 ++nblocks;
05126 avail += chunksize(p);
05127 }
05128 }
05129
05130 mi.smblks = nfastblocks;
05131 mi.ordblks = nblocks;
05132 mi.fordblks = avail;
05133 mi.uordblks = av->system_mem - avail;
05134 mi.arena = av->system_mem;
05135 mi.hblks = mp_.n_mmaps;
05136 mi.hblkhd = mp_.mmapped_mem;
05137 mi.fsmblks = fastavail;
05138 mi.keepcost = chunksize(av->top);
05139 mi.usmblks = mp_.max_total_mem;
05140 return mi;
05141 }
05142
05143
05144
05145
05146
05147 void mSTATs()
05148 {
05149 int i;
05150 mstate ar_ptr;
05151 struct mallinfo mi;
05152 unsigned int in_use_b = mp_.mmapped_mem, system_b = in_use_b;
05153 #if THREAD_STATS
05154 long stat_lock_direct = 0, stat_lock_loop = 0, stat_lock_wait = 0;
05155 #endif
05156
05157 for (i=0, ar_ptr = &main_arena;; i++) {
05158 (void)mutex_lock(&ar_ptr->mutex);
05159 mi = mALLINFo(ar_ptr);
05160 fprintf(stderr, "Arena %d:\n", i);
05161 fprintf(stderr, "system bytes = %10u\n", (unsigned int)mi.arena);
05162 fprintf(stderr, "in use bytes = %10u\n", (unsigned int)mi.uordblks);
05163 #if MALLOC_DEBUG > 1
05164 if (i > 0)
05165 dump_heap(heap_for_ptr(top(ar_ptr)));
05166 #endif
05167 system_b += mi.arena;
05168 in_use_b += mi.uordblks;
05169 #if THREAD_STATS
05170 stat_lock_direct += ar_ptr->stat_lock_direct;
05171 stat_lock_loop += ar_ptr->stat_lock_loop;
05172 stat_lock_wait += ar_ptr->stat_lock_wait;
05173 #endif
05174 (void)mutex_unlock(&ar_ptr->mutex);
05175 ar_ptr = ar_ptr->next;
05176 if(ar_ptr == &main_arena) break;
05177 }
05178 #if HAVE_MMAP
05179 fprintf(stderr, "Total (incl. mmap):\n");
05180 #else
05181 fprintf(stderr, "Total:\n");
05182 #endif
05183 fprintf(stderr, "system bytes = %10u\n", system_b);
05184 fprintf(stderr, "in use bytes = %10u\n", in_use_b);
05185 #ifdef NO_THREADS
05186 fprintf(stderr, "max system bytes = %10u\n", (unsigned int)mp_.max_total_mem);
05187 #endif
05188 #if HAVE_MMAP
05189 fprintf(stderr, "max mmap regions = %10u\n", (unsigned int)mp_.max_n_mmaps);
05190 fprintf(stderr, "max mmap bytes = %10lu\n",
05191 (unsigned long)mp_.max_mmapped_mem);
05192 #endif
05193 #if THREAD_STATS
05194 fprintf(stderr, "heaps created = %10d\n", stat_n_heaps);
05195 fprintf(stderr, "locked directly = %10ld\n", stat_lock_direct);
05196 fprintf(stderr, "locked in loop = %10ld\n", stat_lock_loop);
05197 fprintf(stderr, "locked waiting = %10ld\n", stat_lock_wait);
05198 fprintf(stderr, "locked total = %10ld\n",
05199 stat_lock_direct + stat_lock_loop + stat_lock_wait);
05200 #endif
05201 }
05202
05203
05204
05205
05206
05207
05208 #if __STD_C
05209 int mALLOPt(int param_number, int value)
05210 #else
05211 int mALLOPt(param_number, value) int param_number; int value;
05212 #endif
05213 {
05214 if(__malloc_initialized < 0)
05215 ptmalloc_init ();
05216 {
05217 mstate av = &main_arena;
05218 int res = 1;
05219
05220 (void)mutex_lock(&av->mutex);
05221
05222 malloc_consolidate(av);
05223
05224 switch(param_number) {
05225 case M_MXFAST:
05226 if (value >= 0 && value <= MAX_FAST_SIZE) {
05227 set_max_fast(av, value);
05228 }
05229 else
05230 res = 0;
05231 break;
05232
05233 case M_TRIM_THRESHOLD:
05234 mp_.trim_threshold = value;
05235 break;
05236
05237 case M_TOP_PAD:
05238 mp_.top_pad = value;
05239 break;
05240
05241 case M_MMAP_THRESHOLD:
05242 #if USE_ARENAS
05243
05244 if((unsigned long)value > HEAP_MAX_SIZE/2)
05245 res = 0;
05246 else
05247 #endif
05248 mp_.mmap_threshold = value;
05249 break;
05250
05251 case M_MMAP_MAX:
05252 #if !HAVE_MMAP
05253 if (value != 0)
05254 res = 0;
05255 else
05256 #endif
05257 mp_.n_mmaps_max = value;
05258 break;
05259
05260 case M_CHECK_ACTION:
05261 check_action = value;
05262 break;
05263 }
05264 (void)mutex_unlock(&av->mutex);
05265 return res;
05266 }
05267 }
05268
05269
05270
05271
05272
05273
05274
05275
05276
05277
05278
05279
05280
05281
05282
05283
05284
05285
05286
05287
05288
05289
05290
05291
05292
05293
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305
05306
05307
05308
05309
05310
05311
05312
05313
05314
05315
05316
05317
05318
05319
05320
05321
05322
05323
05324
05325
05326
05327
05328
05329
05330
05331
05332
05333
05334
05335
05336
05337
05338
05339
05340
05341
05342
05343
05344
05345
05346
05347
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357
05358
05359
05360
05361
05362
05363
05364
05365
05366
05367
05368
05369
05370
05371
05372
05373
05374
05375
05376
05377
05378
05379
05380
05381
05382
05383
05384
05385
05386
05387
05388
05389
05390
05391
05392
05393
05394
05395
05396
05397
05398
05399
05400
05401
05402
05403
05404
05405
05406
05407
05408
05409 #ifdef _LIBC
05410 # include <sys/param.h>
05411
05412
05413 int
05414 __posix_memalign (void **memptr, size_t alignment, size_t size)
05415 {
05416 void *mem;
05417
05418
05419
05420 if (alignment % sizeof (void *) != 0 || !powerof2 (alignment) != 0)
05421 return EINVAL;
05422
05423 mem = __libc_memalign (alignment, size);
05424
05425 if (mem != NULL) {
05426 *memptr = mem;
05427 return 0;
05428 }
05429
05430 return ENOMEM;
05431 }
05432 weak_alias (__posix_memalign, posix_memalign)
05433
05434 weak_alias (__libc_calloc, __calloc) weak_alias (__libc_calloc, calloc)
05435 weak_alias (__libc_free, __cfree) weak_alias (__libc_free, cfree)
05436 weak_alias (__libc_free, __free) weak_alias (__libc_free, free)
05437 weak_alias (__libc_malloc, __malloc) weak_alias (__libc_malloc, malloc)
05438 weak_alias (__libc_memalign, __memalign) weak_alias (__libc_memalign, memalign)
05439 weak_alias (__libc_realloc, __realloc) weak_alias (__libc_realloc, realloc)
05440 weak_alias (__libc_valloc, __valloc) weak_alias (__libc_valloc, valloc)
05441 weak_alias (__libc_pvalloc, __pvalloc) weak_alias (__libc_pvalloc, pvalloc)
05442 weak_alias (__libc_mallinfo, __mallinfo) weak_alias (__libc_mallinfo, mallinfo)
05443 weak_alias (__libc_mallopt, __mallopt) weak_alias (__libc_mallopt, mallopt)
05444
05445 weak_alias (__malloc_stats, malloc_stats)
05446 weak_alias (__malloc_usable_size, malloc_usable_size)
05447 weak_alias (__malloc_trim, malloc_trim)
05448 weak_alias (__malloc_get_state, malloc_get_state)
05449 weak_alias (__malloc_set_state, malloc_set_state)
05450
05451 #endif
05452
05453
05454
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465 #undef malloc
05466 #undef free
05467 #undef calloc
05468 #undef cfree
05469 #undef realloc
05470 #undef memalign
05471 #undef valloc
05472