Fix pthread init and null for C++

This commit is contained in:
Wildan M
2026-06-04 00:38:58 +07:00
parent e2218c53d3
commit 6acf560ed0
10 changed files with 78 additions and 8 deletions
+7
View File
@@ -9,3 +9,10 @@
include_guard = "_RELIBC_BITS_NULL_T_H"
language = "C"
no_includes = true
after_includes = """
#ifdef __cplusplus
#define NULL nullptr
#else
#define NULL ((void *)0)
#endif
"""
+1 -4
View File
@@ -1,4 +1 @@
use crate::platform::types::c_long;
/// Null pointer constant.
pub const NULL: c_long = 0;
// NULL is defined in cbindgen
+3 -3
View File
@@ -6,10 +6,10 @@ no_includes = true
cpp_compat = true
# TODO: Any better way to implement pthread_cleanup_push/pthread_cleanup_pop?
after_includes = """
#define PTHREAD_COND_INITIALIZER ((pthread_cond_t){0})
#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t){0})
#define PTHREAD_COND_INITIALIZER {0}
#define PTHREAD_MUTEX_INITIALIZER {0}
#define PTHREAD_RWLOCK_INITIALIZER {0}
#define PTHREAD_ONCE_INIT ((pthread_once_t){0})
#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t){0})
#define pthread_cleanup_push(ROUTINE, ARG) do { \\
struct { \\
+2
View File
@@ -15,7 +15,9 @@ after_includes = """
#include <bits/timespec.h> // for timespec
#include <bits/pthread.h> // for pthread-related types
#ifndef __cplusplus
#define thread_local _Thread_local
#endif
#define ONCE_FLAG_INIT PTHREAD_ONCE_INIT // once_flag == pthread_once_t
"""
+8 -1
View File
@@ -69,7 +69,6 @@ $(BUILD)/%.c: %.c
cp "$*.c" "$@"
FLAGS=\
-std=c11 \
-fno-builtin \
-fno-stack-protector \
-Wall \
@@ -145,6 +144,10 @@ else
endif
endif
$(BUILD)/bins_static/%_cpp: %.cpp $(DEPS)
mkdir -p "$$(dirname "$@")"
$(CC) -x c++ "$<" -x none -o "$@" $(FLAGS) $(STATIC_FLAGS)
$(BUILD)/bins_static/%: %.c $(DEPS)
mkdir -p "$$(dirname "$@")"
@$(CC) "$<" -o "$@" $(FLAGS) $(STATIC_FLAGS)
@@ -171,6 +174,10 @@ $(BUILD)/bins_dynamic/dlopen_scopes: dlopen_scopes.c $(BUILD)/bins_dynamic/libfo
mkdir -p "$$(dirname "$@")"
@$(CC) "$<" -o "$@" $(FLAGS) $(DYNAMIC_FLAGS)
$(BUILD)/bins_dynamic/%_cpp: %.cpp $(DEPS)
mkdir -p "$$(dirname "$@")"
$(CC) -x c++ "$<" -x none -o "$@" $(FLAGS) $(DYNAMIC_FLAGS)
$(BUILD)/bins_dynamic/%: %.c $(DEPS)
mkdir -p "$$(dirname "$@")"
@$(CC) "$<" -o "$@" $(FLAGS) $(DYNAMIC_FLAGS)
+2
View File
@@ -338,6 +338,8 @@ STATIC_CHECK_EXPECT_NAMES=\
args \
constructor \
destructor \
pthread/init \
pthread/init_cpp \
stdlib/env \
unistd/brk \
tls
+1
View File
@@ -0,0 +1 @@
once
+1
View File
@@ -0,0 +1 @@
once
+1
View File
@@ -0,0 +1 @@
init.cpp
+52
View File
@@ -0,0 +1,52 @@
// this file is both C and CPP to check NULL and thread_local on C++ environment
#include <stdio.h>
#include <pthread.h>
#include <stddef.h>
#include <assert.h>
#include <threads.h>
static pthread_cond_t global_cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_rwlock_t global_rwlock = PTHREAD_RWLOCK_INITIALIZER;
// TODO: POSIX mandates *_INITIALIZER as const initializer but not PTHREAD_ONCE_INIT
// But glibc and other platform support it. Ours cannot in C due to union type
#ifdef __cplusplus
static pthread_once_t global_once = PTHREAD_ONCE_INIT;
#else
static pthread_once_t global_once = {0};
#endif
static void once_callback(void) {
printf("once\n");
}
static thread_local int tls_counter = 100;
void* thread_func(void* args) {
(void)args;
assert(tls_counter == 100);
tls_counter = 200;
assert(tls_counter == 200);
return NULL;
}
int main(void) {
assert(pthread_mutex_lock(&global_mutex) == 0);
assert(pthread_mutex_unlock(&global_mutex) == 0);
assert(pthread_rwlock_wrlock(&global_rwlock) == 0);
assert(pthread_rwlock_unlock(&global_rwlock) == 0);
assert(pthread_once(&global_once, once_callback) == 0);
assert(pthread_cond_signal(&global_cond) == 0);
pthread_t thread_id;
int create_res = pthread_create(&thread_id, NULL, thread_func, NULL);
assert(create_res == 0);
pthread_mutex_t dynamic_mutex;
int mutex_res = pthread_mutex_init(&dynamic_mutex, NULL);
assert(mutex_res == 0);
assert(pthread_join(thread_id, NULL) == 0);
assert(tls_counter == 100);
return 0;
}