28,93 → 28,5 |
*/ |
|
#include <arch/mm/asid.h> |
#include <synch/spinlock.h> |
#include <arch.h> |
#include <debug.h> |
#include <typedefs.h> |
|
SPINLOCK_INITIALIZE(asid_usage_lock); |
static count_t asid_usage[ASIDS]; /**< Usage tracking array for ASIDs */ |
|
/** Get ASID |
* |
* Get the least used ASID. |
* |
* @return ASID |
*/ |
asid_t asid_get(void) |
{ |
ipl_t ipl; |
int i, j; |
count_t min; |
|
min = (unsigned) -1; |
|
ipl = interrupts_disable(); |
spinlock_lock(&asid_usage_lock); |
|
for (i = ASID_START, j = ASID_START; i < ASIDS; i++) { |
if (asid_usage[i] < min) { |
j = i; |
min = asid_usage[i]; |
if (!min) |
break; |
} |
} |
|
asid_usage[j]++; |
|
spinlock_unlock(&asid_usage_lock); |
interrupts_restore(ipl); |
|
return i; |
} |
|
/** Release ASID |
* |
* Release ASID by decrementing its usage count. |
* |
* @param asid ASID. |
*/ |
void asid_put(asid_t asid) |
{ |
ipl_t ipl; |
|
ipl = interrupts_disable(); |
spinlock_lock(&asid_usage_lock); |
|
ASSERT(asid != ASID_INVALID); |
|
ASSERT(asid_usage[asid] > 0); |
asid_usage[asid]--; |
|
spinlock_unlock(&asid_usage_lock); |
interrupts_restore(ipl); |
} |
|
/** Find out whether ASID is used by more address spaces |
* |
* Find out whether ASID is used by more address spaces. |
* |
* @param asid ASID in question. |
* |
* @return True if 'asid' is used by more address spaces, false otherwise. |
*/ |
bool asid_has_conflicts(asid_t asid) |
{ |
bool has_conflicts = false; |
ipl_t ipl; |
|
ASSERT(asid != ASID_INVALID); |
|
ipl = interrupts_disable(); |
spinlock_lock(&asid_usage_lock); |
|
if (asid_usage[asid] > 1) |
has_conflicts = true; |
|
spinlock_unlock(&asid_usage_lock); |
interrupts_restore(ipl); |
|
return has_conflicts; |
} |