]> git.saurik.com Git - redis.git/blame - deps/jemalloc/src/chunk_dss.c
Redis 2.6.5
[redis.git] / deps / jemalloc / src / chunk_dss.c
CommitLineData
a78e148b 1#define JEMALLOC_CHUNK_DSS_C_
2#include "jemalloc/internal/jemalloc_internal.h"
a78e148b 3/******************************************************************************/
4/* Data. */
5
4934f93d 6/*
7 * Protects sbrk() calls. This avoids malloc races among threads, though it
8 * does not protect against races with threads that call sbrk() directly.
9 */
10static malloc_mutex_t dss_mtx;
a78e148b 11
12/* Base address of the DSS. */
4934f93d 13static void *dss_base;
a78e148b 14/* Current end of the DSS, or ((void *)-1) if the DSS is exhausted. */
4934f93d 15static void *dss_prev;
a78e148b 16/* Current upper limit on DSS addresses. */
4934f93d 17static void *dss_max;
a78e148b 18
19/******************************************************************************/
20
4934f93d 21#ifndef JEMALLOC_HAVE_SBRK
a78e148b 22static void *
4934f93d 23sbrk(intptr_t increment)
a78e148b 24{
a78e148b 25
4934f93d 26 not_implemented();
a78e148b 27
28 return (NULL);
29}
4934f93d 30#endif
a78e148b 31
32void *
4934f93d 33chunk_alloc_dss(size_t size, size_t alignment, bool *zero)
a78e148b 34{
35 void *ret;
36
4934f93d 37 cassert(config_dss);
38 assert(size > 0 && (size & chunksize_mask) == 0);
39 assert(alignment > 0 && (alignment & chunksize_mask) == 0);
a78e148b 40
41 /*
42 * sbrk() uses a signed increment argument, so take care not to
43 * interpret a huge allocation request as a negative increment.
44 */
45 if ((intptr_t)size < 0)
46 return (NULL);
47
48 malloc_mutex_lock(&dss_mtx);
49 if (dss_prev != (void *)-1) {
4934f93d 50 size_t gap_size, cpad_size;
51 void *cpad, *dss_next;
a78e148b 52 intptr_t incr;
53
54 /*
55 * The loop is necessary to recover from races with other
56 * threads that are using the DSS for something other than
57 * malloc.
58 */
59 do {
60 /* Get the current end of the DSS. */
61 dss_max = sbrk(0);
a78e148b 62 /*
63 * Calculate how much padding is necessary to
64 * chunk-align the end of the DSS.
65 */
4934f93d 66 gap_size = (chunksize - CHUNK_ADDR2OFFSET(dss_max)) &
67 chunksize_mask;
68 /*
69 * Compute how much chunk-aligned pad space (if any) is
70 * necessary to satisfy alignment. This space can be
71 * recycled for later use.
72 */
73 cpad = (void *)((uintptr_t)dss_max + gap_size);
74 ret = (void *)ALIGNMENT_CEILING((uintptr_t)dss_max,
75 alignment);
76 cpad_size = (uintptr_t)ret - (uintptr_t)cpad;
77 dss_next = (void *)((uintptr_t)ret + size);
78 if ((uintptr_t)ret < (uintptr_t)dss_max ||
79 (uintptr_t)dss_next < (uintptr_t)dss_max) {
80 /* Wrap-around. */
81 malloc_mutex_unlock(&dss_mtx);
82 return (NULL);
a78e148b 83 }
4934f93d 84 incr = gap_size + cpad_size + size;
a78e148b 85 dss_prev = sbrk(incr);
86 if (dss_prev == dss_max) {
87 /* Success. */
4934f93d 88 dss_max = dss_next;
a78e148b 89 malloc_mutex_unlock(&dss_mtx);
4934f93d 90 if (cpad_size != 0)
91 chunk_dealloc(cpad, cpad_size, true);
92 if (*zero) {
93 VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
94 memset(ret, 0, size);
95 }
a78e148b 96 return (ret);
97 }
98 } while (dss_prev != (void *)-1);
99 }
100 malloc_mutex_unlock(&dss_mtx);
101
102 return (NULL);
103}
104
a78e148b 105bool
106chunk_in_dss(void *chunk)
107{
108 bool ret;
109
4934f93d 110 cassert(config_dss);
111
a78e148b 112 malloc_mutex_lock(&dss_mtx);
113 if ((uintptr_t)chunk >= (uintptr_t)dss_base
114 && (uintptr_t)chunk < (uintptr_t)dss_max)
115 ret = true;
116 else
117 ret = false;
118 malloc_mutex_unlock(&dss_mtx);
119
120 return (ret);
121}
122
123bool
4934f93d 124chunk_dss_boot(void)
a78e148b 125{
a78e148b 126
4934f93d 127 cassert(config_dss);
a78e148b 128
4934f93d 129 if (malloc_mutex_init(&dss_mtx))
130 return (true);
131 dss_base = sbrk(0);
132 dss_prev = dss_base;
133 dss_max = dss_base;
a78e148b 134
4934f93d 135 return (false);
136}
a78e148b 137
4934f93d 138void
139chunk_dss_prefork(void)
140{
a78e148b 141
4934f93d 142 if (config_dss)
143 malloc_mutex_prefork(&dss_mtx);
144}
a78e148b 145
4934f93d 146void
147chunk_dss_postfork_parent(void)
148{
a78e148b 149
4934f93d 150 if (config_dss)
151 malloc_mutex_postfork_parent(&dss_mtx);
a78e148b 152}
153
4934f93d 154void
155chunk_dss_postfork_child(void)
a78e148b 156{
157
4934f93d 158 if (config_dss)
159 malloc_mutex_postfork_child(&dss_mtx);
a78e148b 160}
161
162/******************************************************************************/