Fix pthread init and null for C++
This commit is contained in:
@@ -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 +1 @@
|
||||
use crate::platform::types::c_long;
|
||||
|
||||
/// Null pointer constant.
|
||||
pub const NULL: c_long = 0;
|
||||
// NULL is defined in cbindgen
|
||||
|
||||
@@ -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 { \\
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -338,6 +338,8 @@ STATIC_CHECK_EXPECT_NAMES=\
|
||||
args \
|
||||
constructor \
|
||||
destructor \
|
||||
pthread/init \
|
||||
pthread/init_cpp \
|
||||
stdlib/env \
|
||||
unistd/brk \
|
||||
tls
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
once
|
||||
@@ -0,0 +1 @@
|
||||
once
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
init.cpp
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user