Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3187 → Rev 3188

/trunk/kernel/generic/src/mm/frame.c
109,9 → 109,10
* Synchronization primitives used to sleep when there is no memory
* available.
*/
mutex_t zones_mtx;
condvar_t zones_cv;
int new_freed_mem = false;
mutex_t mem_avail_mtx;
condvar_t mem_avail_cv;
unsigned long mem_avail_frames = 0; /**< Number of available frames. */
unsigned long mem_avail_gen = 0; /**< Generation counter. */
 
/********************/
/* Helper functions */
140,7 → 141,7
 
/** Initialize frame structure.
*
* @param framei Frame structure to be initialized.
* @param frame Frame structure to be initialized.
*/
static void frame_initialize(frame_t *frame)
{
539,7 → 540,7
}
 
/** Return frame from zone. */
static frame_t * zone_get_frame(zone_t *zone, index_t frame_idx)
static frame_t *zone_get_frame(zone_t *zone, index_t frame_idx)
{
ASSERT(frame_idx < zone->count);
return &zone->frames[frame_idx];
558,6 → 559,10
&frame->buddy_link);
ASSERT(link);
zone->free_count--;
 
mutex_lock(&mem_avail_mtx);
mem_avail_frames--;
mutex_unlock(&mem_avail_mtx);
}
 
/** Join two zones.
735,7 → 740,7
if ((z1 >= zones.count) || (z2 >= zones.count))
goto errout;
/* We can join only 2 zones with none existing inbetween */
if (z2-z1 != 1)
if (z2 - z1 != 1)
goto errout;
 
zone1 = zones.info[z1];
796,7 → 801,7
int count = zones.count;
 
while (zones.count > 1 && --count) {
zone_merge(0,1);
zone_merge(0, 1);
break;
}
}
893,8 → 898,8
* it does not span kernel & init
*/
confcount = SIZE2FRAMES(zone_conf_size(count));
if (confframe >= start && confframe < start+count) {
for (;confframe < start + count; confframe++) {
if (confframe >= start && confframe < start + count) {
for (; confframe < start + count; confframe++) {
addr = PFN2ADDR(confframe);
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(config.base), config.kernel_size))
928,11 → 933,16
if (znum == -1)
return -1;
 
mutex_lock(&mem_avail_mtx);
mem_avail_frames += count;
mutex_unlock(&mem_avail_mtx);
 
/* If confdata in zone, mark as unavailable */
if (confframe >= start && confframe < start + count)
for (i = confframe; i < confframe + confcount; i++) {
zone_mark_unavailable(z, i - z->base);
}
return znum;
}
 
946,7 → 956,7
 
ASSERT(zone);
 
zone_get_frame(zone, pfn-zone->base)->parent = data;
zone_get_frame(zone, pfn - zone->base)->parent = data;
spinlock_unlock(&zone->lock);
}
 
977,6 → 987,7
int freed;
pfn_t v;
zone_t *zone;
unsigned long gen = 0;
loop:
ipl = interrupts_disable();
1008,17 → 1019,30
}
#ifdef CONFIG_DEBUG
printf("Thread %" PRIu64 " falling asleep, low memory.\n", THREAD->tid);
unsigned long avail;
 
mutex_lock(&mem_avail_mtx);
avail = mem_avail_frames;
mutex_unlock(&mem_avail_mtx);
 
printf("Thread %" PRIu64 " waiting for %u frames, "
"%u available.\n", THREAD->tid, 1ULL << order, avail);
#endif
 
mutex_lock(&zones_mtx);
if (!new_freed_mem)
condvar_wait(&zones_cv, &zones_mtx);
new_freed_mem = false;
mutex_unlock(&zones_mtx);
mutex_lock(&mem_avail_mtx);
while ((mem_avail_frames < (1ULL << order)) ||
gen == mem_avail_gen)
condvar_wait(&mem_avail_cv, &mem_avail_mtx);
gen = mem_avail_gen;
mutex_unlock(&mem_avail_mtx);
 
#ifdef CONFIG_DEBUG
printf("Thread %" PRIu64 " woken up, memory available.\n", THREAD->tid);
mutex_lock(&mem_avail_mtx);
avail = mem_avail_frames;
mutex_unlock(&mem_avail_mtx);
 
printf("Thread %" PRIu64 " woken up, %u frames available.\n",
THREAD->tid, avail);
#endif
 
interrupts_restore(ipl);
1029,6 → 1053,11
v += zone->base;
 
spinlock_unlock(&zone->lock);
mutex_lock(&mem_avail_mtx);
mem_avail_frames -= (1ULL << order);
mutex_unlock(&mem_avail_mtx);
 
interrupts_restore(ipl);
 
if (flags & FRAME_KA)
1065,10 → 1094,11
/*
* Signal that some memory has been freed.
*/
mutex_lock(&zones_mtx);
new_freed_mem = true;
condvar_broadcast(&zones_cv);
mutex_unlock(&zones_mtx);
mutex_lock(&mem_avail_mtx);
mem_avail_frames++;
mem_avail_gen++;
condvar_broadcast(&mem_avail_cv);
mutex_unlock(&mem_avail_mtx);
 
interrupts_restore(ipl);
}
1124,6 → 1154,8
if (config.cpu_active == 1) {
zones.count = 0;
spinlock_initialize(&zones.lock, "zones.lock");
mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE);
condvar_initialize(&mem_avail_cv);
}
/* Tell the architecture to create some memory */
frame_arch_init();
1148,9 → 1180,6
* fail in some places */
frame_mark_unavailable(0, 1);
}
 
mutex_initialize(&zones_mtx, MUTEX_ACTIVE); /* mimic spinlock */
condvar_initialize(&zones_cv);
}