initial commit

master
Avril 3 years ago
commit 0e3c5739c3
Signed by: flanchan
GPG Key ID: 284488987C31F630

4
.gitignore vendored

@ -0,0 +1,4 @@
*.o
*~
*.a
*.so

@ -0,0 +1,39 @@
SRC = $(wildcard src/*.c)
INCLUDE = include
CFLAGS = -Wall $(addprefix -I,$(INCLUDE)) --std=gnu11 -pedantic
CFLAGS+= -O3 -flto -fgraphite
LDFLAGS = -O3 -flto
OBJ:= obj
STATIC = $(addprefix $(OBJ)/static/,$(SRC:.c=.o))
SHARED = $(addprefix $(OBJ)/shared/,$(SRC:.c=.o))
BUILD = librc
.PHONY: all
all: dirs $(BUILD)
dirs:
@mkdir -p obj/{shared,static}/src
obj/static/%.o: %.c
$(CC) -c $< $(CFLAGS) -o $@
obj/shared/%.o: %.c
$(CC) -fPIC -c $< $(CFLAGS) -o $@
$(BUILD).a: $(STATIC)
ar rcs $@ $^
$(BUILD).so: $(SHARED)
$(CC) -shared $^ $(CFLAGS) -o $@ $(LDFLAGS)
strip $@
$(BUILD): $(BUILD).a $(BUILD).so
clean:
rm -f $(BUILD).{a,so}
rm -rf obj

@ -0,0 +1 @@
Owned pointers in C

@ -0,0 +1,27 @@
#ifndef _RC_H
#define _RC_H
#ifdef __cplusplus
#define _rc_restrict __restrict
extern "C" {
#else
#define _rc_restrict restrict
#endif
#ifndef __GNUC__
#define _rc_attr(_)
#else
#define _rc_attr(v) __attribute__(v)
#endif
typedef struct rc* rc_t;
void* _rc_restrict rc_malloc(size_t sz) _rc_attr((malloc, alloc_size(1), returns_nonnull));
void rc_free(void* ptr) _rc_attr((nonnull));
void* _rc_attr((may_alias)) rc_clone(void* ptr) _rc_attr((pure, nonnull, returns_nonnull));
#ifdef __cplusplus
}
#endif
#endif /* _RC_H */

@ -0,0 +1,74 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <rc.h>
#define RC_CHK 0xabadcafe
struct rc {
uint32_t check;
_Atomic size_t refs;
uint8_t ptr[];
};
_rc_attr((noreturn)) static void panic(const char* string, ...)
{
va_list args;
va_start(args, string);
fprintf(stderr, "(librc) Fatal error: ");
vfprintf(stderr, string, args);
va_end(args);
fprintf(stderr, "\n");
abort();
}
_rc_attr((noinline, noreturn, cold)) static void _fail_invptr()
{
panic("Invalid RC pointer");
}
_rc_attr((noinline, noreturn, cold)) static void _fail_malloc(size_t sz)
{
panic("malloc() failed to allocate %d bytes (%d + sizeof(struct rc))", sz+sizeof(struct rc), sz);
}
_rc_attr((artificial, always_inline)) inline static rc_t ptr_rev(void* ptr)
{
if (!ptr) _fail_invptr();
return (rc_t)(((uint8_t*)ptr) - sizeof(struct rc));
}
_rc_attr((nonnull)) inline static void rc_checkptr(const rc_t rc)
{
if (rc->check != RC_CHK) _fail_invptr();
}
_rc_attr((malloc, alloc_size(1), returns_nonnull)) void* restrict rc_malloc(size_t sz)
{
register rc_t rc = malloc(sz + sizeof(struct rc));
if (!rc) _fail_malloc(sz);
rc->check = RC_CHK;
rc->refs = 1;
return (void*) rc->ptr;
}
_rc_attr((nonnull)) void rc_free(void* ptr)
{
register rc_t rc = ptr_rev(ptr);
rc_checkptr(rc);
if (!--rc->refs) free(rc);
}
_rc_attr((pure, nonnull, returns_nonnull)) void* _rc_attr((may_alias)) rc_clone(void* ptr)
{
register rc_t rc = ptr_rev(ptr);
rc_checkptr(rc);
++rc->refs;
return ptr;
}
Loading…
Cancel
Save