Changeset 30187eb in mainline


Ignore:
Timestamp:
2005-11-12T20:30:45Z (19 years ago)
Author:
Sergey Bondari <bondari@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a4be38d
Parents:
6e8b3c8
Message:

Buddy system allocator implementation. Not checked. For review only.

Location:
generic
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • generic/include/mm/buddy.h

    r6e8b3c8 r30187eb  
    3636
    3737struct buddy_system_operations {
    38         link_t *(* find_buddy)(link_t *);               /**< Return pointer to left-side or right-side buddy for block passed as argument. */
    39         link_t *(* bisect)(link_t *);                   /**< Bisect the block passed as argument and return pointer to the new right-side buddy. */
    40         link_t *(* coalesce)(link_t *, link_t *);       /**< Coalesce to buddies into a bigger block. */
    41         void (*set_order)(link_t *, __u8);              /**< Set order of block passed as argument. */
    42         __u8 (*get_order)(link_t *);                    /**< Return order of block passed as argument. */
     38        link_t *(* find_buddy)(link_t *);                               /**< Return pointer to left-side or right-side buddy for block passed as argument. */
     39        link_t *(* bisect)(link_t *);                                   /**< Bisect the block passed as argument and return pointer to the new right-side buddy. */
     40        link_t *(* coalesce)(link_t *, link_t *);                       /**< Coalesce to buddies into a bigger block. */
     41        void (*set_order)(link_t *, __u8);                              /**< Set order of block passed as argument. */
     42        __u8 (*get_order)(link_t *);                                    /**< Return order of block passed as argument. */
    4343};
    4444
  • generic/include/mm/frame.h

    r6e8b3c8 r30187eb  
    11/*
    22 * Copyright (C) 2005 Jakub Jermar
     3 * Copyright (C) 2005 Sergey Bondari
    34 * All rights reserved.
    45 *
     
    3940#define FRAME_PANIC     2       /* panic on failure */
    4041
    41 #define FRAME2ADDR(zone, frame)         ((zone)->base + ((frame) - (zone)->frames) * FRAME_SIZE)
    42 #define ADDR2FRAME(zone, addr)          (&((zone)->frames[((addr) - (zone)->base) / FRAME_SIZE]))
     42#define FRAME2ADDR(zone, frame)                 ((zone)->base + ((frame) - (zone)->frames) * FRAME_SIZE)
     43#define ADDR2FRAME(zone, addr)                  (&((zone)->frames[((addr) - (zone)->base) / FRAME_SIZE]))
     44#define FRAME_INDEX(zone, frame)                ((count_t)((frame) - (zone)->frames))
     45#define IS_BUDDY_LEFT_BLOCK(zone, frame)        ((FRAME_INDEX((zone), (frame)) % (1 >> ((frame)->buddy_order + 1))) == 0)
     46#define IS_BUDDY_RIGHT_BLOCK(zone, frame)       ((FRAME_INDEX((zone), (frame)) % (1 >> ((frame)->buddy_order + 1))) == (1 >> (frame)->buddy_order))
     47
     48
    4349
    4450struct zone {
     
    5258        count_t busy_count;     /**< number of frame_t structures not in free list */
    5359       
    54         buddy_system_t * buddy_system; /**< buddy system allocator for the zone */
     60        buddy_system_t * buddy_system; /**< buddy system for the zone */
    5561        int flags;
    5662};
     
    5965        count_t refcount;       /**< when == 0, the frame is in free list */
    6066        link_t link;            /**< link to zone free list when refcount == 0 */
    61         __u8 order;             /**< buddy system block order */
     67        __u8 buddy_order;       /**< buddy system block order */
    6268        link_t buddy_link;      /**< link to the next free block inside one order*/
    6369};
     
    7682extern void frame_not_free(__address addr);
    7783extern void frame_region_not_free(__address start, __address stop);
     84zone_t * get_zone_by_frame(frame_t * frame);
    7885
    7986/*
  • generic/src/mm/frame.c

    r6e8b3c8 r30187eb  
    508508}
    509509
     510/** Guess zone by frame instance address
     511 *
     512 * @param frame Frame
     513 *
     514 * @return Zone of given frame
     515 */
     516zone_t * get_zone_by_frame(frame_t * frame) {
     517        link_t * cur;
     518        zone_t * zone, *z;
     519
     520        ASSERT(frame);
     521        /*
     522         * First, find host frame zone for addr.
     523         */
     524        for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
     525                z = list_get_instance(cur, zone_t, link);
     526               
     527                spinlock_lock(&z->lock);
     528               
     529                /*
     530                 * Check if frame address belongs to z.
     531                 */
     532                if ((frame >= z->frames) && (frame <= z->frames + (z->free_count + z->busy_count))) {
     533                        zone = z;
     534                        break;
     535                }
     536                spinlock_unlock(&z->lock);
     537        }
     538        ASSERT(zone);
     539       
     540        return zone;
     541
     542
     543}
    510544
    511545/** Buddy system find_buddy implementation
    512  *
    513  */
    514 link_t * zone_buddy_find_buddy(link_t * buddy) {
    515 
     546 * @param block Block for which buddy should be found
     547 *
     548 * @return Buddy for given block if found
     549 */
     550link_t * zone_buddy_find_buddy(link_t * block) {
     551        frame_t * frame, * f;
     552        zone_t * zone;
     553        link_t * cur;
     554        bool is_left, is_right;
     555
     556        frame = list_get_instance(block, frame_t, buddy_link);
     557        zone = get_zone_by_frame(frame);
     558       
     559       
     560        /*
     561         * (FRAME_INDEX % 2^(ORDER+1)) == 0 ===> LEFT BUDDY
     562         * (FRAME_INDEX % 2^(ORDER+1)) == 2^(ORDER) ===> RIGHT BUDDY
     563         */
     564         
     565        is_left = IS_BUDDY_LEFT_BLOCK(zone, frame);
     566        is_right = IS_BUDDY_RIGHT_BLOCK(zone, frame);
     567       
     568        ASSERT((is_left || is_right) && (!is_left || !is_right));
     569       
     570        for (cur = &zone->buddy_system->order[frame->buddy_order]; cur; cur = cur->next) {
     571                f = list_get_instance(cur, frame_t, buddy_link);
     572               
     573                ASSERT(f->buddy_order == frame->buddy_order);
     574               
     575                /*
     576                 * if found frame is coherent with our frame from the left
     577                 */
     578                if ((FRAME_INDEX(zone, f) + 1 >> frame->buddy_order == FRAME_INDEX(zone, frame)) && is_right) {
     579                        return cur;
     580                }
     581               
     582                /*
     583                 * if found frame is coherent with our frame from the right
     584                 */
     585                if ((FRAME_INDEX(zone,f) - 1 >> frame->buddy_order == FRAME_INDEX(zone, frame)) && is_left) {
     586                        return cur;
     587                }
     588               
     589        }
     590       
     591        return NULL;
     592       
     593       
    516594}
    517595
    518596/** Buddy system bisect implementation
    519597 *
     598 * @param block Block to bisect
     599 *
     600 * @return right block
    520601 */
    521602link_t * zone_buddy_bisect(link_t * block) {
    522 
     603        frame_t * frame_l, * frame_r;
     604        zone_t * zone;
     605       
     606        frame_l = list_get_instance(block, frame_t, buddy_link);
     607
     608        zone = get_zone_by_frame(frame_l);
     609       
     610        frame_r = &zone->frames[FRAME_INDEX(zone, frame_l) + 1>>(frame_l->buddy_order-1)];
     611
     612
     613        return &frame_r->buddy_link;
     614       
    523615}
    524616
    525617/** Buddy system coalesce implementation
    526618 *
    527  */
    528 link_t * zone_buddy_coalesce(link_t * buddy_l, link_t * buddy_r) {
     619 * @param block_1 First block
     620 * @param block_2 First block's buddy
     621 *
     622 * @return Coalesced block (actually block that represents lower address)
     623 */
     624link_t * zone_buddy_coalesce(link_t * block_1, link_t * block_2) {
     625        frame_t * frame1, * frame2;
     626        zone_t * zone;
     627       
     628        frame1 = list_get_instance(block_1, frame_t, buddy_link);
     629        frame2 = list_get_instance(block_2, frame_t, buddy_link);
     630       
     631        zone = get_zone_by_frame(frame1);
     632       
     633        return FRAME_INDEX(zone, frame1) < FRAME_INDEX(zone, frame2) ? block_1 : block_2;
    529634
    530635}
    531636
    532637/** Buddy system set_order implementation
    533  *
     638 * @param block Buddy system block
     639 * @param order Order to set
    534640 */
    535641void zone_buddy_set_order(link_t * block, __u8 order) {
    536 
     642        frame_t * frame;
     643        frame = list_get_instance(block, frame_t, buddy_link);
     644        frame->buddy_order = order;
    537645}
    538646
    539647/** Buddy system get_order implementation
    540  *
     648 * @param block Buddy system block
     649 *
     650 * @return Order of block
    541651 */
    542652__u8 zone_buddy_get_order(link_t * block) {
    543 
    544 
    545 }
     653        frame_t * frame;
     654        frame = list_get_instance(block, frame_t, buddy_link);
     655        return frame->buddy_order;
     656}
Note: See TracChangeset for help on using the changeset viewer.