Subversion Repositories HelenOS

Rev

Rev 4377 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4377 Rev 4692
Line 415... Line 415...
415
            node =
415
            node =
416
                list_get_instance(area->used_space.leaf_head.prev,
416
                list_get_instance(area->used_space.leaf_head.prev,
417
                btree_node_t, leaf_link);
417
                btree_node_t, leaf_link);
418
            if ((cond = (bool) node->keys)) {
418
            if ((cond = (bool) node->keys)) {
419
                uintptr_t b = node->key[node->keys - 1];
419
                uintptr_t b = node->key[node->keys - 1];
420
                count_t c =
420
                size_t c =
421
                    (count_t) node->value[node->keys - 1];
421
                    (size_t) node->value[node->keys - 1];
422
                unsigned int i = 0;
422
                unsigned int i = 0;
423
           
423
           
424
                if (overlaps(b, c * PAGE_SIZE, area->base,
424
                if (overlaps(b, c * PAGE_SIZE, area->base,
425
                    pages * PAGE_SIZE)) {
425
                    pages * PAGE_SIZE)) {
426
                   
426
                   
Line 552... Line 552...
552
        unsigned int i;
552
        unsigned int i;
553
       
553
       
554
        node = list_get_instance(cur, btree_node_t, leaf_link);
554
        node = list_get_instance(cur, btree_node_t, leaf_link);
555
        for (i = 0; i < node->keys; i++) {
555
        for (i = 0; i < node->keys; i++) {
556
            uintptr_t b = node->key[i];
556
            uintptr_t b = node->key[i];
557
            count_t j;
557
            size_t j;
558
            pte_t *pte;
558
            pte_t *pte;
559
           
559
           
560
            for (j = 0; j < (count_t) node->value[i]; j++) {
560
            for (j = 0; j < (size_t) node->value[i]; j++) {
561
                page_table_lock(as, false);
561
                page_table_lock(as, false);
562
                pte = page_mapping_find(as, b + j * PAGE_SIZE);
562
                pte = page_mapping_find(as, b + j * PAGE_SIZE);
563
                ASSERT(pte && PTE_VALID(pte) &&
563
                ASSERT(pte && PTE_VALID(pte) &&
564
                    PTE_PRESENT(pte));
564
                    PTE_PRESENT(pte));
565
                if (area->backend &&
565
                if (area->backend &&
Line 785... Line 785...
785
    uintptr_t base;
785
    uintptr_t base;
786
    link_t *cur;
786
    link_t *cur;
787
    ipl_t ipl;
787
    ipl_t ipl;
788
    int page_flags;
788
    int page_flags;
789
    uintptr_t *old_frame;
789
    uintptr_t *old_frame;
790
    index_t frame_idx;
790
    size_t frame_idx;
791
    count_t used_pages;
791
    size_t used_pages;
792
   
792
   
793
    /* Flags for the new memory mapping */
793
    /* Flags for the new memory mapping */
794
    page_flags = area_flags_to_page_flags(flags);
794
    page_flags = area_flags_to_page_flags(flags);
795
 
795
 
796
    ipl = interrupts_disable();
796
    ipl = interrupts_disable();
Line 824... Line 824...
824
        btree_node_t *node;
824
        btree_node_t *node;
825
        unsigned int i;
825
        unsigned int i;
826
       
826
       
827
        node = list_get_instance(cur, btree_node_t, leaf_link);
827
        node = list_get_instance(cur, btree_node_t, leaf_link);
828
        for (i = 0; i < node->keys; i++) {
828
        for (i = 0; i < node->keys; i++) {
829
            used_pages += (count_t) node->value[i];
829
            used_pages += (size_t) node->value[i];
830
        }
830
        }
831
    }
831
    }
832
 
832
 
833
    /* An array for storing frame numbers */
833
    /* An array for storing frame numbers */
834
    old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
834
    old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
Line 850... Line 850...
850
        unsigned int i;
850
        unsigned int i;
851
       
851
       
852
        node = list_get_instance(cur, btree_node_t, leaf_link);
852
        node = list_get_instance(cur, btree_node_t, leaf_link);
853
        for (i = 0; i < node->keys; i++) {
853
        for (i = 0; i < node->keys; i++) {
854
            uintptr_t b = node->key[i];
854
            uintptr_t b = node->key[i];
855
            count_t j;
855
            size_t j;
856
            pte_t *pte;
856
            pte_t *pte;
857
           
857
           
858
            for (j = 0; j < (count_t) node->value[i]; j++) {
858
            for (j = 0; j < (size_t) node->value[i]; j++) {
859
                page_table_lock(as, false);
859
                page_table_lock(as, false);
860
                pte = page_mapping_find(as, b + j * PAGE_SIZE);
860
                pte = page_mapping_find(as, b + j * PAGE_SIZE);
861
                ASSERT(pte && PTE_VALID(pte) &&
861
                ASSERT(pte && PTE_VALID(pte) &&
862
                    PTE_PRESENT(pte));
862
                    PTE_PRESENT(pte));
863
                old_frame[frame_idx++] = PTE_GET_FRAME(pte);
863
                old_frame[frame_idx++] = PTE_GET_FRAME(pte);
Line 900... Line 900...
900
        unsigned int i;
900
        unsigned int i;
901
       
901
       
902
        node = list_get_instance(cur, btree_node_t, leaf_link);
902
        node = list_get_instance(cur, btree_node_t, leaf_link);
903
        for (i = 0; i < node->keys; i++) {
903
        for (i = 0; i < node->keys; i++) {
904
            uintptr_t b = node->key[i];
904
            uintptr_t b = node->key[i];
905
            count_t j;
905
            size_t j;
906
           
906
           
907
            for (j = 0; j < (count_t) node->value[i]; j++) {
907
            for (j = 0; j < (size_t) node->value[i]; j++) {
908
                page_table_lock(as, false);
908
                page_table_lock(as, false);
909
 
909
 
910
                /* Insert the new mapping */
910
                /* Insert the new mapping */
911
                page_mapping_insert(as, b + j * PAGE_SIZE,
911
                page_mapping_insert(as, b + j * PAGE_SIZE,
912
                    old_frame[frame_idx++], page_flags);
912
                    old_frame[frame_idx++], page_flags);
Line 1394... Line 1394...
1394
 * @param page      First page to be marked.
1394
 * @param page      First page to be marked.
1395
 * @param count     Number of page to be marked.
1395
 * @param count     Number of page to be marked.
1396
 *
1396
 *
1397
 * @return      Zero on failure and non-zero on success.
1397
 * @return      Zero on failure and non-zero on success.
1398
 */
1398
 */
1399
int used_space_insert(as_area_t *a, uintptr_t page, count_t count)
1399
int used_space_insert(as_area_t *a, uintptr_t page, size_t count)
1400
{
1400
{
1401
    btree_node_t *leaf, *node;
1401
    btree_node_t *leaf, *node;
1402
    count_t pages;
1402
    size_t pages;
1403
    unsigned int i;
1403
    unsigned int i;
1404
 
1404
 
1405
    ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
1405
    ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
1406
    ASSERT(count);
1406
    ASSERT(count);
1407
 
1407
 
1408
    pages = (count_t) btree_search(&a->used_space, page, &leaf);
1408
    pages = (size_t) btree_search(&a->used_space, page, &leaf);
1409
    if (pages) {
1409
    if (pages) {
1410
        /*
1410
        /*
1411
         * We hit the beginning of some used space.
1411
         * We hit the beginning of some used space.
1412
         */
1412
         */
1413
        return 0;
1413
        return 0;
Line 1420... Line 1420...
1420
 
1420
 
1421
    node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
1421
    node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
1422
    if (node) {
1422
    if (node) {
1423
        uintptr_t left_pg = node->key[node->keys - 1];
1423
        uintptr_t left_pg = node->key[node->keys - 1];
1424
        uintptr_t right_pg = leaf->key[0];
1424
        uintptr_t right_pg = leaf->key[0];
1425
        count_t left_cnt = (count_t) node->value[node->keys - 1];
1425
        size_t left_cnt = (size_t) node->value[node->keys - 1];
1426
        count_t right_cnt = (count_t) leaf->value[0];
1426
        size_t right_cnt = (size_t) leaf->value[0];
1427
       
1427
       
1428
        /*
1428
        /*
1429
         * Examine the possibility that the interval fits
1429
         * Examine the possibility that the interval fits
1430
         * somewhere between the rightmost interval of
1430
         * somewhere between the rightmost interval of
1431
         * the left neigbour and the first interval of the leaf.
1431
         * the left neigbour and the first interval of the leaf.
Line 1475... Line 1475...
1475
                leaf);
1475
                leaf);
1476
            return 1;
1476
            return 1;
1477
        }
1477
        }
1478
    } else if (page < leaf->key[0]) {
1478
    } else if (page < leaf->key[0]) {
1479
        uintptr_t right_pg = leaf->key[0];
1479
        uintptr_t right_pg = leaf->key[0];
1480
        count_t right_cnt = (count_t) leaf->value[0];
1480
        size_t right_cnt = (size_t) leaf->value[0];
1481
   
1481
   
1482
        /*
1482
        /*
1483
         * Investigate the border case in which the left neighbour does
1483
         * Investigate the border case in which the left neighbour does
1484
         * not exist but the interval fits from the left.
1484
         * not exist but the interval fits from the left.
1485
         */
1485
         */
Line 1510... Line 1510...
1510
 
1510
 
1511
    node = btree_leaf_node_right_neighbour(&a->used_space, leaf);
1511
    node = btree_leaf_node_right_neighbour(&a->used_space, leaf);
1512
    if (node) {
1512
    if (node) {
1513
        uintptr_t left_pg = leaf->key[leaf->keys - 1];
1513
        uintptr_t left_pg = leaf->key[leaf->keys - 1];
1514
        uintptr_t right_pg = node->key[0];
1514
        uintptr_t right_pg = node->key[0];
1515
        count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
1515
        size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
1516
        count_t right_cnt = (count_t) node->value[0];
1516
        size_t right_cnt = (size_t) node->value[0];
1517
       
1517
       
1518
        /*
1518
        /*
1519
         * Examine the possibility that the interval fits
1519
         * Examine the possibility that the interval fits
1520
         * somewhere between the leftmost interval of
1520
         * somewhere between the leftmost interval of
1521
         * the right neigbour and the last interval of the leaf.
1521
         * the right neigbour and the last interval of the leaf.
Line 1565... Line 1565...
1565
                leaf);
1565
                leaf);
1566
            return 1;
1566
            return 1;
1567
        }
1567
        }
1568
    } else if (page >= leaf->key[leaf->keys - 1]) {
1568
    } else if (page >= leaf->key[leaf->keys - 1]) {
1569
        uintptr_t left_pg = leaf->key[leaf->keys - 1];
1569
        uintptr_t left_pg = leaf->key[leaf->keys - 1];
1570
        count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
1570
        size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
1571
   
1571
   
1572
        /*
1572
        /*
1573
         * Investigate the border case in which the right neighbour
1573
         * Investigate the border case in which the right neighbour
1574
         * does not exist but the interval fits from the right.
1574
         * does not exist but the interval fits from the right.
1575
         */
1575
         */
Line 1603... Line 1603...
1603
     */
1603
     */
1604
    for (i = 1; i < leaf->keys; i++) {
1604
    for (i = 1; i < leaf->keys; i++) {
1605
        if (page < leaf->key[i]) {
1605
        if (page < leaf->key[i]) {
1606
            uintptr_t left_pg = leaf->key[i - 1];
1606
            uintptr_t left_pg = leaf->key[i - 1];
1607
            uintptr_t right_pg = leaf->key[i];
1607
            uintptr_t right_pg = leaf->key[i];
1608
            count_t left_cnt = (count_t) leaf->value[i - 1];
1608
            size_t left_cnt = (size_t) leaf->value[i - 1];
1609
            count_t right_cnt = (count_t) leaf->value[i];
1609
            size_t right_cnt = (size_t) leaf->value[i];
1610
 
1610
 
1611
            /*
1611
            /*
1612
             * The interval fits between left_pg and right_pg.
1612
             * The interval fits between left_pg and right_pg.
1613
             */
1613
             */
1614
 
1614
 
Line 1662... Line 1662...
1662
                return 1;
1662
                return 1;
1663
            }
1663
            }
1664
        }
1664
        }
1665
    }
1665
    }
1666
 
1666
 
1667
    panic("Inconsistency detected while adding %" PRIc " pages of used "
1667
    panic("Inconsistency detected while adding %" PRIs " pages of used "
1668
        "space at %p.", count, page);
1668
        "space at %p.", count, page);
1669
}
1669
}
1670
 
1670
 
1671
/** Mark portion of address space area as unused.
1671
/** Mark portion of address space area as unused.
1672
 *
1672
 *
Line 1676... Line 1676...
1676
 * @param page      First page to be marked.
1676
 * @param page      First page to be marked.
1677
 * @param count     Number of page to be marked.
1677
 * @param count     Number of page to be marked.
1678
 *
1678
 *
1679
 * @return      Zero on failure and non-zero on success.
1679
 * @return      Zero on failure and non-zero on success.
1680
 */
1680
 */
1681
int used_space_remove(as_area_t *a, uintptr_t page, count_t count)
1681
int used_space_remove(as_area_t *a, uintptr_t page, size_t count)
1682
{
1682
{
1683
    btree_node_t *leaf, *node;
1683
    btree_node_t *leaf, *node;
1684
    count_t pages;
1684
    size_t pages;
1685
    unsigned int i;
1685
    unsigned int i;
1686
 
1686
 
1687
    ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
1687
    ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
1688
    ASSERT(count);
1688
    ASSERT(count);
1689
 
1689
 
1690
    pages = (count_t) btree_search(&a->used_space, page, &leaf);
1690
    pages = (size_t) btree_search(&a->used_space, page, &leaf);
1691
    if (pages) {
1691
    if (pages) {
1692
        /*
1692
        /*
1693
         * We are lucky, page is the beginning of some interval.
1693
         * We are lucky, page is the beginning of some interval.
1694
         */
1694
         */
1695
        if (count > pages) {
1695
        if (count > pages) {
Line 1714... Line 1714...
1714
    }
1714
    }
1715
 
1715
 
1716
    node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
1716
    node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
1717
    if (node && page < leaf->key[0]) {
1717
    if (node && page < leaf->key[0]) {
1718
        uintptr_t left_pg = node->key[node->keys - 1];
1718
        uintptr_t left_pg = node->key[node->keys - 1];
1719
        count_t left_cnt = (count_t) node->value[node->keys - 1];
1719
        size_t left_cnt = (size_t) node->value[node->keys - 1];
1720
 
1720
 
1721
        if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
1721
        if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
1722
            count * PAGE_SIZE)) {
1722
            count * PAGE_SIZE)) {
1723
            if (page + count * PAGE_SIZE ==
1723
            if (page + count * PAGE_SIZE ==
1724
                left_pg + left_cnt * PAGE_SIZE) {
1724
                left_pg + left_cnt * PAGE_SIZE) {
Line 1730... Line 1730...
1730
                 */
1730
                 */
1731
                node->value[node->keys - 1] -= count;
1731
                node->value[node->keys - 1] -= count;
1732
                return 1;
1732
                return 1;
1733
            } else if (page + count * PAGE_SIZE <
1733
            } else if (page + count * PAGE_SIZE <
1734
                left_pg + left_cnt*PAGE_SIZE) {
1734
                left_pg + left_cnt*PAGE_SIZE) {
1735
                count_t new_cnt;
1735
                size_t new_cnt;
1736
               
1736
               
1737
                /*
1737
                /*
1738
                 * The interval is contained in the rightmost
1738
                 * The interval is contained in the rightmost
1739
                 * interval of the left neighbour but its
1739
                 * interval of the left neighbour but its
1740
                 * removal requires both updating the size of
1740
                 * removal requires both updating the size of
Line 1754... Line 1754...
1754
        return 0;
1754
        return 0;
1755
    }
1755
    }
1756
   
1756
   
1757
    if (page > leaf->key[leaf->keys - 1]) {
1757
    if (page > leaf->key[leaf->keys - 1]) {
1758
        uintptr_t left_pg = leaf->key[leaf->keys - 1];
1758
        uintptr_t left_pg = leaf->key[leaf->keys - 1];
1759
        count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
1759
        size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
1760
 
1760
 
1761
        if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
1761
        if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
1762
            count * PAGE_SIZE)) {
1762
            count * PAGE_SIZE)) {
1763
            if (page + count * PAGE_SIZE ==
1763
            if (page + count * PAGE_SIZE ==
1764
                left_pg + left_cnt * PAGE_SIZE) {
1764
                left_pg + left_cnt * PAGE_SIZE) {
Line 1769... Line 1769...
1769
                 */
1769
                 */
1770
                leaf->value[leaf->keys - 1] -= count;
1770
                leaf->value[leaf->keys - 1] -= count;
1771
                return 1;
1771
                return 1;
1772
            } else if (page + count * PAGE_SIZE < left_pg +
1772
            } else if (page + count * PAGE_SIZE < left_pg +
1773
                left_cnt * PAGE_SIZE) {
1773
                left_cnt * PAGE_SIZE) {
1774
                count_t new_cnt;
1774
                size_t new_cnt;
1775
               
1775
               
1776
                /*
1776
                /*
1777
                 * The interval is contained in the rightmost
1777
                 * The interval is contained in the rightmost
1778
                 * interval of the leaf but its removal
1778
                 * interval of the leaf but its removal
1779
                 * requires both updating the size of the
1779
                 * requires both updating the size of the
Line 1796... Line 1796...
1796
     * Now the interval can be only between intervals of the leaf.
1796
     * Now the interval can be only between intervals of the leaf.
1797
     */
1797
     */
1798
    for (i = 1; i < leaf->keys - 1; i++) {
1798
    for (i = 1; i < leaf->keys - 1; i++) {
1799
        if (page < leaf->key[i]) {
1799
        if (page < leaf->key[i]) {
1800
            uintptr_t left_pg = leaf->key[i - 1];
1800
            uintptr_t left_pg = leaf->key[i - 1];
1801
            count_t left_cnt = (count_t) leaf->value[i - 1];
1801
            size_t left_cnt = (size_t) leaf->value[i - 1];
1802
 
1802
 
1803
            /*
1803
            /*
1804
             * Now the interval is between intervals corresponding
1804
             * Now the interval is between intervals corresponding
1805
             * to (i - 1) and i.
1805
             * to (i - 1) and i.
1806
             */
1806
             */
Line 1816... Line 1816...
1816
                     */
1816
                     */
1817
                    leaf->value[i - 1] -= count;
1817
                    leaf->value[i - 1] -= count;
1818
                    return 1;
1818
                    return 1;
1819
                } else if (page + count * PAGE_SIZE <
1819
                } else if (page + count * PAGE_SIZE <
1820
                    left_pg + left_cnt * PAGE_SIZE) {
1820
                    left_pg + left_cnt * PAGE_SIZE) {
1821
                    count_t new_cnt;
1821
                    size_t new_cnt;
1822
               
1822
               
1823
                    /*
1823
                    /*
1824
                     * The interval is contained in the
1824
                     * The interval is contained in the
1825
                     * interval (i - 1) of the leaf but its
1825
                     * interval (i - 1) of the leaf but its
1826
                     * removal requires both updating the
1826
                     * removal requires both updating the
Line 1841... Line 1841...
1841
            return 0;
1841
            return 0;
1842
        }
1842
        }
1843
    }
1843
    }
1844
 
1844
 
1845
error:
1845
error:
1846
    panic("Inconsistency detected while removing %" PRIc " pages of used "
1846
    panic("Inconsistency detected while removing %" PRIs " pages of used "
1847
        "space from %p.", count, page);
1847
        "space from %p.", count, page);
1848
}
1848
}
1849
 
1849
 
1850
/** Remove reference to address space area share info.
1850
/** Remove reference to address space area share info.
1851
 *
1851
 *
Line 1940... Line 1940...
1940
        unsigned int i;
1940
        unsigned int i;
1941
        for (i = 0; i < node->keys; i++) {
1941
        for (i = 0; i < node->keys; i++) {
1942
            as_area_t *area = node->value[i];
1942
            as_area_t *area = node->value[i];
1943
       
1943
       
1944
            mutex_lock(&area->lock);
1944
            mutex_lock(&area->lock);
1945
            printf("as_area: %p, base=%p, pages=%" PRIc
1945
            printf("as_area: %p, base=%p, pages=%" PRIs
1946
                " (%p - %p)\n", area, area->base, area->pages,
1946
                " (%p - %p)\n", area, area->base, area->pages,
1947
                area->base, area->base + FRAMES2SIZE(area->pages));
1947
                area->base, area->base + FRAMES2SIZE(area->pages));
1948
            mutex_unlock(&area->lock);
1948
            mutex_unlock(&area->lock);
1949
        }
1949
        }
1950
    }
1950
    }