Fix: mman behavior
This commit is contained in:
@@ -56,14 +56,14 @@ void _pull(int idx, size_t sz)
|
||||
CUR->state = PAGE_DIVIDED;
|
||||
switch (CUR->state) {
|
||||
case PAGE_FREE:
|
||||
CUR->maxsz = sz;
|
||||
CUR->size = sz;
|
||||
break;
|
||||
case PAGE_DIVIDED:
|
||||
CUR->maxsz = MAX(LCH->maxsz, RCH->maxsz);
|
||||
CUR->size = LCH->size | RCH->size;
|
||||
break;
|
||||
case PAGE_ALLOCATED:
|
||||
case PAGE_RESERVED:
|
||||
CUR->maxsz = 0;
|
||||
CUR->size = 0;
|
||||
break;
|
||||
default:
|
||||
exit(ERR_UNREACHABLE);
|
||||
@@ -85,7 +85,7 @@ void mman_init()
|
||||
|
||||
mman_frame_array[0] = (page_header_t){
|
||||
.state = PAGE_FREE,
|
||||
.maxsz = msb64(mman_page_cnt),
|
||||
.size = mman_page_cnt,
|
||||
};
|
||||
|
||||
fdt_reserve_entry_t *entry = 0x0;
|
||||
@@ -109,7 +109,7 @@ static inline
|
||||
uint64_t _allocate_page(size_t req, int idx, uint64_t l, uint64_t r)
|
||||
{
|
||||
uint64_t sz = r - l;
|
||||
if (req > sz || req > CUR->maxsz) {
|
||||
if (req > sz || req > CUR->size) {
|
||||
return MMAN_NO_PAGE;
|
||||
}
|
||||
|
||||
@@ -121,12 +121,12 @@ uint64_t _allocate_page(size_t req, int idx, uint64_t l, uint64_t r)
|
||||
LOG(l);
|
||||
DEBUG_MEM(r);
|
||||
CUR->state = PAGE_ALLOCATED;
|
||||
CUR->maxsz = 0;
|
||||
CUR->size = 0;
|
||||
return l;
|
||||
}
|
||||
LCH->state = RCH->state = PAGE_FREE;
|
||||
LCH->maxsz = msb64(m - l);
|
||||
RCH->maxsz = msb64(r - m);
|
||||
LCH->size = m - l;
|
||||
RCH->size = r - m;
|
||||
break;
|
||||
case PAGE_DIVIDED:
|
||||
break;
|
||||
@@ -138,10 +138,25 @@ uint64_t _allocate_page(size_t req, int idx, uint64_t l, uint64_t r)
|
||||
}
|
||||
|
||||
uint64_t ret = MMAN_NO_PAGE;
|
||||
if (ret == MMAN_NO_PAGE && LCH->maxsz >= req)
|
||||
|
||||
// Goto child where size >= req
|
||||
// If both children can handle, choose the one that has the least significant
|
||||
// bit that can handle.
|
||||
// It both children are the same, choose the left one
|
||||
int is_lch_valid = (LCH->size >= req);
|
||||
int is_rch_valid = (RCH->size >= req);
|
||||
if (is_lch_valid && is_rch_valid) {
|
||||
if (lsb64(LCH->size & ~(req - 1)) <= lsb64(RCH->size & ~(req - 1)))
|
||||
ret = _allocate_page(req, LIDX, l, m);
|
||||
else
|
||||
ret = _allocate_page(req, RIDX, m, r);
|
||||
}
|
||||
|
||||
if (ret == MMAN_NO_PAGE && LCH->size >= req)
|
||||
ret = _allocate_page(req, LIDX, l, m);
|
||||
if (ret == MMAN_NO_PAGE && RCH->maxsz >= req)
|
||||
if (ret == MMAN_NO_PAGE && RCH->size >= req)
|
||||
ret = _allocate_page(req, RIDX, m, r);
|
||||
|
||||
_pull(idx, sz);
|
||||
return ret;
|
||||
}
|
||||
@@ -174,7 +189,7 @@ void _free_page(uint64_t req, int idx, uint64_t l, uint64_t r)
|
||||
LOG(l);
|
||||
DEBUG_MEM(r);
|
||||
CUR->state = PAGE_FREE;
|
||||
CUR->maxsz = sz;
|
||||
CUR->size = sz;
|
||||
return;
|
||||
}
|
||||
case PAGE_DIVIDED:
|
||||
@@ -218,15 +233,15 @@ void _reserve_page(uint64_t ql, uint64_t qr, int idx, uint64_t l, uint64_t r)
|
||||
LOG(l);
|
||||
DEBUG_MEM(r);
|
||||
CUR->state = PAGE_RESERVED;
|
||||
CUR->maxsz = 0;
|
||||
CUR->size = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t m = l + ((msb64(sz) == sz) ? (sz >> 1) : msb64(sz));
|
||||
if (CUR->state == PAGE_FREE) {
|
||||
LCH->state = RCH->state = PAGE_FREE;
|
||||
LCH->maxsz = msb64(m - l);
|
||||
RCH->maxsz = msb64(r - m);
|
||||
LCH->size = m - l;
|
||||
RCH->size = r - m;
|
||||
}
|
||||
|
||||
if (ql < m)
|
||||
|
||||
Reference in New Issue
Block a user