提交 554c58e9 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Use cmpswap in the amd64 page table code.

上级 36f95831
...@@ -13,6 +13,8 @@ static inline void *p2v(uptr a) { return (void *) a + KBASE; } ...@@ -13,6 +13,8 @@ static inline void *p2v(uptr a) { return (void *) a + KBASE; }
#define NELEM(x) (sizeof(x)/sizeof((x)[0])) #define NELEM(x) (sizeof(x)/sizeof((x)[0]))
#define cmpswap(ptr, old, new) __sync_bool_compare_and_swap(ptr, old, new)
struct spinlock; struct spinlock;
struct condvar; struct condvar;
struct context; struct context;
......
...@@ -25,17 +25,21 @@ descend(pme_t *dir, void *va, u64 flags, int create, int level) ...@@ -25,17 +25,21 @@ descend(pme_t *dir, void *va, u64 flags, int create, int level)
pme_t entry; pme_t entry;
pme_t *next; pme_t *next;
retry:
dir = &dir[PX(level, va)]; dir = &dir[PX(level, va)];
entry = *dir; entry = *dir;
if (entry == 0) { if (entry & PTE_P) {
next = p2v(PTE_ADDR(entry));
} else {
if (!create) if (!create)
return NULL; return NULL;
next = (u64*) pgalloc(); next = (pme_t*) pgalloc();
if (!next) if (!next)
return NULL; return NULL;
*dir = v2p(next) | PTE_P | PTE_W | flags; if (!cmpswap(dir, entry, v2p(next) | PTE_P | PTE_W | flags)) {
} else { kfree((void*) next);
next = p2v(PTE_ADDR(entry)); goto retry;
}
} }
return next; return next;
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论