Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/as.c

    r826599a2 r5df1963  
    520520}
    521521
    522 /** Remove reference to address space area share info.
    523  *
    524  * If the reference count drops to 0, the sh_info is deallocated.
    525  *
    526  * @param sh_info Pointer to address space area share info.
    527  *
    528  */
    529 NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
    530 {
    531         bool dealloc = false;
    532        
    533         mutex_lock(&sh_info->lock);
    534         ASSERT(sh_info->refcount);
    535        
    536         if (--sh_info->refcount == 0) {
    537                 dealloc = true;
    538                
    539                 /*
    540                  * Now walk carefully the pagemap B+tree and free/remove
    541                  * reference from all frames found there.
    542                  */
    543                 list_foreach(sh_info->pagemap.leaf_list, leaf_link,
    544                     btree_node_t, node) {
    545                         btree_key_t i;
    546                        
    547                         for (i = 0; i < node->keys; i++)
    548                                 frame_free((uintptr_t) node->value[i], 1);
    549                 }
    550                
    551         }
    552         mutex_unlock(&sh_info->lock);
    553        
    554         if (dealloc) {
    555                 if (sh_info->backend && sh_info->backend->destroy_shared_data) {
    556                         sh_info->backend->destroy_shared_data(
    557                             sh_info->backend_shared_data);
    558                 }
    559                 btree_destroy(&sh_info->pagemap);
    560                 free(sh_info);
    561         }
    562 }
    563 
    564 
    565522/** Create address space area of common attributes.
    566523 *
     
    572529 * @param attrs        Attributes of the area.
    573530 * @param backend      Address space area backend. NULL if no backend is used.
    574  * @param backend_data NULL or a pointer to custom backend data.
     531 * @param backend_data NULL or a pointer to an array holding two void *.
    575532 * @param base         Starting virtual address of the area.
    576533 *                     If set to -1, a suitable mappable area is found.
     
    609566        }
    610567
    611         if (overflows_into_positive(*base, size)) {
    612                 mutex_unlock(&as->lock);
     568        if (overflows_into_positive(*base, size))
    613569                return NULL;
    614         }
    615570
    616571        if (!check_area_conflicts(as, *base, pages, guarded, NULL)) {
     
    629584        area->resident = 0;
    630585        area->base = *base;
     586        area->sh_info = NULL;
    631587        area->backend = backend;
    632         area->sh_info = NULL;
    633588       
    634589        if (backend_data)
     
    636591        else
    637592                memsetb(&area->backend_data, sizeof(area->backend_data), 0);
    638 
    639         share_info_t *si = NULL;
    640 
    641         /*
    642          * Create the sharing info structure.
    643          * We do this in advance for every new area, even if it is not going
    644          * to be shared.
    645          */
    646         if (!(attrs & AS_AREA_ATTR_PARTIAL)) {
    647                 si = (share_info_t *) malloc(sizeof(share_info_t), 0);
    648                 mutex_initialize(&si->lock, MUTEX_PASSIVE);
    649                 si->refcount = 1;
    650                 si->shared = false;
    651                 si->backend_shared_data = NULL;
    652                 si->backend = backend;
    653                 btree_create(&si->pagemap);
    654 
    655                 area->sh_info = si;
    656        
    657                 if (area->backend && area->backend->create_shared_data) {
    658                         if (!area->backend->create_shared_data(area)) {
    659                                 free(area);
    660                                 mutex_unlock(&as->lock);
    661                                 sh_info_remove_reference(si);
    662                                 return NULL;
    663                         }
    664                 }
    665         }
    666 
     593       
    667594        if (area->backend && area->backend->create) {
    668595                if (!area->backend->create(area)) {
    669596                        free(area);
    670597                        mutex_unlock(&as->lock);
    671                         if (!(attrs & AS_AREA_ATTR_PARTIAL))
    672                                 sh_info_remove_reference(si);
    673598                        return NULL;
    674599                }
    675600        }
    676 
     601       
    677602        btree_create(&area->used_space);
    678603        btree_insert(&as->as_area_btree, *base, (void *) area,
     
    784709        }
    785710       
    786         mutex_lock(&area->sh_info->lock);
    787         if (area->sh_info->shared) {
     711        if (area->sh_info) {
    788712                /*
    789713                 * Remapping of shared address space areas
    790714                 * is not supported.
    791715                 */
    792                 mutex_unlock(&area->sh_info->lock);
    793716                mutex_unlock(&area->lock);
    794717                mutex_unlock(&as->lock);
    795718                return ENOTSUP;
    796719        }
    797         mutex_unlock(&area->sh_info->lock);
    798720       
    799721        size_t pages = SIZE2FRAMES((address - area->base) + size);
     
    959881}
    960882
     883/** Remove reference to address space area share info.
     884 *
     885 * If the reference count drops to 0, the sh_info is deallocated.
     886 *
     887 * @param sh_info Pointer to address space area share info.
     888 *
     889 */
     890NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
     891{
     892        bool dealloc = false;
     893       
     894        mutex_lock(&sh_info->lock);
     895        ASSERT(sh_info->refcount);
     896       
     897        if (--sh_info->refcount == 0) {
     898                dealloc = true;
     899               
     900                /*
     901                 * Now walk carefully the pagemap B+tree and free/remove
     902                 * reference from all frames found there.
     903                 */
     904                list_foreach(sh_info->pagemap.leaf_list, leaf_link,
     905                    btree_node_t, node) {
     906                        btree_key_t i;
     907                       
     908                        for (i = 0; i < node->keys; i++)
     909                                frame_free((uintptr_t) node->value[i], 1);
     910                }
     911               
     912        }
     913        mutex_unlock(&sh_info->lock);
     914       
     915        if (dealloc) {
     916                btree_destroy(&sh_info->pagemap);
     917                free(sh_info);
     918        }
     919}
     920
    961921/** Destroy address space area.
    962922 *
     
    10401000        area->attributes |= AS_AREA_ATTR_PARTIAL;
    10411001       
    1042         sh_info_remove_reference(area->sh_info);
     1002        if (area->sh_info)
     1003                sh_info_remove_reference(area->sh_info);
    10431004       
    10441005        mutex_unlock(&area->lock);
     
    11271088         */
    11281089        share_info_t *sh_info = src_area->sh_info;
    1129        
    1130         mutex_lock(&sh_info->lock);
    1131         sh_info->refcount++;
    1132         bool shared = sh_info->shared;
    1133         sh_info->shared = true;
    1134         mutex_unlock(&sh_info->lock);
    1135 
    1136         if (!shared) {
     1090        if (!sh_info) {
     1091                sh_info = (share_info_t *) malloc(sizeof(share_info_t), 0);
     1092                mutex_initialize(&sh_info->lock, MUTEX_PASSIVE);
     1093                sh_info->refcount = 2;
     1094                btree_create(&sh_info->pagemap);
     1095                src_area->sh_info = sh_info;
     1096               
    11371097                /*
    11381098                 * Call the backend to setup sharing.
    1139                  * This only happens once for each sh_info.
    11401099                 */
    11411100                src_area->backend->share(src_area);
     1101        } else {
     1102                mutex_lock(&sh_info->lock);
     1103                sh_info->refcount++;
     1104                mutex_unlock(&sh_info->lock);
    11421105        }
    11431106       
     
    12581221        }
    12591222       
    1260         if (area->backend != &anon_backend) {
     1223        if ((area->sh_info) || (area->backend != &anon_backend)) {
     1224                /* Copying shared areas not supported yet */
    12611225                /* Copying non-anonymous memory not supported yet */
    12621226                mutex_unlock(&area->lock);
     
    12641228                return ENOTSUP;
    12651229        }
    1266 
    1267         mutex_lock(&area->sh_info->lock);
    1268         if (area->sh_info->shared) {
    1269                 /* Copying shared areas not supported yet */
    1270                 mutex_unlock(&area->sh_info->lock);
    1271                 mutex_unlock(&area->lock);
    1272                 mutex_unlock(&as->lock);
    1273                 return ENOTSUP;
    1274         }
    1275         mutex_unlock(&area->sh_info->lock);
    12761230       
    12771231        /*
     
    17251679        ASSERT(count);
    17261680       
    1727         btree_node_t *leaf = NULL;
     1681        btree_node_t *leaf;
    17281682        size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
    17291683        if (pages) {
     
    17331687                return false;
    17341688        }
    1735 
    1736         ASSERT(leaf != NULL);
    17371689       
    17381690        if (!leaf->keys) {
Note: See TracChangeset for help on using the changeset viewer.