80 uint8_t page_type,
81 size_t page_size,
82 size_t size,
83 ZAllocationFlags flags) {
84 uintptr_t addr = 0;
85 ZPage* page = Atomic::load_acquire(shared_page);
86
87 if (page != NULL) {
88 addr = page->alloc_object_atomic(size);
89 }
90
91 if (addr == 0) {
92 // Allocate new page
93 ZPage* const new_page = alloc_page(page_type, page_size, flags);
94 if (new_page != NULL) {
95 // Allocate object before installing the new page
96 addr = new_page->alloc_object(size);
97
98 retry:
99 // Install new page
100 ZPage* const prev_page = Atomic::cmpxchg(new_page, shared_page, page);
101 if (prev_page != page) {
102 if (prev_page == NULL) {
103 // Previous page was retired, retry installing the new page
104 page = prev_page;
105 goto retry;
106 }
107
108 // Another page already installed, try allocation there first
109 const uintptr_t prev_addr = prev_page->alloc_object_atomic(size);
110 if (prev_addr == 0) {
111 // Allocation failed, retry installing the new page
112 page = prev_page;
113 goto retry;
114 }
115
116 // Allocation succeeded in already installed page
117 addr = prev_addr;
118
119 // Undo new page allocation
120 undo_alloc_page(new_page);
|
80 uint8_t page_type,
81 size_t page_size,
82 size_t size,
83 ZAllocationFlags flags) {
84 uintptr_t addr = 0;
85 ZPage* page = Atomic::load_acquire(shared_page);
86
87 if (page != NULL) {
88 addr = page->alloc_object_atomic(size);
89 }
90
91 if (addr == 0) {
92 // Allocate new page
93 ZPage* const new_page = alloc_page(page_type, page_size, flags);
94 if (new_page != NULL) {
95 // Allocate object before installing the new page
96 addr = new_page->alloc_object(size);
97
98 retry:
99 // Install new page
100 ZPage* const prev_page = Atomic::cmpxchg(shared_page, page, new_page);
101 if (prev_page != page) {
102 if (prev_page == NULL) {
103 // Previous page was retired, retry installing the new page
104 page = prev_page;
105 goto retry;
106 }
107
108 // Another page already installed, try allocation there first
109 const uintptr_t prev_addr = prev_page->alloc_object_atomic(size);
110 if (prev_addr == 0) {
111 // Allocation failed, retry installing the new page
112 page = prev_page;
113 goto retry;
114 }
115
116 // Allocation succeeded in already installed page
117 addr = prev_addr;
118
119 // Undo new page allocation
120 undo_alloc_page(new_page);
|