#define nelem(x) (sizeof(x)/sizeof((x)[0]))
#endif
+#ifndef container_of
+#define container_of(obj, type, member) \
+ (type*)((uintptr_t)obj - offsetof(type, member))
+#endif
+
/*
* Assertions
*/
char* cistrstr(char*, char*);
int tokenize(char*, char**, int);
+void* refallocate(size_t);
+void* refobject(size_t,void (*)(void*));
void* refretain(void*);
void refrelease(void*);
-void refcount(void*);
-static inline void __refreplace(void** var, void* val)
-{
- void* doomed = *var;
- *var = val;
- refrelease(doomed);
-}
-#define refreplace(var, val) \
- __refreplace((void**)var, val);
+size_t refcount(void*);
+void refreplace(void** var, void* val);
/*
* Rune Definitions and Routines
--- /dev/null
+#include "libc.h"
+
+typedef struct obj_t {
+ uintptr_t refcount;
+ void (*destruct)(void*);
+ uint8_t data[];
+} obj_t;
+
+void* refallocate(size_t sz)
+{
+ return refobject(sz, nil);
+}
+
+void* refobject(size_t sz, void (*destruct)(void*))
+{
+ obj_t* object = (obj_t*)malloc(sizeof(obj_t) + sz);
+ object->refcount = 1;
+ object->destruct = destruct;
+ return &(object->data[0]);
+}
+
+void* refretain(void* obj)
+{
+ obj_t* object = container_of(obj, obj_t, data);
+ object->refcount++;
+ return obj;
+}
+
+void refrelease(void* obj)
+{
+ obj_t* object = container_of(obj, obj_t, data);
+ object->refcount--;
+ if (object->refcount == 0) {
+ if (nil != object->destruct)
+ object->destruct(obj);
+ free(object);
+ }
+}
+
+size_t refcount(void* obj)
+{
+ obj_t* object = container_of(obj, obj_t, data);
+ return object->refcount;
+}
+
+void refreplace(void** var, void* val)
+{
+ void* deadite = *var;
+ *var = val;
+ refrelease(deadite);
+}
+