Subversion Repositories HelenOS-historic

Rev

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

Rev 1413 Rev 1415
Line 81... Line 81...
81
    btree_t pagemap;    /**< B+tree containing complete map of anonymous pages of the shared area. */
81
    btree_t pagemap;    /**< B+tree containing complete map of anonymous pages of the shared area. */
82
};
82
};
83
 
83
 
84
as_operations_t *as_operations = NULL;
84
as_operations_t *as_operations = NULL;
85
 
85
 
86
/** Address space lock. It protects inactive_as_with_asid_head. Must be acquired before as_t mutex. */
86
/** This lock protects inactive_as_with_asid_head list. It must be acquired before as_t mutex. */
87
SPINLOCK_INITIALIZE(as_lock);
87
SPINLOCK_INITIALIZE(inactive_as_with_asid_lock);
88
 
88
 
89
/**
89
/**
90
 * This list contains address spaces that are not active on any
90
 * This list contains address spaces that are not active on any
91
 * processor and that have valid ASID.
91
 * processor and that have valid ASID.
92
 */
92
 */
Line 126... Line 126...
126
    if (flags & FLAG_AS_KERNEL)
126
    if (flags & FLAG_AS_KERNEL)
127
        as->asid = ASID_KERNEL;
127
        as->asid = ASID_KERNEL;
128
    else
128
    else
129
        as->asid = ASID_INVALID;
129
        as->asid = ASID_INVALID;
130
   
130
   
131
    as->refcount = 0;
131
    as->cpu_refcount = 0;
132
    as->page_table = page_table_create(flags);
132
    as->page_table = page_table_create(flags);
133
 
133
 
134
    return as;
134
    return as;
135
}
135
}
136
 
136
 
137
/** Free Adress space */
137
/** Free Adress space */
138
void as_free(as_t *as)
138
void as_free(as_t *as)
139
{
139
{
140
    ASSERT(as->refcount == 0);
140
    ASSERT(as->cpu_refcount == 0);
141
 
141
 
142
    /* TODO: free as_areas and other resources held by as */
142
    /* TODO: free as_areas and other resources held by as */
143
    /* TODO: free page table */
143
    /* TODO: free page table */
144
    free(as);
144
    free(as);
145
}
145
}
Line 731... Line 731...
731
}
731
}
732
 
732
 
733
/** Switch address spaces.
733
/** Switch address spaces.
734
 *
734
 *
735
 * Note that this function cannot sleep as it is essentially a part of
735
 * Note that this function cannot sleep as it is essentially a part of
736
 * the scheduling. Sleeping here would lead to deadlock on wakeup.
736
 * scheduling. Sleeping here would lead to deadlock on wakeup.
737
 *
737
 *
738
 * @param old Old address space or NULL.
738
 * @param old Old address space or NULL.
739
 * @param new New address space.
739
 * @param new New address space.
740
 */
740
 */
741
void as_switch(as_t *old, as_t *new)
741
void as_switch(as_t *old, as_t *new)
742
{
742
{
743
    ipl_t ipl;
743
    ipl_t ipl;
744
    bool needs_asid = false;
744
    bool needs_asid = false;
745
   
745
   
746
    ipl = interrupts_disable();
746
    ipl = interrupts_disable();
747
    spinlock_lock(&as_lock);
747
    spinlock_lock(&inactive_as_with_asid_lock);
748
 
748
 
749
    /*
749
    /*
750
     * First, take care of the old address space.
750
     * First, take care of the old address space.
751
     */
751
     */
752
    if (old) {
752
    if (old) {
753
        mutex_lock_active(&old->lock);
753
        mutex_lock_active(&old->lock);
754
        ASSERT(old->refcount);
754
        ASSERT(old->cpu_refcount);
755
        if((--old->refcount == 0) && (old != AS_KERNEL)) {
755
        if((--old->cpu_refcount == 0) && (old != AS_KERNEL)) {
756
            /*
756
            /*
757
             * The old address space is no longer active on
757
             * The old address space is no longer active on
758
             * any processor. It can be appended to the
758
             * any processor. It can be appended to the
759
             * list of inactive address spaces with assigned
759
             * list of inactive address spaces with assigned
760
             * ASID.
760
             * ASID.
Line 767... Line 767...
767
 
767
 
768
    /*
768
    /*
769
     * Second, prepare the new address space.
769
     * Second, prepare the new address space.
770
     */
770
     */
771
    mutex_lock_active(&new->lock);
771
    mutex_lock_active(&new->lock);
772
    if ((new->refcount++ == 0) && (new != AS_KERNEL)) {
772
    if ((new->cpu_refcount++ == 0) && (new != AS_KERNEL)) {
773
        if (new->asid != ASID_INVALID)
773
        if (new->asid != ASID_INVALID)
774
            list_remove(&new->inactive_as_with_asid_link);
774
            list_remove(&new->inactive_as_with_asid_link);
775
        else
775
        else
776
            needs_asid = true;  /* defer call to asid_get() until new->lock is released */
776
            needs_asid = true;  /* defer call to asid_get() until new->lock is released */
777
    }
777
    }
Line 788... Line 788...
788
        asid = asid_get();
788
        asid = asid_get();
789
        mutex_lock_active(&new->lock);
789
        mutex_lock_active(&new->lock);
790
        new->asid = asid;
790
        new->asid = asid;
791
        mutex_unlock(&new->lock);
791
        mutex_unlock(&new->lock);
792
    }
792
    }
793
    spinlock_unlock(&as_lock);
793
    spinlock_unlock(&inactive_as_with_asid_lock);
794
    interrupts_restore(ipl);
794
    interrupts_restore(ipl);
795
   
795
   
796
    /*
796
    /*
797
     * Perform architecture-specific steps.
797
     * Perform architecture-specific steps.
798
     * (e.g. write ASID to hardware register etc.)
798
     * (e.g. write ASID to hardware register etc.)