Subversion Repositories HelenOS-historic

Rev

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

Rev 479 Rev 480
Line 505... Line 505...
505
   
505
   
506
    spinlock_unlock(&zone_head_lock);
506
    spinlock_unlock(&zone_head_lock);
507
    interrupts_restore(ipl);
507
    interrupts_restore(ipl);
508
}
508
}
509
 
509
 
-
 
510
/** Guess zone by frame instance address
-
 
511
 *
-
 
512
 * @param frame Frame
-
 
513
 *
-
 
514
 * @return Zone of given frame
-
 
515
 */
-
 
516
zone_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
}
510
 
544
 
511
/** Buddy system find_buddy implementation
545
/** Buddy system find_buddy implementation
-
 
546
 * @param block Block for which buddy should be found
512
 *
547
 *
-
 
548
 * @return Buddy for given block if found
513
 */
549
 */
514
link_t * zone_buddy_find_buddy(link_t * buddy) {
550
link_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;
515
 
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
   
516
}
594
}
517
 
595
 
518
/** Buddy system bisect implementation
596
/** Buddy system bisect implementation
519
 *
597
 *
-
 
598
 * @param block Block to bisect
-
 
599
 *
-
 
600
 * @return right block
520
 */
601
 */
521
link_t * zone_buddy_bisect(link_t * block) {
602
link_t * zone_buddy_bisect(link_t * block) {
-
 
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)];
522
 
611
 
-
 
612
 
-
 
613
    return &frame_r->buddy_link;
-
 
614
   
523
}
615
}
524
 
616
 
525
/** Buddy system coalesce implementation
617
/** Buddy system coalesce implementation
526
 *
618
 *
-
 
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)
527
 */
623
 */
528
link_t * zone_buddy_coalesce(link_t * buddy_l, link_t * buddy_r) {
624
link_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;
529
 
634
 
530
}
635
}
531
 
636
 
532
/** Buddy system set_order implementation
637
/** Buddy system set_order implementation
-
 
638
 * @param block Buddy system block
533
 *
639
 * @param order Order to set
534
 */
640
 */
535
void zone_buddy_set_order(link_t * block, __u8 order) {
641
void 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;
537
}
645
}
538
 
646
 
539
/** Buddy system get_order implementation
647
/** Buddy system get_order implementation
-
 
648
 * @param block Buddy system block
540
 *
649
 *
-
 
650
 * @return Order of block
541
 */
651
 */
542
__u8 zone_buddy_get_order(link_t * block) {
652
__u8 zone_buddy_get_order(link_t * block) {
543
 
-
 
544
 
-
 
-
 
653
    frame_t * frame;
-
 
654
    frame = list_get_instance(block, frame_t, buddy_link);
-
 
655
    return frame->buddy_order;
545
}
656
}