mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-04 22:54:03 +02:00
143 lines
3.1 KiB
Plaintext
143 lines
3.1 KiB
Plaintext
|
#include "kernel.hh"
|
||
|
|
||
|
void *Memory::palloc ():
|
||
|
if use >= limit:
|
||
|
return NULL
|
||
|
FreePage *ret = junk_pages
|
||
|
if !ret:
|
||
|
ret = zero_pages
|
||
|
zero_pages = ret->next
|
||
|
else:
|
||
|
junk_pages = ret->next
|
||
|
return ret
|
||
|
|
||
|
void *Memory::zalloc ():
|
||
|
if use >= limit:
|
||
|
return NULL
|
||
|
FreePage *ret = zero_pages
|
||
|
if !ret:
|
||
|
ret = junk_pages
|
||
|
for unsigned i = 1; i < PAGE_SIZE; ++i:
|
||
|
((unsigned *)ret)[i] = 0
|
||
|
junk_pages = ret->next
|
||
|
else:
|
||
|
zero_pages = ret->next
|
||
|
ret->next = NULL
|
||
|
return ret
|
||
|
|
||
|
void Memory::pfree (void *page):
|
||
|
FreePage *p = (FreePage *)page
|
||
|
p->next = junk_pages
|
||
|
junk_pages = p
|
||
|
|
||
|
void Memory::zfree (void *page):
|
||
|
FreePage *p = (FreePage *)page
|
||
|
p->next = zero_pages
|
||
|
zero_pages = p
|
||
|
|
||
|
void *Memory::search_free (unsigned size, void *&first):
|
||
|
Free *f
|
||
|
unsigned s = 0
|
||
|
for f = frees; f; f = f->next:
|
||
|
if f->next_obj:
|
||
|
s = f->next_obj - f
|
||
|
else:
|
||
|
s = PAGE_SIZE - ((unsigned)f & ~PAGE_MASK)
|
||
|
if s >= size:
|
||
|
break
|
||
|
if !f:
|
||
|
f = (Free *)palloc ()
|
||
|
if !f:
|
||
|
return NULL
|
||
|
f->marker = ~0
|
||
|
f->next = frees
|
||
|
f->prev = NULL
|
||
|
frees = f
|
||
|
if f->next:
|
||
|
f->next->prev = f
|
||
|
f->next_obj = NULL
|
||
|
f->prev_obj = NULL
|
||
|
s = PAGE_SIZE
|
||
|
// We have a free block, possibly too large.
|
||
|
if s >= size + sizeof (Free):
|
||
|
// Create the new object at the end and keep the Free.
|
||
|
Free *obj = (Free *)((unsigned)f + s - size)
|
||
|
obj->next_obj = f->next_obj
|
||
|
if (obj->next_obj)
|
||
|
obj->next_obj->prev_obj = obj
|
||
|
obj->prev_obj = f
|
||
|
f->next_obj = obj
|
||
|
f = obj
|
||
|
else:
|
||
|
if f->prev:
|
||
|
f->prev->next = f->next
|
||
|
else:
|
||
|
frees = f->next
|
||
|
if f->next:
|
||
|
f->next->prev = f->prev
|
||
|
f->next = first
|
||
|
f->prev = NULL
|
||
|
if f->next:
|
||
|
f->next->prev = f
|
||
|
first = f
|
||
|
return f
|
||
|
|
||
|
void Object_base::free_obj (Memory *parent):
|
||
|
Free *self
|
||
|
// Merge with previous, if it exists and is a Free.
|
||
|
if prev_obj && prev_obj->is_free ():
|
||
|
self = (Free *)prev_obj
|
||
|
self->next_obj = next_obj
|
||
|
if next_obj:
|
||
|
next_obj->prev_obj = self
|
||
|
else:
|
||
|
self = (Free *)this
|
||
|
self->next = parent->frees
|
||
|
self->prev = NULL
|
||
|
if self->next:
|
||
|
self->next->prev = self
|
||
|
parent->frees = self
|
||
|
self->marker = ~0
|
||
|
// Merge with next, if it exists and is a Free.
|
||
|
if self->next_obj && self->next_obj->is_free ():
|
||
|
self->next_obj = self->next_obj->next_obj
|
||
|
if self->next_obj:
|
||
|
self->next_obj->prev_obj = self
|
||
|
// Free page if the resulting object is the only thing in it.
|
||
|
if !self->prev_obj && !self->next_obj:
|
||
|
if self->next:
|
||
|
self->next->prev = self->prev
|
||
|
if self->prev:
|
||
|
self->prev->next = self->next
|
||
|
else:
|
||
|
parent->frees = self->next
|
||
|
parent->pfree (self)
|
||
|
|
||
|
Page *Memory::alloc_page ():
|
||
|
Page *ret = (Page *)search_free (sizeof (Page), pages)
|
||
|
ret->physical = zalloc ()
|
||
|
if !ret->physical:
|
||
|
ret->free (this, pages)
|
||
|
return ret
|
||
|
|
||
|
Thread *Memory::alloc_thread ():
|
||
|
Thread *ret = (Thread *)search_free (sizeof (Thread), threads)
|
||
|
ret->address_space = this
|
||
|
ret->pc = 0
|
||
|
ret->sp = 0
|
||
|
Thread_arch_init (ret)
|
||
|
ret->schedule_prev = NULL
|
||
|
ret->schedule_next = NULL
|
||
|
return ret
|
||
|
|
||
|
Memory *Memory::alloc_memory ():
|
||
|
Memory *ret = (Memory *)search_free (sizeof (Memory), memories)
|
||
|
ret->frees = NULL
|
||
|
ret->pages = NULL
|
||
|
ret->threads = NULL
|
||
|
ret->memories = NULL
|
||
|
ret->limit = ~0
|
||
|
ret->used = 0
|
||
|
Memory_arch_init (ret)
|
||
|
return ret
|