Subversion Repositories HelenOS-historic

Rev

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

Rev 1483 Rev 1495
Line 134... Line 134...
134
 * the address space can be destroyed.
134
 * the address space can be destroyed.
135
 */
135
 */
136
void as_destroy(as_t *as)
136
void as_destroy(as_t *as)
137
{
137
{
138
    ipl_t ipl;
138
    ipl_t ipl;
139
    bool cond;
139
    link_t *cur;
140
 
140
 
141
    ASSERT(as->refcount == 0);
141
    ASSERT(as->refcount == 0);
142
   
142
   
143
    /*
143
    /*
144
     * Since there is no reference to this area,
144
     * Since there is no reference to this area,
Line 154... Line 154...
154
    spinlock_unlock(&inactive_as_with_asid_lock);
154
    spinlock_unlock(&inactive_as_with_asid_lock);
155
 
155
 
156
    /*
156
    /*
157
     * Destroy address space areas of the address space.
157
     * Destroy address space areas of the address space.
158
     */
158
     */
159
    for (cond = true; cond; ) {
159
    for (cur = as->as_area_btree.leaf_head.next; cur != &as->as_area_btree.leaf_head; cur = cur->next) {
160
        btree_node_t *node;
160
        btree_node_t *node;
-
 
161
        int i;
161
       
162
       
162
        ASSERT(!list_empty(&as->as_area_btree.leaf_head));
-
 
163
        node = list_get_instance(&as->as_area_btree.leaf_head.next, btree_node_t, leaf_link);
163
        node = list_get_instance(cur, btree_node_t, leaf_link);
164
        if ((cond = node->keys))
164
        for (i = 0; i < node->keys; i++)
165
            as_area_destroy(as, node->key[0]);
165
            as_area_destroy(as, node->key[i]);
166
    }
166
    }
167
   
167
 
168
    btree_destroy(&as->as_area_btree);
168
    btree_destroy(&as->as_area_btree);
169
    page_table_destroy(as->page_table);
169
    page_table_destroy(as->page_table);
170
 
170
 
171
    interrupts_restore(ipl);
171
    interrupts_restore(ipl);
172
   
172
   
Line 408... Line 408...
408
 */
408
 */
409
int as_area_destroy(as_t *as, __address address)
409
int as_area_destroy(as_t *as, __address address)
410
{
410
{
411
    as_area_t *area;
411
    as_area_t *area;
412
    __address base;
412
    __address base;
-
 
413
    link_t *cur;
413
    ipl_t ipl;
414
    ipl_t ipl;
414
    bool cond;
-
 
415
 
415
 
416
    ipl = interrupts_disable();
416
    ipl = interrupts_disable();
417
    mutex_lock(&as->lock);
417
    mutex_lock(&as->lock);
418
 
418
 
419
    area = find_area_and_lock(as, address);
419
    area = find_area_and_lock(as, address);
Line 430... Line 430...
430
     */
430
     */
431
    tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base, area->pages);
431
    tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base, area->pages);
432
 
432
 
433
    /*
433
    /*
434
     * Visit only the pages mapped by used_space B+tree.
434
     * Visit only the pages mapped by used_space B+tree.
435
     * Note that we must be very careful when walking the tree
-
 
436
     * leaf list and removing used space as the leaf list changes
-
 
437
     * unpredictibly after each remove. The solution is to actually
-
 
438
     * not walk the tree at all, but to remove items from the head
-
 
439
     * of the leaf list until there are some keys left.
-
 
440
     */
435
     */
441
    for (cond = true; cond;) {
436
    for (cur = area->used_space.leaf_head.next; cur != &area->used_space.leaf_head; cur = cur->next) {
442
        btree_node_t *node;
437
        btree_node_t *node;
-
 
438
        int i;
443
       
439
       
444
        ASSERT(!list_empty(&area->used_space.leaf_head));
-
 
445
        node = list_get_instance(area->used_space.leaf_head.next, btree_node_t, leaf_link);
440
        node = list_get_instance(cur, btree_node_t, leaf_link);
446
        if ((cond = (bool) node->keys)) {
441
        for (i = 0; i < node->keys; i++) {
447
            __address b = node->key[0];
442
            __address b = node->key[i];
448
            count_t i;
443
            count_t j;
449
            pte_t *pte;
444
            pte_t *pte;
450
           
445
           
451
            for (i = 0; i < (count_t) node->value[0]; i++) {
446
            for (j = 0; j < (count_t) node->value[i]; j++) {
452
                page_table_lock(as, false);
447
                page_table_lock(as, false);
453
                pte = page_mapping_find(as, b + i*PAGE_SIZE);
448
                pte = page_mapping_find(as, b + j*PAGE_SIZE);
454
                ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte));
449
                ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte));
455
                if (area->backend && area->backend->frame_free) {
450
                if (area->backend && area->backend->frame_free) {
456
                    area->backend->frame_free(area,
451
                    area->backend->frame_free(area,
457
                        b + i*PAGE_SIZE, PTE_GET_FRAME(pte));
452
                        b + j*PAGE_SIZE, PTE_GET_FRAME(pte));
458
                }
453
                }
459
                page_mapping_remove(as, b + i*PAGE_SIZE);
454
                page_mapping_remove(as, b + j*PAGE_SIZE);
460
                page_table_unlock(as, false);
455
                page_table_unlock(as, false);
461
            }
456
            }
462
        }
457
        }
463
    }
458
    }
464
 
459
 
Line 1471... Line 1466...
1471
 
1466
 
1472
    mutex_lock(&sh_info->lock);
1467
    mutex_lock(&sh_info->lock);
1473
    ASSERT(sh_info->refcount);
1468
    ASSERT(sh_info->refcount);
1474
    if (--sh_info->refcount == 0) {
1469
    if (--sh_info->refcount == 0) {
1475
        dealloc = true;
1470
        dealloc = true;
1476
        bool cond;
1471
        link_t *cur;
1477
       
1472
       
1478
        /*
1473
        /*
1479
         * Now walk carefully the pagemap B+tree and free/remove
1474
         * Now walk carefully the pagemap B+tree and free/remove
1480
         * reference from all frames found there.
1475
         * reference from all frames found there.
1481
         */
1476
         */
1482
        for (cond = true; cond;) {
1477
        for (cur = sh_info->pagemap.leaf_head.next; cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
1483
            btree_node_t *node;
1478
            btree_node_t *node;
-
 
1479
            int i;
1484
           
1480
           
1485
            ASSERT(!list_empty(&sh_info->pagemap.leaf_head));
-
 
1486
            node = list_get_instance(sh_info->pagemap.leaf_head.next, btree_node_t, leaf_link);
1481
            node = list_get_instance(cur, btree_node_t, leaf_link);
1487
            if ((cond = node->keys)) {
1482
            for (i = 0; i < node->keys; i++)
1488
                frame_free(ADDR2PFN((__address) node->value[0]));
1483
                frame_free(ADDR2PFN((__address) node->value[i]));
1489
            }
-
 
1490
        }
1484
        }
1491
       
1485
       
1492
    }
1486
    }
1493
    mutex_unlock(&sh_info->lock);
1487
    mutex_unlock(&sh_info->lock);
1494
   
1488