diff --git a/dynamic.list b/dynamic.list index ee0d363b648dffcc65c3fc0c56b09d9ea2a00114..84d13c53c58ee448cccc52f9e2085bbd2462e3e0 100644 --- a/dynamic.list +++ b/dynamic.list @@ -14,6 +14,7 @@ memalign; posix_memalign; aligned_alloc; malloc_usable_size; +mallinfo; timezone; daylight; diff --git a/include/malloc.h b/include/malloc.h index 35f8b19c2c340d510c7aeaf4a5401b54acbc1d0b..98ba01000134eb592f0ef800c4ba995b51482a46 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -18,6 +18,36 @@ void *memalign(size_t, size_t); size_t malloc_usable_size(void *); +struct mallinfo { + int arena; + int ordblks; + int smblks; + int hblks; + int hblkhd; + int usmblks; + int fsmblks; + int uordblks; + int fordblks; + int keepcost; +}; + +struct mallinfo mallinfo(void); + +struct mallinfo2 { + size_t arena; + size_t ordblks; + size_t smblks; + size_t hblks; + size_t hblkhd; + size_t usmblks; + size_t fsmblks; + size_t uordblks; + size_t fordblks; + size_t keepcost; +}; + +struct mallinfo2 mallinfo2(void); + #ifdef __cplusplus } #endif diff --git a/include/sys/prctl.h b/include/sys/prctl.h index d9c846e9c2eaec7103f71b9894d76a0b0345c1e2..769229f56bc7c6d757d2dc37bca495d92adbb40e 100644 --- a/include/sys/prctl.h +++ b/include/sys/prctl.h @@ -158,6 +158,9 @@ struct prctl_mm_map { #define PR_GET_TAGGED_ADDR_CTRL 56 #define PR_TAGGED_ADDR_ENABLE (1UL << 0) +#define PR_SET_VMA 0x53564d41 +#define PR_SET_VMA_ANON_NAME 0 + int prctl (int, ...); #ifdef __cplusplus diff --git a/musl_src.gni b/musl_src.gni index e1737017cb50a01b02e50e9a4142d9b804386931..bc5d073954986671eddca9f07f16a40fb8838af4 100755 --- a/musl_src.gni +++ b/musl_src.gni @@ -449,6 +449,7 @@ musl_src_file = [ "src/malloc/lite_malloc.c", "src/malloc/malloc.c", "src/malloc/malloc_usable_size.c", + "src/malloc/mallocng/mallinfo.c", "src/malloc/memalign.c", "src/malloc/posix_memalign.c", "src/math/__cos.c", diff --git a/porting/linux/user/src/malloc/malloc.c b/porting/linux/user/src/malloc/malloc.c index 5c414bfaaafc6b6704c2e693299725373944e7d9..905a497031631310b7879316394fd651162e5d52 100755 --- a/porting/linux/user/src/malloc/malloc.c +++ b/porting/linux/user/src/malloc/malloc.c @@ -9,6 +9,7 @@ #include "atomic.h" #include "pthread_impl.h" #include "malloc_impl.h" +#include #if defined(__GNUC__) && defined(__PIC__) #define inline inline __attribute__((always_inline)) @@ -302,6 +303,10 @@ void *malloc(size_t n) char *base = __mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (base == (void *)-1) return 0; + + if(prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, base, len, "native_heap:musl")) + printf("prctl error"); + c = (void *)(base + SIZE_ALIGN - OVERHEAD); c->csize = len - (SIZE_ALIGN - OVERHEAD); c->psize = SIZE_ALIGN - OVERHEAD; diff --git a/src/malloc/expand_heap.c b/src/malloc/expand_heap.c index e6a3d7a000ebfc556d4863794ee1dd417e7f3cc8..3e296021e6ca7f68e0a2190b38e3b89c3bdf459c 100644 --- a/src/malloc/expand_heap.c +++ b/src/malloc/expand_heap.c @@ -6,6 +6,8 @@ #include "syscall.h" #include "malloc_impl.h" +#include + /* This function returns true if the interval [old,new] * intersects the 'len'-sized interval below &libc.auxv * (interpreted as the main-thread stack) or below &b @@ -65,6 +67,9 @@ void *__expand_heap(size_t *pn) void *area = __mmap(0, n, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (area == MAP_FAILED) return 0; + if(prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, area, n, "native_heap:musl")) + printf("prctl error"); + *pn = n; mmap_step++; return area; diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index 96982596b94d8c638eb716f1b0000081288e7e8c..45a8117771240a5025e688af9c3f78213cb9b8e3 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -293,6 +293,10 @@ void *malloc(size_t n) char *base = __mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (base == (void *)-1) return 0; + + if(prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, base, len, "native_heap:musl")) + printf("prctl failed"); + c = (void *)(base + SIZE_ALIGN - OVERHEAD); c->csize = len - (SIZE_ALIGN - OVERHEAD); c->psize = SIZE_ALIGN - OVERHEAD; diff --git a/src/malloc/mallocng/mallinfo.c b/src/malloc/mallocng/mallinfo.c new file mode 100644 index 0000000000000000000000000000000000000000..6e0856ae3d6f42a29477f0fa4464804f79e5621e --- /dev/null +++ b/src/malloc/mallocng/mallinfo.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#if 0 +#include "glue.h" +#include "meta.h" + +static void accumulate_meta(struct mallinfo2 *mi, struct meta *g) { + int sc = g->sizeclass; + if (sc >= 48) { + // Large mmap allocation + mi->hblks++; + mi->uordblks += g->maplen*4096; + mi->hblkhd += g->maplen*4096; + } else { + if (g->freeable && !g->maplen) { + // Small size slots are embedded in a larger slot, avoid double counting + // by subtracing the size of the larger slot from the total used memory. + struct meta* outer_g = get_meta((void*)g->mem); + int outer_sc = outer_g->sizeclass; + int outer_sz = size_classes[outer_sc]*UNIT; + mi->uordblks -= outer_sz; + } + int sz = size_classes[sc]*UNIT; + int mask = g->avail_mask | g->freed_mask; + int nr_unused = __builtin_popcount(mask); + mi->ordblks += nr_unused; + mi->uordblks += sz*(g->last_idx+1-nr_unused); + mi->fordblks += sz*nr_unused; + } +} + +static void accumulate_meta_area(struct mallinfo2 *mi, struct meta_area *ma) { + for (int i=0; inslots; i++) { + if (ma->slots[i].mem) { + accumulate_meta(mi, &ma->slots[i]); + } + } +} +#endif + +struct mallinfo2 mallinfo2() { + + struct mallinfo2 mi = {0}; + +#if 0 + rdlock(); + struct meta_area *ma = ctx.meta_area_head; + while (ma) { + accumulate_meta_area(&mi, ma); + ma = ma->next; + } + unlock(); +#endif + + return mi; +} + +#define cap(x) ((x > INT_MAX) ? INT_MAX : x) + +struct mallinfo mallinfo() { + struct mallinfo mi = {0}; + struct mallinfo2 mi2 = mallinfo2(); + + mi.arena = cap(mi2.arena); + mi.ordblks = cap(mi2.ordblks); + mi.smblks = cap(mi2.smblks); + mi.hblks = cap(mi2.hblks); + mi.hblkhd = cap(mi2.hblkhd); + mi.usmblks = cap(mi2.usmblks); + mi.fsmblks = cap(mi2.fsmblks); + mi.uordblks = cap(mi2.uordblks); + mi.fordblks = cap(mi2.fordblks); + mi.keepcost = cap(mi2.keepcost); + + return mi; +}