| 101 | } |
| 102 | |
| 103 | void |
| 104 | tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, cache_bin_t *tbin, |
| 105 | szind_t binind, unsigned rem) { |
| 106 | bool merged_stats = false; |
| 107 | |
| 108 | assert(binind < NBINS); |
| 109 | assert((cache_bin_sz_t)rem <= tbin->ncached); |
| 110 | |
| 111 | arena_t *arena = tcache->arena; |
| 112 | assert(arena != NULL); |
| 113 | unsigned nflush = tbin->ncached - rem; |
| 114 | VARIABLE_ARRAY(extent_t *, item_extent, nflush); |
| 115 | /* Look up extent once per item. */ |
| 116 | for (unsigned i = 0 ; i < nflush; i++) { |
| 117 | item_extent[i] = iealloc(tsd_tsdn(tsd), *(tbin->avail - 1 - i)); |
| 118 | } |
| 119 | |
| 120 | while (nflush > 0) { |
| 121 | /* Lock the arena bin associated with the first object. */ |
| 122 | extent_t *extent = item_extent[0]; |
| 123 | arena_t *bin_arena = extent_arena_get(extent); |
| 124 | bin_t *bin = &bin_arena->bins[binind]; |
| 125 | |
| 126 | if (config_prof && bin_arena == arena) { |
| 127 | if (arena_prof_accum(tsd_tsdn(tsd), arena, |
| 128 | tcache->prof_accumbytes)) { |
| 129 | prof_idump(tsd_tsdn(tsd)); |
| 130 | } |
| 131 | tcache->prof_accumbytes = 0; |
| 132 | } |
| 133 | |
| 134 | malloc_mutex_lock(tsd_tsdn(tsd), &bin->lock); |
| 135 | if (config_stats && bin_arena == arena) { |
| 136 | assert(!merged_stats); |
| 137 | merged_stats = true; |
| 138 | bin->stats.nflushes++; |
| 139 | bin->stats.nrequests += tbin->tstats.nrequests; |
| 140 | tbin->tstats.nrequests = 0; |
| 141 | } |
| 142 | unsigned ndeferred = 0; |
| 143 | for (unsigned i = 0; i < nflush; i++) { |
| 144 | void *ptr = *(tbin->avail - 1 - i); |
| 145 | extent = item_extent[i]; |
| 146 | assert(ptr != NULL && extent != NULL); |
| 147 | |
| 148 | if (extent_arena_get(extent) == bin_arena) { |
| 149 | arena_dalloc_bin_junked_locked(tsd_tsdn(tsd), |
| 150 | bin_arena, extent, ptr); |
| 151 | } else { |
| 152 | /* |
| 153 | * This object was allocated via a different |
| 154 | * arena bin than the one that is currently |
| 155 | * locked. Stash the object, so that it can be |
| 156 | * handled in a future pass. |
| 157 | */ |
| 158 | *(tbin->avail - 1 - ndeferred) = ptr; |
| 159 | item_extent[ndeferred] = extent; |
| 160 | ndeferred++; |
no test coverage detected