Subversion Repositories HelenOS

Rev

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

Rev 3206 Rev 3207
Line 198... Line 198...
198
    interrupts_restore(ipl);
198
    interrupts_restore(ipl);
199
 
199
 
200
    return i;
200
    return i;
201
}
201
}
202
 
202
 
203
/**
-
 
204
 * Try to find a zone where can we find the frame.
203
/** Try to find a zone where can we find the frame.
205
 *
204
 *
206
 * Assume interrupts are disabled.
205
 * Assume interrupts are disabled.
207
 *
206
 *
208
 * @param frame     Frame number contained in zone.
207
 * @param frame     Frame number contained in zone.
209
 * @param pzone     If not null, it is used as zone hint. Zone index is
208
 * @param pzone     If not null, it is used as zone hint. Zone index is
Line 235... Line 234...
235
        spinlock_unlock(&z->lock);
234
        spinlock_unlock(&z->lock);
236
 
235
 
237
        i++;
236
        i++;
238
        if (i >= zones.count)
237
        if (i >= zones.count)
239
            i = 0;
238
            i = 0;
240
    } while(i != hint);
239
    } while (i != hint);
241
 
240
 
242
    spinlock_unlock(&zones.lock);
241
    spinlock_unlock(&zones.lock);
243
    return NULL;
242
    return NULL;
244
}
243
}
245
 
244
 
Line 252... Line 251...
252
/** Find and lock zone that can allocate order frames.
251
/** Find and lock zone that can allocate order frames.
253
 *
252
 *
254
 * Assume interrupts are disabled.
253
 * Assume interrupts are disabled.
255
 *
254
 *
256
 * @param order     Size (2^order) of free space we are trying to find.
255
 * @param order     Size (2^order) of free space we are trying to find.
-
 
256
 * @param flags     Required flags of the target zone.
257
 * @param pzone     Pointer to preferred zone or NULL, on return contains
257
 * @param pzone     Pointer to preferred zone or NULL, on return contains
258
 *          zone number.
258
 *          zone number.
259
 */
259
 */
-
 
260
static zone_t *
260
static zone_t *find_free_zone_and_lock(uint8_t order, unsigned int *pzone)
261
find_free_zone_and_lock(uint8_t order, int flags, unsigned int *pzone)
261
{
262
{
262
    unsigned int i;
263
    unsigned int i;
263
    zone_t *z;
264
    zone_t *z;
264
    unsigned int hint = pzone ? *pzone : 0;
265
    unsigned int hint = pzone ? *pzone : 0;
265
   
266
   
-
 
267
    /* Mask off flags that are not applicable. */
-
 
268
    flags &= FRAME_LOW_16_GiB;
-
 
269
 
266
    spinlock_lock(&zones.lock);
270
    spinlock_lock(&zones.lock);
267
    if (hint >= zones.count)
271
    if (hint >= zones.count)
268
        hint = 0;
272
        hint = 0;
269
    i = hint;
273
    i = hint;
270
    do {
274
    do {
271
        z = zones.info[i];
275
        z = zones.info[i];
272
       
276
       
273
        spinlock_lock(&z->lock);
277
        spinlock_lock(&z->lock);
274
 
278
 
-
 
279
        /*
-
 
280
         * Check whether the zone meets the search criteria.
-
 
281
         */
-
 
282
        if ((z->flags & flags) == flags) {
-
 
283
            /*
275
        /* Check if the zone has 2^order frames area available  */
284
             * Check if the zone has 2^order frames area available.
-
 
285
             */
276
        if (zone_can_alloc(z, order)) {
286
            if (zone_can_alloc(z, order)) {
277
            spinlock_unlock(&zones.lock);
287
                spinlock_unlock(&zones.lock);
278
            if (pzone)
288
                if (pzone)
279
                *pzone = i;
289
                    *pzone = i;
280
            return z;
290
                return z;
-
 
291
            }
281
        }
292
        }
282
        spinlock_unlock(&z->lock);
293
        spinlock_unlock(&z->lock);
283
        if (++i >= zones.count)
294
        if (++i >= zones.count)
284
            i = 0;
295
            i = 0;
285
    } while(i != hint);
296
    } while (i != hint);
286
    spinlock_unlock(&zones.lock);
297
    spinlock_unlock(&zones.lock);
287
    return NULL;
298
    return NULL;
288
}
299
}
289
 
300
 
290
/**************************/
301
/**************************/
Line 808... Line 819...
808
    uint8_t max_order;
819
    uint8_t max_order;
809
 
820
 
810
    spinlock_initialize(&z->lock, "zone_lock");
821
    spinlock_initialize(&z->lock, "zone_lock");
811
    z->base = start;
822
    z->base = start;
812
    z->count = count;
823
    z->count = count;
-
 
824
 
-
 
825
    /* Mask off flags that are calculated automatically. */
-
 
826
    flags &= ~FRAME_LOW_16_GiB;
-
 
827
    /* Determine calculated flags. */
-
 
828
    if (z->base + count < (1ULL << (34 - FRAME_WIDTH))) /* 16 GiB */
-
 
829
        flags |= FRAME_LOW_16_GiB;
-
 
830
 
813
    z->flags = flags;
831
    z->flags = flags;
-
 
832
 
814
    z->free_count = count;
833
    z->free_count = count;
815
    z->busy_count = 0;
834
    z->busy_count = 0;
816
 
835
 
817
    /*
836
    /*
818
     * Compute order for buddy system, initialize
837
     * Compute order for buddy system, initialize
Line 980... Line 999...
980
    ipl = interrupts_disable();
999
    ipl = interrupts_disable();
981
   
1000
   
982
    /*
1001
    /*
983
     * First, find suitable frame zone.
1002
     * First, find suitable frame zone.
984
     */
1003
     */
985
    zone = find_free_zone_and_lock(order, pzone);
1004
    zone = find_free_zone_and_lock(order, flags, pzone);
986
   
1005
   
987
    /* If no memory, reclaim some slab memory,
1006
    /* If no memory, reclaim some slab memory,
988
       if it does not help, reclaim all */
1007
       if it does not help, reclaim all */
989
    if (!zone && !(flags & FRAME_NO_RECLAIM)) {
1008
    if (!zone && !(flags & FRAME_NO_RECLAIM)) {
990
        freed = slab_reclaim(0);
1009
        freed = slab_reclaim(0);
991
        if (freed)
1010
        if (freed)
992
            zone = find_free_zone_and_lock(order, pzone);
1011
            zone = find_free_zone_and_lock(order, flags, pzone);
993
        if (!zone) {
1012
        if (!zone) {
994
            freed = slab_reclaim(SLAB_RECLAIM_ALL);
1013
            freed = slab_reclaim(SLAB_RECLAIM_ALL);
995
            if (freed)
1014
            if (freed)
996
                zone = find_free_zone_and_lock(order, pzone);
1015
                zone = find_free_zone_and_lock(order, flags,
-
 
1016
                    pzone);
997
        }
1017
        }
998
    }
1018
    }
999
    if (!zone) {
1019
    if (!zone) {
1000
        /*
1020
        /*
1001
         * Sleep until some frames are available again.
1021
         * Sleep until some frames are available again.