Subversion Repositories HelenOS-historic

Rev

Rev 538 | Rev 541 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 538 Rev 539
Line 41... Line 41...
41
#include <align.h>
41
#include <align.h>
42
 
42
 
43
spinlock_t zone_head_lock;       /**< this lock protects zone_head list */
43
spinlock_t zone_head_lock;       /**< this lock protects zone_head list */
44
link_t zone_head;                /**< list of all zones in the system */
44
link_t zone_head;                /**< list of all zones in the system */
45
 
45
 
-
 
46
/** Blacklist containing non-available areas of memory.
-
 
47
 *
-
 
48
 * This blacklist is used to exclude frames that cannot be allocated
-
 
49
 * (e.g. kernel memory) from available memory map.
-
 
50
 */
46
region_t zone_blacklist[ZONE_BLACKLIST_SIZE];
51
region_t zone_blacklist[ZONE_BLACKLIST_SIZE];
47
count_t zone_blacklist_count = 0;
52
count_t zone_blacklist_count = 0;
48
 
53
 
49
static struct buddy_system_operations  zone_buddy_system_operations = {
54
static struct buddy_system_operations  zone_buddy_system_operations = {
50
    .find_buddy = zone_buddy_find_buddy,
55
    .find_buddy = zone_buddy_find_buddy,
Line 120... Line 125...
120
        goto loop;
125
        goto loop;
121
    }
126
    }
122
       
127
       
123
 
128
 
124
    /* Allocate frames from zone buddy system */
129
    /* Allocate frames from zone buddy system */
125
    cur = buddy_system_alloc(zone->buddy_system, order);
130
    tmp = buddy_system_alloc(zone->buddy_system, order);
-
 
131
   
-
 
132
    ASSERT(tmp);
126
   
133
   
-
 
134
    /* Update zone information. */
-
 
135
    zone->free_count -= (1 << order);
-
 
136
    zone->busy_count += (1 << order);
-
 
137
 
127
    /* frame will be actually a first frame of the block */
138
    /* Frame will be actually a first frame of the block. */
128
    frame = list_get_instance(cur, frame_t, buddy_link);
139
    frame = list_get_instance(tmp, frame_t, buddy_link);
129
   
140
   
130
    /* get frame address */
141
    /* get frame address */
131
    v = FRAME2ADDR(zone, frame);
142
    v = FRAME2ADDR(zone, frame);
132
 
143
 
133
    if (flags & FRAME_KA)
-
 
134
        v = PA2KA(v);
-
 
135
   
-
 
136
    spinlock_unlock(&zone->lock);
144
    spinlock_unlock(&zone->lock);
137
    spinlock_unlock(&zone_head_lock);
145
    spinlock_unlock(&zone_head_lock);
138
    interrupts_restore(ipl);
146
    interrupts_restore(ipl);
139
    return v;
-
 
140
 
147
 
-
 
148
 
-
 
149
    if (flags & FRAME_KA)
-
 
150
        v = PA2KA(v);
-
 
151
   
-
 
152
    return v;
141
}
153
}
142
 
154
 
143
/** Free a frame.
155
/** Free a frame.
144
 *
156
 *
145
 * Find respective frame structrue for supplied addr.
157
 * Find respective frame structrue for supplied addr.
Line 188... Line 200...
188
    ASSERT(frame->refcount);
200
    ASSERT(frame->refcount);
189
 
201
 
190
    if (!--frame->refcount) {
202
    if (!--frame->refcount) {
191
        buddy_system_free(zone->buddy_system, &frame->buddy_link);
203
        buddy_system_free(zone->buddy_system, &frame->buddy_link);
192
    }
204
    }
-
 
205
 
-
 
206
    /* Update zone information. */
-
 
207
    zone->free_count += (1 << frame->buddy_order);
-
 
208
    zone->busy_count -= (1 << frame->buddy_order);
193
   
209
   
194
    spinlock_unlock(&zone->lock);  
210
    spinlock_unlock(&zone->lock);
