${BUILDDIR}/arc.o: src/arc.c src/arc.h src/memutils.h src/panic.h src/jmp.h \
- src/arith.h
+ src/arith.h src/atomic.h
${BUILDDIR}/defer.o: src/defer.c src/defer.h src/framealloc.h src/align.h \
src/stacktrack.h src/memutils.h src/panic.h src/jmp.h
${BUILDDIR}/eval.o: src/eval.c src/ccera.h src/jmp.h src/defer.h src/framealloc.h \
src/align.h src/stacktrack.h src/memutils.h src/panic.h src/value.h \
src/value_get.h src/value_types.h src/value_new.h src/arith.h \
- src/arc.h
+ src/arc.h src/atomic.h
${BUILDDIR}/framealloc.o: src/framealloc.c src/framealloc.h src/align.h \
src/stacktrack.h
${BUILDDIR}/panic.o: src/panic.c src/panic.h src/jmp.h src/defer.h src/framealloc.h \
SRCS=src/arc.c src/defer.c src/eval.c src/framealloc.c src/panic.c src/stacktrack.c src/value_lifetime.c src/value_list.c src/value_move.c src/value_new.c
-HEADERS=src/align.h src/arc.h src/arith.h src/ccera.h src/defer.h src/framealloc.h src/jmp.h src/memutils.h src/panic.h src/stacktrack.h src/value_get.h src/value.h src/value_new.h src/value_types.h
+HEADERS=src/align.h src/arc.h src/arith.h src/atomic.h src/ccera.h src/defer.h src/framealloc.h src/jmp.h src/memutils.h src/panic.h src/stacktrack.h src/value_get.h src/value.h src/value_new.h src/value_types.h
+
+CC = cc
+
+CONFFILE ?= conf.mk
+include ${CONFFILE}
BUILDDIR=.build
OBJS=${SRCS:src/%.c=${BUILDDIR}/%.o}
-CFLAGS=-Wall -Wextra -Werror -pthread -std=gnu17
-# IMPORTANT: We use this to properly keep track of stack frames at a source level
-CFLAGS += -finstrument-functions
+CFLAGS ?=
+
+CFLAGS += -Wall -Wextra -Werror -pthread -finstrument-functions
+
+CFLAGS += -std=gnu99
+
CFLAGS += -g
-CFLAGS += -O3
-#CFLAGS += -flto -ffat-lto-objects
CFLAGS += -fdiagnostics-color
-#CC=clang
-#CC=gcc
-CC=cc
+CFLAGS += -O3
-AR=gcc-ar
+LTO ?= 0
+
+UBSAN ?= 0
+ifeq (${UBSAN}, 1)
+CFLAGS += -fsanitize=undefined
+endif
+
+TSAN ?= 0
+ifeq (${TSAN}, 1)
+CFLAGS += -fsanitize=thread
+# Tsan incompat with lto
+ifeq (${LTO}, 1)
+$(info Disabling LTO because TSAN is enabled)
+endif
+LTO=0
+endif
+
+ASAN ?= 0
+ifeq (${ASAN}, 1)
+CFLAGS += -fsanitize=address
+# Tsan incompat with lto
+ifeq (${LTO}, 1)
+$(info Disabling LTO because ASAN is enabled)
+endif
+LTO=0
+endif
+
+ifeq (${CC}, gcc)
+ifeq (${LTO}, 1)
+$(info Disabling LTO because gcc has SSA corruption bug)
+CFLAGS += -flto -ffat-lto-objects
+endif
+endif
+
+ifeq (${LTO}, 1)
+CFLAGS += -flto -ffat-lto-objects
+endif
+
+AR=ar
+
+MAKE_CMD=CONFFILE=${CONFFILE} make
MAKEFLAGS += --no-print-directory
all: ${NAME}
+${CONFFILE}:
+ touch $@
+
+${DEPSFILE}:
+ touch $@
+
include ${DEPSFILE}
-${BUILDDIR}/%.o: src/%.c ${THIS} ${DEPSFILE} | ${BUILDDIR}
+${BUILDDIR}/%.o: src/%.c ${THIS} ${DEPSFILE} ${CONFFILE} | ${BUILDDIR}
${CC} ${CFLAGS} -c -o $@ $<
${BUILDDIR}:
@test ! -e .norm_fail
watch-step:
- make remakefile
- make redeps
- make norm
- make
+ ${MAKE_CMD} remakefile
+ ${MAKE_CMD} redeps
+ ${MAKE_CMD} norm
+ ${MAKE_CMD} all
watch:
- watch -c -n 1 make watch-step
+ watch -c -n 1 ${MAKE_CMD} watch-step
-norm-watch:
- watch -c -n 1 make norm
-
-build-watch:
- watch -c -n 1 make
-
-a.out: test.c ${NAME} ${THIS}
- ${CC} ${CFLAGS} test.c ccera.a
+a.out: test.c ${NAME}
+ ${CC} ${CFLAGS} $^
test: a.out
- valgrind ./a.out
+ ./a.out
.PHONY: all clean fclean re remakefile redeps norm watch-step watch test
-
-${BUILDDIR}/arc.o: src/arc.c src/arc.h
--- /dev/null
+#LTO=1
+CC=clang
+#UBSAN=1
+TSAN=1
+#ASAN=1
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/04/29 16:40:27 by agilliar #+# #+# */
-/* Updated: 2026/05/13 16:42:04 by agilliar ### ########.fr */
+/* Updated: 2026/05/15 11:22:29 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
#include "panic.h"
#include "memutils.h"
#include "arith.h"
+#include "atomic.h"
t_arc arc_new(size_t size)
{
{
if (__atomic_sub_fetch(((size_t *)arc) - 1, 1, __ATOMIC_RELEASE) != 0)
return ;
- __atomic_thread_fence(__ATOMIC_ACQUIRE);
+ acquire_fence_on(((size_t *)arc) - 1);
((void (*)(void *))destructor)(arc);
free(((char *)arc) - 8);
}
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/05/13 08:56:53 by agilliar #+# #+# */
-/* Updated: 2026/05/13 12:55:03 by agilliar ### ########.fr */
+/* Updated: 2026/05/14 15:55:35 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* atomic.h :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2026/05/15 11:18:31 by agilliar #+# #+# */
+/* Updated: 2026/05/15 11:23:58 by agilliar ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#ifndef ATOMIC_H
+# define ATOMIC_H
+
+# include <stddef.h>
+
+# if __has_feature(thread_sanitizer)
+
+__attribute__((always_inline))
+static inline void acquire_fence_on(size_t *p)
+{
+ __atomic_load_n(p, __ATOMIC_ACQUIRE);
+}
+
+# else
+
+__attribute__((always_inline))
+static inline void acquire_fence_on(size_t *p)
+{
+ (void) p;
+ __atomic_thread_fence(__ATOMIC_ACQUIRE);
+}
+
+# endif
+
+#endif
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/04/29 16:08:57 by agilliar #+# #+# */
-/* Updated: 2026/05/14 14:58:03 by agilliar ### ########.fr */
+/* Updated: 2026/05/15 11:21:51 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
# include "arith.h"
# include "arc.h"
# include "stacktrack.h"
+# include "atomic.h"
// The expression value is a tuple of an evaluatable and the argument to give it
//
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/05/05 17:31:36 by agilliar #+# #+# */
-/* Updated: 2026/05/14 14:49:54 by agilliar ### ########.fr */
+/* Updated: 2026/05/15 11:02:57 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/05/05 15:38:33 by agilliar #+# #+# */
-/* Updated: 2026/05/14 15:27:37 by agilliar ### ########.fr */
+/* Updated: 2026/05/15 11:04:14 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/05/14 12:00:36 by agilliar #+# #+# */
-/* Updated: 2026/05/14 15:33:45 by agilliar ### ########.fr */
+/* Updated: 2026/05/15 11:04:26 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/05/13 22:04:36 by agilliar #+# #+# */
-/* Updated: 2026/05/13 22:08:57 by agilliar ### ########.fr */
+/* Updated: 2026/05/15 13:05:11 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
enum e_value tag;
} t_value;
-typedef struct s_bytes
+struct s_bytes
{
size_t len;
char buf[];
-} t_bytes;
+};
-typedef struct s_list
+struct s_list
{
size_t len;
t_value buf[];
-} t_list;
+};
#endif
/* By: agilliar <agilliar@student.42mulhouse.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/04/30 17:19:58 by agilliar #+# #+# */
-/* Updated: 2026/05/14 15:45:14 by agilliar ### ########.fr */
+/* Updated: 2026/05/15 11:08:09 by agilliar ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdio.h>
#include <stdlib.h>
-void main2(char *orig)
+void main2(void *_orig)
{
- char *s = malloc(strlen(orig) + 1);
+ char *orig = _orig;
+ char *s = malloc(strlen(orig) + 1);
defer(free, s);
- char *s2 = malloc(strlen(orig) + 1);
+ char *s2 = malloc(strlen(orig) + 1);
defer(free, s2);
strcpy(s2, orig);
printf("%s\n", s2);