mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-28 13:30:29 +00:00
Harden against aba problem
This commit is contained in:
parent
610c951f71
commit
884d89235f
8 changed files with 212 additions and 85 deletions
|
@ -1,24 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2024 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/atomic.h"
|
||||
|
||||
bool dog(_Atomic(long) *p, long *e, long w) {
|
||||
return atomic_compare_exchange_weak_explicit(p, e, w, memory_order_acq_rel,
|
||||
memory_order_relaxed);
|
||||
}
|
|
@ -29,7 +29,7 @@ struct Map {
|
|||
struct Maps {
|
||||
struct Tree *maps;
|
||||
_Atomic(uint64_t) lock;
|
||||
_Atomic(struct Map *) freed;
|
||||
_Atomic(uintptr_t) freed;
|
||||
size_t count;
|
||||
size_t pages;
|
||||
_Atomic(char *) pick;
|
||||
|
|
|
@ -50,6 +50,13 @@
|
|||
|
||||
#define PGUP(x) (((x) + pagesz - 1) & -pagesz)
|
||||
|
||||
#define MASQUE 0x00fffffffffffff8
|
||||
#define PTR(x) ((uintptr_t)(x) & MASQUE)
|
||||
#define TAG(x) ROL((uintptr_t)(x) & ~MASQUE, 8)
|
||||
#define ABA(p, t) ((uintptr_t)(p) | (ROR((uintptr_t)(t), 8) & ~MASQUE))
|
||||
#define ROL(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
|
||||
#define ROR(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
|
||||
|
||||
#if !MMDEBUG
|
||||
#define ASSERT(x) (void)0
|
||||
#else
|
||||
|
@ -227,14 +234,17 @@ StartOver:
|
|||
}
|
||||
|
||||
void __maps_free(struct Map *map) {
|
||||
uintptr_t tip;
|
||||
ASSERT(!TAG(map));
|
||||
map->size = 0;
|
||||
map->addr = MAP_FAILED;
|
||||
map->freed = atomic_load_explicit(&__maps.freed, memory_order_relaxed);
|
||||
for (;;) {
|
||||
if (atomic_compare_exchange_weak_explicit(&__maps.freed, &map->freed, map,
|
||||
memory_order_release,
|
||||
memory_order_relaxed))
|
||||
for (tip = atomic_load_explicit(&__maps.freed, memory_order_relaxed);;) {
|
||||
map->freed = (struct Map *)PTR(tip);
|
||||
if (atomic_compare_exchange_weak_explicit(
|
||||
&__maps.freed, &tip, ABA(map, TAG(tip) + 1), memory_order_release,
|
||||
memory_order_relaxed))
|
||||
break;
|
||||
pthread_pause_np();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,12 +307,13 @@ void __maps_insert(struct Map *map) {
|
|||
|
||||
struct Map *__maps_alloc(void) {
|
||||
struct Map *map;
|
||||
map = atomic_load_explicit(&__maps.freed, memory_order_relaxed);
|
||||
while (map) {
|
||||
if (atomic_compare_exchange_weak_explicit(&__maps.freed, &map, map->freed,
|
||||
memory_order_acquire,
|
||||
memory_order_relaxed))
|
||||
uintptr_t tip = atomic_load_explicit(&__maps.freed, memory_order_relaxed);
|
||||
while ((map = (struct Map *)PTR(tip))) {
|
||||
if (atomic_compare_exchange_weak_explicit(
|
||||
&__maps.freed, &tip, ABA(map->freed, TAG(tip) + 1),
|
||||
memory_order_acquire, memory_order_relaxed))
|
||||
return map;
|
||||
pthread_pause_np();
|
||||
}
|
||||
int gransz = __gransize;
|
||||
struct DirectMap sys = sys_mmap(0, gransz, PROT_READ | PROT_WRITE,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue