| ... | ... | @@ -158,27 +158,53 @@ fn alloc(context: *anyopaque, len: usize, alignment: mem.Alignment, ra: usize) ? |
| 158 | 158 | return PageAllocator.map(len, alignment); |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | | const t = Thread.lock(); |
| 162 | | defer t.unlock(); |
| 163 | | |
| 164 | 161 | const slot_size = slotSize(class); |
| 162 | const max_search = 2; |
| 163 | var search_count: u32 = 0; |
| 165 | 164 | |
| 166 | | const top_free_ptr = t.frees[class]; |
| 167 | | if (top_free_ptr != 0) { |
| 168 | | const node: *usize = @ptrFromInt(top_free_ptr + (slot_size - @sizeOf(usize))); |
| 169 | | t.frees[class] = node.*; |
| 170 | | return @ptrFromInt(top_free_ptr); |
| 171 | | } |
| 165 | var t = Thread.lock(); |
| 172 | 166 | |
| 173 | | const next_addr = t.next_addrs[class]; |
| 174 | | if (next_addr % slab_len == 0) { |
| 175 | | const slab = PageAllocator.map(slab_len, .fromByteUnits(std.heap.pageSize())) orelse return null; |
| 176 | | t.next_addrs[class] = @intFromPtr(slab) + slot_size; |
| 177 | | return slab; |
| 178 | | } |
| 167 | outer: while (true) { |
| 168 | const top_free_ptr = t.frees[class]; |
| 169 | if (top_free_ptr != 0) { |
| 170 | @branchHint(.likely); |
| 171 | defer t.unlock(); |
| 172 | const node: *usize = @ptrFromInt(top_free_ptr + (slot_size - @sizeOf(usize))); |
| 173 | t.frees[class] = node.*; |
| 174 | return @ptrFromInt(top_free_ptr); |
| 175 | } |
| 179 | 176 | |
| 180 | | t.next_addrs[class] = next_addr + slot_size; |
| 181 | | return @ptrFromInt(next_addr); |
| 177 | const next_addr = t.next_addrs[class]; |
| 178 | if ((next_addr % slab_len) != 0) { |
| 179 | @branchHint(.likely); |
| 180 | defer t.unlock(); |
| 181 | t.next_addrs[class] = next_addr + slot_size; |
| 182 | return @ptrFromInt(next_addr); |
| 183 | } |
| 184 | |
| 185 | if (search_count >= max_search) { |
| 186 | @branchHint(.likely); |
| 187 | defer t.unlock(); |
| 188 | const slab = PageAllocator.map(slab_len, .fromByteUnits(std.heap.pageSize())) orelse return null; |
| 189 | t.next_addrs[class] = @intFromPtr(slab) + slot_size; |
| 190 | return slab; |
| 191 | } |
| 192 | |
| 193 | t.unlock(); |
| 194 | t = undefined; |
| 195 | const cpu_count = global.cpu_count; |
| 196 | assert(cpu_count != 0); |
| 197 | var index = thread_id.toIndex(); |
| 198 | while (true) { |
| 199 | index = (index + 1) % cpu_count; |
| 200 | t = &global.threads[index]; |
| 201 | if (t.mutex.tryLock()) { |
| 202 | thread_id = .fromIndex(index); |
| 203 | search_count += 1; |
| 204 | continue :outer; |
| 205 | } |
| 206 | } |
| 207 | } |
| 182 | 208 | } |
| 183 | 209 | |
| 184 | 210 | fn resize(context: *anyopaque, memory: []u8, alignment: mem.Alignment, new_len: usize, ra: usize) bool { |
| ... | ... | @@ -214,12 +240,13 @@ fn free(context: *anyopaque, memory: []u8, alignment: mem.Alignment, ra: usize) |
| 214 | 240 | return PageAllocator.unmap(@alignCast(memory)); |
| 215 | 241 | } |
| 216 | 242 | |
| 217 | | const t = Thread.lock(); |
| 218 | | defer t.unlock(); |
| 219 | | |
| 220 | 243 | const slot_size = slotSize(class); |
| 221 | 244 | const addr = @intFromPtr(memory.ptr); |
| 222 | 245 | const node: *usize = @ptrFromInt(addr + (slot_size - @sizeOf(usize))); |
| 246 | |
| 247 | const t = Thread.lock(); |
| 248 | defer t.unlock(); |
| 249 | |
| 223 | 250 | node.* = t.frees[class]; |
| 224 | 251 | t.frees[class] = addr; |
| 225 | 252 | } |