| ... | ... | @@ -6,8 +6,6 @@ |
| 6 | 6 | //! |
| 7 | 7 | //! ## Basic Design |
| 8 | 8 | //! |
| 9 | | //! Avoid locking the global mutex as much as possible. |
| 10 | | //! |
| 11 | 9 | //! Each thread gets a separate freelist, however, the data must be recoverable |
| 12 | 10 | //! when the thread exits. We do not directly learn when a thread exits, so |
| 13 | 11 | //! occasionally, one thread must attempt to reclaim another thread's |
| ... | ... | @@ -122,6 +120,7 @@ fn alloc(context: *anyopaque, len: usize, alignment: mem.Alignment, ra: usize) ? |
| 122 | 120 | } |
| 123 | 121 | |
| 124 | 122 | const slot_size = slotSize(class); |
| 123 | assert(slab_len % slot_size == 0); |
| 125 | 124 | const max_search = 1; |
| 126 | 125 | var search_count: u8 = 0; |
| 127 | 126 | |
| ... | ... | @@ -148,7 +147,8 @@ fn alloc(context: *anyopaque, len: usize, alignment: mem.Alignment, ra: usize) ? |
| 148 | 147 | if (search_count >= max_search) { |
| 149 | 148 | @branchHint(.likely); |
| 150 | 149 | defer t.unlock(); |
| 151 | | const slab = PageAllocator.map(slab_len, .fromByteUnits(std.heap.pageSize())) orelse return null; |
| 150 | // slab alignment here ensures the % slab len earlier catches the end of slots. |
| 151 | const slab = PageAllocator.map(slab_len, .fromByteUnits(slab_len)) orelse return null; |
| 152 | 152 | t.next_addrs[class] = @intFromPtr(slab) + slot_size; |
| 153 | 153 | return slab; |
| 154 | 154 | } |