58,6 → 58,8 |
#include <debug.h> |
#include <adt/list.h> |
#include <synch/spinlock.h> |
#include <synch/mutex.h> |
#include <synch/condvar.h> |
#include <arch/asm.h> |
#include <arch.h> |
#include <print.h> |
103,6 → 105,13 |
|
static zones_t zones; |
|
/* |
* Synchronization primitives used to sleep when there is no memory |
* available. |
*/ |
mutex_t zones_mtx; |
condvar_t zones_cv; |
int new_freed_mem = false; |
|
/********************/ |
/* Helper functions */ |
991,14 → 1000,28 |
} |
if (!zone) { |
/* |
* TODO: Sleep until frames are available again. |
* Sleep until some frames are available again. |
*/ |
if (flags & FRAME_ATOMIC) { |
interrupts_restore(ipl); |
|
if (flags & FRAME_ATOMIC) |
return 0; |
} |
|
panic("Sleep not implemented.\n"); |
#ifdef CONFIG_DEBUG |
printf("Thread %" PRIu64 " falling asleep, low memory.\n", THREAD->tid); |
#endif |
|
mutex_lock(&zones_mtx); |
if (!new_freed_mem) |
condvar_wait(&zones_cv, &zones_mtx); |
new_freed_mem = false; |
mutex_unlock(&zones_mtx); |
|
#ifdef CONFIG_DEBUG |
printf("Thread %" PRIu64 " woken up, memory available.\n", THREAD->tid); |
#endif |
|
interrupts_restore(ipl); |
goto loop; |
} |
|
1038,6 → 1061,15 |
zone_frame_free(zone, pfn-zone->base); |
|
spinlock_unlock(&zone->lock); |
|
/* |
* Signal that some memory has been freed. |
*/ |
mutex_lock(&zones_mtx); |
new_freed_mem = true; |
condvar_broadcast(&zones_cv); |
mutex_unlock(&zones_mtx); |
|
interrupts_restore(ipl); |
} |
|
1116,6 → 1148,9 |
* fail in some places */ |
frame_mark_unavailable(0, 1); |
} |
|
mutex_initialize(&zones_mtx, MUTEX_ACTIVE); /* mimic spinlock */ |
condvar_initialize(&zones_cv); |
} |
|
|