Skip to content

Instantly share code, notes, and snippets.

@kalamay
Created December 2, 2017 18:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kalamay/cbdbc1724c358d578b9862e644505591 to your computer and use it in GitHub Desktop.
Save kalamay/cbdbc1724c358d578b9862e644505591 to your computer and use it in GitHub Desktop.
Shared Pointer
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdbool.h>
static inline void increment(unsigned *cnt)
{
__atomic_fetch_add(cnt, 1, __ATOMIC_RELAXED);
}
static inline bool decrement(unsigned *cnt)
{
return __atomic_fetch_sub(cnt, 1, __ATOMIC_ACQ_REL) == 1;
}
/*
static inline bool try_increment(unsigned *cnt)
{
unsigned n = __atomic_load_n(cnt, __ATOMIC_RELAXED);
while (n > 0) {
if (__atomic_compare_exchange_n(cnt, &n, n+1, true, __ATOMIC_RELAXED, __ATOMIC_RELAXED)) {
return true;
}
}
return false;
}
*/
struct Shared {
unsigned strong_ref;
unsigned weak_ref;
void (*final)(void *);
};
struct Thing {
struct Shared shared;
int id;
};
static void
final_thing(void *ptr)
{
printf("final: %d\n", ((struct Thing *)ptr)->id);
}
static struct Thing *
make_thing(int id)
{
struct Thing *t = malloc(sizeof(*t));
t->shared.strong_ref = 1;
t->shared.weak_ref = 1;
t->shared.final = final_thing;
t->id = id;
return t;
}
static struct Thing *
weak_retain(struct Thing *t)
{
if (t) {
increment(&t->shared.weak_ref);
}
return t;
}
static struct Thing *
retain(struct Thing *t)
{
if (t) {
increment(&t->shared.strong_ref);
}
return t;
}
static void
weak_release(struct Thing *t)
{
if (t && decrement(&t->shared.weak_ref)) {
free(t);
}
}
static void
release(struct Thing *t)
{
if (t && decrement(&t->shared.strong_ref)) {
t->shared.final(t);
weak_release(t);
}
}
int
main(void)
{
struct Thing *t = make_thing(5);
struct Thing *t2 = retain(t);
struct Thing *t3 = weak_retain(t);
release(t);
weak_release(t3);
release(t2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment