diff options
Diffstat (limited to 'examples/redis-unstable/deps/jemalloc/test/unit/binshard.c')
| -rw-r--r-- | examples/redis-unstable/deps/jemalloc/test/unit/binshard.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/examples/redis-unstable/deps/jemalloc/test/unit/binshard.c b/examples/redis-unstable/deps/jemalloc/test/unit/binshard.c new file mode 100644 index 0000000..040ea54 --- /dev/null +++ b/examples/redis-unstable/deps/jemalloc/test/unit/binshard.c | |||
| @@ -0,0 +1,154 @@ | |||
| 1 | #include "test/jemalloc_test.h" | ||
| 2 | |||
| 3 | /* Config -- "narenas:1,bin_shards:1-160:16|129-512:4|256-256:8" */ | ||
| 4 | |||
| 5 | #define NTHREADS 16 | ||
| 6 | #define REMOTE_NALLOC 256 | ||
| 7 | |||
| 8 | static void * | ||
| 9 | thd_producer(void *varg) { | ||
| 10 | void **mem = varg; | ||
| 11 | unsigned arena, i; | ||
| 12 | size_t sz; | ||
| 13 | |||
| 14 | sz = sizeof(arena); | ||
| 15 | /* Remote arena. */ | ||
| 16 | expect_d_eq(mallctl("arenas.create", (void *)&arena, &sz, NULL, 0), 0, | ||
| 17 | "Unexpected mallctl() failure"); | ||
| 18 | for (i = 0; i < REMOTE_NALLOC / 2; i++) { | ||
| 19 | mem[i] = mallocx(1, MALLOCX_TCACHE_NONE | MALLOCX_ARENA(arena)); | ||
| 20 | } | ||
| 21 | |||
| 22 | /* Remote bin. */ | ||
| 23 | for (; i < REMOTE_NALLOC; i++) { | ||
| 24 | mem[i] = mallocx(1, MALLOCX_TCACHE_NONE | MALLOCX_ARENA(0)); | ||
| 25 | } | ||
| 26 | |||
| 27 | return NULL; | ||
| 28 | } | ||
| 29 | |||
| 30 | TEST_BEGIN(test_producer_consumer) { | ||
| 31 | thd_t thds[NTHREADS]; | ||
| 32 | void *mem[NTHREADS][REMOTE_NALLOC]; | ||
| 33 | unsigned i; | ||
| 34 | |||
| 35 | /* Create producer threads to allocate. */ | ||
| 36 | for (i = 0; i < NTHREADS; i++) { | ||
| 37 | thd_create(&thds[i], thd_producer, mem[i]); | ||
| 38 | } | ||
| 39 | for (i = 0; i < NTHREADS; i++) { | ||
| 40 | thd_join(thds[i], NULL); | ||
| 41 | } | ||
| 42 | /* Remote deallocation by the current thread. */ | ||
| 43 | for (i = 0; i < NTHREADS; i++) { | ||
| 44 | for (unsigned j = 0; j < REMOTE_NALLOC; j++) { | ||
| 45 | expect_ptr_not_null(mem[i][j], | ||
| 46 | "Unexpected remote allocation failure"); | ||
| 47 | dallocx(mem[i][j], 0); | ||
| 48 | } | ||
| 49 | } | ||
| 50 | } | ||
| 51 | TEST_END | ||
| 52 | |||
| 53 | static void * | ||
| 54 | thd_start(void *varg) { | ||
| 55 | void *ptr, *ptr2; | ||
| 56 | edata_t *edata; | ||
| 57 | unsigned shard1, shard2; | ||
| 58 | |||
| 59 | tsdn_t *tsdn = tsdn_fetch(); | ||
| 60 | /* Try triggering allocations from sharded bins. */ | ||
| 61 | for (unsigned i = 0; i < 1024; i++) { | ||
| 62 | ptr = mallocx(1, MALLOCX_TCACHE_NONE); | ||
| 63 | ptr2 = mallocx(129, MALLOCX_TCACHE_NONE); | ||
| 64 | |||
| 65 | edata = emap_edata_lookup(tsdn, &arena_emap_global, ptr); | ||
| 66 | shard1 = edata_binshard_get(edata); | ||
| 67 | dallocx(ptr, 0); | ||
| 68 | expect_u_lt(shard1, 16, "Unexpected bin shard used"); | ||
| 69 | |||
| 70 | edata = emap_edata_lookup(tsdn, &arena_emap_global, ptr2); | ||
| 71 | shard2 = edata_binshard_get(edata); | ||
| 72 | dallocx(ptr2, 0); | ||
| 73 | expect_u_lt(shard2, 4, "Unexpected bin shard used"); | ||
| 74 | |||
| 75 | if (shard1 > 0 || shard2 > 0) { | ||
| 76 | /* Triggered sharded bin usage. */ | ||
| 77 | return (void *)(uintptr_t)shard1; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | return NULL; | ||
| 82 | } | ||
| 83 | |||
| 84 | TEST_BEGIN(test_bin_shard_mt) { | ||
| 85 | test_skip_if(have_percpu_arena && | ||
| 86 | PERCPU_ARENA_ENABLED(opt_percpu_arena)); | ||
| 87 | |||
| 88 | thd_t thds[NTHREADS]; | ||
| 89 | unsigned i; | ||
| 90 | for (i = 0; i < NTHREADS; i++) { | ||
| 91 | thd_create(&thds[i], thd_start, NULL); | ||
| 92 | } | ||
| 93 | bool sharded = false; | ||
| 94 | for (i = 0; i < NTHREADS; i++) { | ||
| 95 | void *ret; | ||
| 96 | thd_join(thds[i], &ret); | ||
| 97 | if (ret != NULL) { | ||
| 98 | sharded = true; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | expect_b_eq(sharded, true, "Did not find sharded bins"); | ||
| 102 | } | ||
| 103 | TEST_END | ||
| 104 | |||
| 105 | TEST_BEGIN(test_bin_shard) { | ||
| 106 | unsigned nbins, i; | ||
| 107 | size_t mib[4], mib2[4]; | ||
| 108 | size_t miblen, miblen2, len; | ||
| 109 | |||
| 110 | len = sizeof(nbins); | ||
| 111 | expect_d_eq(mallctl("arenas.nbins", (void *)&nbins, &len, NULL, 0), 0, | ||
| 112 | "Unexpected mallctl() failure"); | ||
| 113 | |||
| 114 | miblen = 4; | ||
| 115 | expect_d_eq(mallctlnametomib("arenas.bin.0.nshards", mib, &miblen), 0, | ||
| 116 | "Unexpected mallctlnametomib() failure"); | ||
| 117 | miblen2 = 4; | ||
| 118 | expect_d_eq(mallctlnametomib("arenas.bin.0.size", mib2, &miblen2), 0, | ||
| 119 | "Unexpected mallctlnametomib() failure"); | ||
| 120 | |||
| 121 | for (i = 0; i < nbins; i++) { | ||
| 122 | uint32_t nshards; | ||
| 123 | size_t size, sz1, sz2; | ||
| 124 | |||
| 125 | mib[2] = i; | ||
| 126 | sz1 = sizeof(nshards); | ||
| 127 | expect_d_eq(mallctlbymib(mib, miblen, (void *)&nshards, &sz1, | ||
| 128 | NULL, 0), 0, "Unexpected mallctlbymib() failure"); | ||
| 129 | |||
| 130 | mib2[2] = i; | ||
| 131 | sz2 = sizeof(size); | ||
| 132 | expect_d_eq(mallctlbymib(mib2, miblen2, (void *)&size, &sz2, | ||
| 133 | NULL, 0), 0, "Unexpected mallctlbymib() failure"); | ||
| 134 | |||
| 135 | if (size >= 1 && size <= 128) { | ||
| 136 | expect_u_eq(nshards, 16, "Unexpected nshards"); | ||
| 137 | } else if (size == 256) { | ||
| 138 | expect_u_eq(nshards, 8, "Unexpected nshards"); | ||
| 139 | } else if (size > 128 && size <= 512) { | ||
| 140 | expect_u_eq(nshards, 4, "Unexpected nshards"); | ||
| 141 | } else { | ||
| 142 | expect_u_eq(nshards, 1, "Unexpected nshards"); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | } | ||
| 146 | TEST_END | ||
| 147 | |||
| 148 | int | ||
| 149 | main(void) { | ||
| 150 | return test_no_reentrancy( | ||
| 151 | test_bin_shard, | ||
| 152 | test_bin_shard_mt, | ||
| 153 | test_producer_consumer); | ||
| 154 | } | ||
