1 // Copyright (c) 2016 Couchbase, Inc.
2 // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3 // except in compliance with the License. You may obtain a copy of the License at
4 //   http://www.apache.org/licenses/LICENSE-2.0
5 // Unless required by applicable law or agreed to in writing, software distributed under the
6 // License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
7 // either express or implied. See the License for the specific language governing permissions
8 // and limitations under the License.
9 #include "malloc.h"
10 #include <stdio.h>
11 #include <string.h>
12 
13 #ifdef JEMALLOC
14 #include <jemalloc/jemalloc.h>
15 
16 const char *je_malloc_conf = "narenas:2,lg_dirty_mult:5";
17 
writecb(void *ref, const char *s)18 void writecb(void *ref, const char *s) {
19 	stats_buf *buf = (stats_buf *)(ref);
20 	int len;
21 	len = strlen(s);
22 	if (buf->offset + len >= buf->size) {
23 		buf->size *=2;
24 		buf->buf = realloc(buf->buf, buf->size);
25 	}
26 	strncpy(buf->buf + buf->offset, s, len);
27 	buf->offset += len;
28 }
29 
30 
doStatsnull31 char *doStats()  {
32 	stats_buf buf;
33 	buf.size = 1024;
34 	buf.buf = malloc(buf.size);
35 	buf.offset = 0;
36 	je_malloc_stats_print(writecb, &buf, NULL);
37 	buf.buf[buf.offset] = 0;
38 	return buf.buf;
39 }
40 
41 #endif
42 
mm_malloc(size_t sz)43 void *mm_malloc(size_t sz) {
44 #ifdef JEMALLOC
45     return je_malloc(sz);
46 #else
47     return malloc(sz);
48 #endif
49 }
50 
mm_free(void *p)51 void mm_free(void *p) {
52 #ifdef JEMALLOC
53     return je_free(p);
54 #else
55     return free(p);
56 #endif
57 }
58 
mm_statsnull59 char *mm_stats() {
60 #ifdef JEMALLOC
61     return doStats();
62 #else
63     return NULL;
64 #endif
65 }
66 
mm_sizeat(void *p)67 size_t mm_sizeat(void *p) {
68 #ifdef JEMALLOC
69     return je_sallocx(p, 0);
70 #else
71     return 0;
72 #endif
73 }
74 
mm_sizenull75 size_t mm_size() {
76     size_t resident, sz;
77     sz = sizeof(size_t);
78 #ifdef JEMALLOC
79     // Force stats cache flush
80     uint64_t epoch = 1;
81     sz = sizeof(epoch);
82     je_mallctl("epoch", &epoch, &sz, &epoch, sz);
83 
84     je_mallctl("stats.resident", &resident, &sz, NULL, 0);
85     return resident;
86 #else
87     return 0;
88 #endif
89 }
90 
mm_free2osnull91 int mm_free2os() {
92 #ifdef JEMALLOC
93 	char buf[100];
94 	unsigned int narenas;
95 	size_t len = sizeof(narenas);
96 	je_mallctl("arenas.narenas", &narenas, &len, NULL, 0);
97 	sprintf(buf, "arena.%u.purge", narenas);
98 	return je_mallctl(buf, NULL, NULL, NULL, 0);
99 #endif
100 	return 0;
101 }
102