package arena_test import ( "sync" "testing" "unsafe" "git.brut.systems/judah/xx/arena" "git.brut.systems/judah/xx/mem" "git.brut.systems/judah/xx/testx" ) func TestArenas_ThatShouldPanicWhenOOM(t *testing.T) { arenas := []arena.Arena{ arena.Linear(1), arena.Nil(), } for _, a := range arenas { testx.ShouldPanic(t, func() { _ = arena.New[int](a) }) } } func TestArenas_ThatShouldClearAfterReset(t *testing.T) { arenas := []arena.Arena{ arena.Linear(16), arena.Chunked(16), arena.Ring[uint16](2), } for _, a := range arenas { x := arena.New[uint16](a) y := arena.New[uint16](a) *x, *y = 100, 200 arena.Reset(a) testx.Expect(t, *x == 0, "x = %d, expected 0", *x) testx.Expect(t, *y == 0, "y = %d, expected 0", *y) } } func TestArenas_ThatShouldReuseMemoryAfterReset(t *testing.T) { arenas := []arena.Arena{ arena.Linear(16), arena.Chunked(16), arena.Ring[uint16](2), } for _, a := range arenas { x1 := arena.New[uint16](a) y1 := arena.New[uint16](a) arena.Reset(a) x2 := arena.New[uint16](a) y2 := arena.New[uint16](a) testx.Expect(t, x1 == x2, "x1 = %p, x2 = %p", x1, x2) testx.Expect(t, y1 == y2, "y1 = %p, y2 = %p", y1, y2) } } func TestArenas_WithRegion(t *testing.T) { arenas := []arena.Arena{ arena.Linear(256), arena.Chunked(256), arena.Ring[uint16](16), } var baseptrs []*uint16 for i, a := range arenas { v := arena.New[uint16](a) *v = uint16(i) baseptrs = append(baseptrs, v) } for _, a := range arenas { a := arena.Region(a) for range 10 { _ = arena.New[uint16](a) } arena.Reset(a) } for i, a := range arenas { testx.Expect(t, *baseptrs[i] == uint16(i), "baseptrs[%d] = %d, expected %d", i, *baseptrs[i], i) base := uintptr(unsafe.Pointer(baseptrs[i])) next := uintptr(unsafe.Pointer(arena.New[uint16](a))) testx.Expect(t, next-base == mem.Sizeof[uint16](), "delta was %d", next-base) } } func TestConcurrent(t *testing.T) { a := arena.Concurrent(arena.Linear(16)) base, err := a(arena.ACTION_ALLOC, 0, 1, nil) testx.Expect(t, err == nil, "ACTION_ALLOC failed: %v", err) var wg sync.WaitGroup wg.Go(func() { _ = arena.New[uint8](a) _ = arena.New[uint8](a) _ = arena.New[uint8](a) _ = arena.New[uint8](a) }) wg.Go(func() { _ = arena.New[uint16](a) _ = arena.New[uint16](a) _ = arena.New[uint16](a) _ = arena.New[uint16](a) }) wg.Wait() after, err := a(arena.ACTION_ALLOC, 0, 1, nil) testx.Expect(t, err == nil, "ACTION_ALLOC failed: %v", err) testx.Expect(t, uintptr(after)-uintptr(base) == 12, "diff is: %v", uintptr(after)-uintptr(base)) }