195
   
-
 
196
    spinlock_unlock(&zone_head_lock);
211
    spinlock_unlock(&zone_head_lock);
197
    interrupts_restore(ipl);
212
    interrupts_restore(ipl);
198
}
213
}
199
 
214
 
200
/** Mark frame region not free.
215
/** Mark frame region not free.
Line 228... Line 243...
228
{
243
{
229
    spinlock_initialize(&zone_head_lock);
244
    spinlock_initialize(&zone_head_lock);
230
    list_initialize(&zone_head);
245
    list_initialize(&zone_head);
231
}
246
}
232
 
247
 
-
 
248
/** Create frame zones in region of available memory.
-
 
249
 *
-
 
250
 * Avoid any black listed areas of non-available memory.
-
 
251
 * Assume that the black listed areas cannot overlap
-
 
252
 * one another or cross available memory region boundaries.
233
 
253
 *
-
 
254
 * @param base Base address of available memory region.
-
 
255
 * @param size Size of the region.
-
 
256
 */
234
void zone_create_in_region(__address base, size_t size) {
257
void zone_create_in_region(__address base, size_t size) {
235
    int i;
258
    int i;
236
    zone_t * z;
259
    zone_t * z;
237
    __address s;
260
    __address s;
238
    size_t sz;
261
    size_t sz;
Line 266... Line 289...
266
   
289
   
267
    zone_attach(z);
290
    zone_attach(z);
268
}
291
}
269
 
292
 
270
 
293
 
271
 
-
 
272
/** Create frame zone
294
/** Create frame zone
273
 *
295
 *
274
 * Create new frame zone.
296
 * Create new frame zone.
275
 *
297
 *
276
 * @param start Physical address of the first frame within the zone.
298
 * @param start Physical address of the first frame within the zone.
Line 371... Line 393...
371
 * @param block Block for which buddy should be found
393
 * @param block Block for which buddy should be found
372
 *
394
 *
373
 * @return Buddy for given block if found
395
 * @return Buddy for given block if found
374
 */
396
 */
375
link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * block) {
397
link_t * zone_buddy_find_buddy(buddy_system_t *b, link_t * block) {
376
    frame_t * frame, * f;
398
    frame_t * frame;
377
    zone_t * zone;
399
    zone_t * zone;
378
    link_t * cur;
-
 
379
    count_t index;
400
    count_t index;
380
    bool is_left, is_right;
401
    bool is_left, is_right;
381
 
402
 
382
    frame = list_get_instance(block, frame_t, buddy_link);
403
    frame = list_get_instance(block, frame_t, buddy_link);
383
    zone = (zone_t *) b->data;
404
    zone = (zone_t *) b->data;
384
   
405
   
385
    /*
-
 
386
     * (FRAME_INDEX % 2^(ORDER+1)) == 0 ===> LEFT BUDDY
-
 
387
     * (FRAME_INDEX % 2^(ORDER+1)) == 2^(ORDER) ===> RIGHT BUDDY
-
 
388
     */
-
 
389
 
-
 
390
    is_left = IS_BUDDY_LEFT_BLOCK(zone, frame);
406
    is_left = IS_BUDDY_LEFT_BLOCK(zone, frame);
391
    is_right = !is_left;
407
    is_right = !is_left;
392
   
408
   
393
    /*
409
    /*
394
     * test left buddy
410
     * test left buddy
Line 404... Line 420...
404
            zone->frames[index].refcount == 0) {
420
            zone->frames[index].refcount == 0) {
405
            return &zone->frames[index].buddy_link;
421
            return &zone->frames[index].buddy_link;
406
        }
422
        }
407
    }
423
    }
408
   
424
   
409
    return NULL;
425
    return NULL;   
410
   
-
 
411
}
426
}
412
 
427
 
413
/** Buddy system bisect implementation
428
/** Buddy system bisect implementation
414
 *
429
 *
415
 * @param b Buddy system.
430
 * @param b Buddy system.