Skip to content

Commit

Permalink
fix anomap_clone, and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Anotra committed Feb 27, 2024
1 parent 21ed41c commit 811d9ea
Showing 1 changed file with 53 additions and 48 deletions.
101 changes: 53 additions & 48 deletions anomap.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,7 @@ struct anomap_lock {
bool (*attempt)(void *lock);
void (*acquire)(void *lock);
void (*release)(void *lock);
} r;
struct {
bool (*attempt)(void *lock);
void (*acquire)(void *lock);
void (*release)(void *lock);
} w;
} r, w;
};

static void *
Expand Down Expand Up @@ -105,47 +100,47 @@ static unsigned anomap_has_locks =
}

static bool
_pthread_rd_lock_attempt(void *lock) {
_pthread_rd_attempt(void *lock) {
return 0 == pthread_rwlock_tryrdlock(lock);
}

static void
_pthread_rd_lock(void *lock) {
_pthread_rd_acquire(void *lock) {
pthread_rwlock_rdlock(lock);
}

static void
_pthread_rd_unlock(void *lock) {
_pthread_rd_release(void *lock) {
pthread_rwlock_unlock(lock);
}

static bool
_pthread_wr_lock_attempt(void *lock) {
_pthread_wr_attempt(void *lock) {
return 0 == pthread_rwlock_trywrlock(lock);
}

static void
_pthread_wr_lock(void *lock) {
_pthread_wr_acquire(void *lock) {
pthread_rwlock_wrlock(lock);
}

static void
_pthread_wr_unlock(void *lock) {
_pthread_wr_release(void *lock) {
pthread_rwlock_unlock(lock);
}

static struct anomap_lock lock_functions = {
static const struct anomap_lock lock_functions = {
.create = _pthread_lock_create,
.destroy = _pthread_lock_destroy,
.r = {
.attempt = _pthread_rd_lock_attempt,
.acquire = _pthread_rd_lock,
.release = _pthread_rd_unlock,
.attempt = _pthread_rd_attempt,
.acquire = _pthread_rd_acquire,
.release = _pthread_rd_release,
},
.w = {
.attempt = _pthread_wr_lock_attempt,
.acquire = _pthread_wr_lock,
.release = _pthread_wr_unlock,
.attempt = _pthread_wr_attempt,
.acquire = _pthread_wr_acquire,
.release = _pthread_wr_release,
},
};
#elif ANOMAP_NATIVE_LOCKS == NATIVE_LOCK_WINDOWS
Expand All @@ -165,60 +160,62 @@ static unsigned anomap_has_locks =
}

static bool
_srw_rd_lock_attempt(void *lock) {
_srw_rd_attempt(void *lock) {
return TryAcquireSRWLockShared(lock);
}

static void
_srw_rd_lock(void *lock) {
_srw_rd_acquire(void *lock) {
AcquireSRWLockShared(lock);
}

static void
_srw_rd_unlock(void *lock) {
_srw_rd_release(void *lock) {
ReleaseSRWLockShared(lock);
}

static bool
_srw_wr_lock_attempt(void *lock) {
_srw_wr_attempt(void *lock) {
return TryAcquireSRWLockExclusive(lock);
}

static void
_srw_wr_lock(void *lock) {
_srw_wr_acquire(void *lock) {
AcquireSRWLockExclusive(lock);
}

static void
_srw_wr_unlock(void *lock) {
_srw_wr_release(void *lock) {
ReleaseSRWLockExclusive(lock);
}

static struct anomap_lock lock_functions = {
static const struct anomap_lock lock_functions = {
.create = _srw_lock_create,
.destroy = _srw_lock_destroy,
.r = {
.attempt = _srw_rd_lock_attempt,
.acquire = _srw_rd_lock,
.release = _srw_rd_unlock,
.attempt = _srw_rd_attempt,
.acquire = _srw_rd_acquire,
.release = _srw_rd_release,
},
.w = {
.attempt = _srw_wr_lock_attempt,
.acquire = _srw_wr_lock,
.release = _srw_wr_unlock,
.attempt = _srw_wr_attempt,
.acquire = _srw_wr_acquire,
.release = _srw_wr_release,
},
};
#else
#error native lock not yet implemented
#endif
#endif

#define LOCK_W_ATTEMPT map->lock.functions->w.attempt(map->lock.lock)
#define LOCK_W_ACQUIRE map->lock.functions->w.acquire(map->lock.lock)
#define LOCK_W_RELEASE map->lock.functions->w.release(map->lock.lock)
#define LOCK_R_ATTEMPT map->lock.functions->r.attempt(map->lock.lock)
#define LOCK_R_ACQUIRE map->lock.functions->r.acquire(map->lock.lock)
#define LOCK_R_RELEASE map->lock.functions->r.release(map->lock.lock)
#define LOCK_DO(MODE, FUNC) \
map->lock.functions->MODE.FUNC(map->lock.lock)
#define LOCK_W_ATTEMPT LOCK_DO(w, attempt)
#define LOCK_W_ACQUIRE LOCK_DO(w, acquire)
#define LOCK_W_RELEASE LOCK_DO(w, release)
#define LOCK_R_ATTEMPT LOCK_DO(r, attempt)
#define LOCK_R_ACQUIRE LOCK_DO(r, acquire)
#define LOCK_R_RELEASE LOCK_DO(r, release)

#define ANOMAP_ALLOWED_OPTIONS ( anomap_reverse_order \
| anomap_direct_access \
Expand All @@ -241,7 +238,7 @@ struct anomap {
struct {
unsigned *arr;
size_t len : 32, cap : 32;
size_t highest;
unsigned highest;
} map;
struct {
char *arr;
Expand Down Expand Up @@ -331,11 +328,11 @@ struct anomap *
anomap_clone(struct anomap *map, anomap_clone_options options) {
if (options) return NULL;
struct anomap *clone = malloc(sizeof *clone);
if (!clone) return NULL;
struct {
void *ptrs[16];
size_t len;
} cleanup = { 0 };
if (!clone) return NULL;
} cleanup = { .len = 0 };

LOCK_R_ACQUIRE;
memcpy(clone, map, sizeof *clone);
Expand All @@ -359,6 +356,13 @@ anomap_clone(struct anomap *map, anomap_clone_options options) {
CLONE_ARRAY(vals, clone->vals.cap * clone->vals.size);
if (clone->options & anomap_preserve_order)
CLONE_ARRAY(order, clone->order.cap * sizeof *clone->order.arr);
} else {
memset(&clone->map, 0, sizeof clone->map);
memset(&clone->keys, 0, sizeof clone->keys);
clone->keys.size = map->keys.size;
memset(&clone->vals, 0, sizeof clone->vals);
clone->vals.size = map->vals.size;
memset(&clone->order, 0, sizeof clone->order);
}

LOCK_R_RELEASE;
Expand All @@ -378,7 +382,7 @@ void
anomap_move(struct anomap *dest, bool free_on_destroy, struct anomap *map) {
LOCK_W_ACQUIRE;
memcpy(dest, map, sizeof *dest);
bool free_map = map->free_on_cleanup;
const bool free_map = map->free_on_cleanup;
dest->free_on_cleanup = free_on_destroy;
memset(map, 0, sizeof *map);
if (free_map) free(map);
Expand Down Expand Up @@ -589,9 +593,10 @@ anomap_operation
anomap_do(struct anomap *map, anomap_operation operation,
void *key, void *val)
{
if (operation == anomap_getval)
LOCK_R_ACQUIRE;
else LOCK_W_ACQUIRE;
const bool use_write_lock = operation != anomap_getval;
if (use_write_lock)
LOCK_W_ACQUIRE;
else LOCK_R_ACQUIRE;
const size_t key_size = map->keys.size, val_size = map->vals.size;
anomap_operation result = 0;
size_t mpos = 0;
Expand Down Expand Up @@ -695,9 +700,9 @@ anomap_do(struct anomap *map, anomap_operation operation,
_anomap_on_empty(map);
}
finish:
if (operation == anomap_getval)
LOCK_R_RELEASE;
else LOCK_W_RELEASE;
if (use_write_lock)
LOCK_W_RELEASE;
else LOCK_R_RELEASE;
return result;
}

Expand Down

0 comments on commit 811d9ea

Please sign in to comment.