option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(build_cord "Build cord library" ON)
option(build_tests "Build tests" OFF)
-option(enable_threads "TODO" OFF) #TODO Support it
+option(enable_threads "Support threads" ON)
option(enable_parallel_mark "Parallelize marking and free list construction" ON)
option(enable_thread_local_alloc "Turn on thread-local allocation optimization" ON)
option(enable_threads_discovery "Enable threads discovery in GC" ON)
endif()
include_directories(include)
-include_directories(libatomic_ops/src)
set(SRC alloc.c reclaim.c allchblk.c misc.c mach_dep.c os_dep.c
mark_rts.c headers.c mark.c obj_map.c blacklst.c finalize.c
new_hblk.c dbg_mlc.c malloc.c dyn_load.c typd_mlc.c ptr_chck.c
mallocx.c)
-set(LIBS)
+set(THREADDLLIBS)
set(_HOST ${CMAKE_SYSTEM_PROCESSOR}-unknown-${CMAKE_SYSTEM})
string(TOLOWER ${_HOST} HOST)
if (enable_threads)
find_package(Threads REQUIRED)
- message("Thread Model: ${CMAKE_THREAD_LIBS_INIT}" )
+ message(STATUS "Thread library: ${CMAKE_THREAD_LIBS_INIT}")
+ include_directories(libatomic_ops/src)
include_directories(${Threads_INCLUDE_DIR})
- set(LIBS ${LIBS} ${Threads_LIBRARIES})
-endif()
-
-#IF(Threads_FOUND)
-# ADD_DEFINITIONS("")
-#ELSE
-# MESSAGE("Parallel mark requires enable_threads ON" )
-#ENDIF(Threads_FOUND)
+ set(THREADDLLIBS ${CMAKE_THREAD_LIBS_INIT})
+ if (NOT (APPLE OR CYGWIN OR MSYS OR WIN32 OR HOST MATCHES mips-.*-irix6.*))
+ set(THREADDLLIBS ${THREADDLLIBS} -ldl)
+ # The predefined CMAKE_DL_LIBS may be broken.
+ endif()
+endif(enable_threads)
-# Thread Detection. Relying on cmake for lib and includes.
-#TODO check cmake detection
+# Thread support detection.
if (CMAKE_USE_PTHREADS_INIT)
set(SRC ${SRC} pthread_start.c pthread_support.c pthread_stop_world.c)
- # Common defines for most POSIX platforms.
- if (ANDROID OR APPLE OR CYGWIN OR MSYS OR HOST MATCHES .*-.*-aix.*|.*-.*-.*freebsd.*|.*-.*-haiku.*|.*-.*-gnu.*|.*-.*-hpux11.*|.*-.*-irix.*|.*-.*-.*linux.*|.*-.*-nacl.*|.*-.*-netbsd.*|.*-.*-openbsd.*|.*-.*-osf.*|.*-.*-solaris.*)
- add_definitions("-DGC_THREADS -D_REENTRANT")
- if (enable_parallel_mark)
- add_definitions("-DPARALLEL_MARK")
- endif()
- if (enable_thread_local_alloc)
- add_definitions("-DTHREAD_LOCAL_ALLOC")
- set(SRC ${SRC} thread_local_alloc.c)
- endif()
- message("Explicit GC_INIT() calls may be required.")
+ if (HOST MATCHES .*-.*-hpux10.*)
+ message(FATAL_ERROR "HP/UX 10 POSIX threads are not supported.")
+ endif()
+ # Assume the compiler supports C11 (GCC) atomic intrinsics.
+ add_definitions("-DGC_BUILTIN_ATOMIC")
+ # Common defines for POSIX platforms.
+ add_definitions("-DGC_THREADS -D_REENTRANT")
+ if (enable_parallel_mark)
+ add_definitions("-DPARALLEL_MARK")
endif()
+ if (enable_thread_local_alloc)
+ add_definitions("-DTHREAD_LOCAL_ALLOC")
+ set(SRC ${SRC} thread_local_alloc.c)
+ endif()
+ message("Explicit GC_INIT() calls may be required.")
if (HOST MATCHES .*-.*-hpux11.*)
message("Only HP/UX 11 POSIX threads are supported.")
add_definitions("-D_POSIX_C_SOURCE=199506L")
- #TODO test -DVAR=value. Alternative is COMPILE_DEFINITIONS property
- endif()
- if (HOST MATCHES .*-.*-hpux10.*)
- message("HP/UX 10 POSIX threads are not supported.")
- endif()
- if (HOST MATCHES .*-.*-netbsd.*)
+ elseif (HOST MATCHES .*-.*-netbsd.*)
message("Only on NetBSD 2.0 or later.")
add_definitions("-D_PTHREADS")
endif()
- if (ANDROID) # ANDROID variable is defined by CMake v3.7.0+.
+ if (ANDROID OR MSYS) # ANDROID variable is defined by CMake v3.7.0+.
# Android NDK does not provide pthread_atfork.
- elseif (CYGWIN OR HOST MATCHES .*-.*-aix.*|.*-.*-freebsd.*|.*-.*-haiku.*|.*-.*-hpux11.*|.*-.*-irix.*|.*-.*-kfreebsd.*-gnu|.*-.*-.*linux.*|.*-.*-netbsd.*|.*-.*-openbsd.*|.*-.*-osf.*|.*-.*-solaris.*)
- if (enable_handle_fork)
- add_definitions("-DHANDLE_FORK")
- endif(enable_handle_fork)
elseif (APPLE)
if (enable_handle_fork)
# The incremental mode conflicts with fork handling.
endif()
endif(enable_handle_fork)
set(SRC ${SRC} darwin_stop_world.c)
+ elseif (enable_handle_fork)
+ add_definitions("-DHANDLE_FORK")
endif()
if (enable_sigrt_signals)
add_definitions("-DGC_USESIGRT_SIGNALS")
if (CYGWIN OR MSYS)
set(SRC ${SRC} win32_threads.c)
endif()
-endif(CMAKE_USE_PTHREADS_INIT)
-
-if (CMAKE_USE_WIN32_THREADS_INIT)
+elseif (CMAKE_USE_WIN32_THREADS_INIT)
add_definitions("-DGC_THREADS")
if (enable_parallel_mark)
add_definitions("-DPARALLEL_MARK")
- if (enable_thread_local_alloc)
- add_definitions("-DTHREAD_LOCAL_ALLOC")
- set(SRC ${SRC} thread_local_alloc.c)
- endif()
- endif(enable_parallel_mark)
+ endif()
+ if (enable_thread_local_alloc AND (enable_parallel_mark OR NOT BUILD_SHARED_LIBS))
+ # Imply THREAD_LOCAL_ALLOC unless GC_DLL.
+ add_definitions("-DTHREAD_LOCAL_ALLOC")
+ set(SRC ${SRC} thread_local_alloc.c)
+ endif()
add_definitions("-DEMPTY_GETENV_RESULTS")
set(SRC ${SRC} win32_threads.c)
-endif(CMAKE_USE_WIN32_THREADS_INIT)
+elseif (CMAKE_HP_PTHREADS_INIT OR CMAKE_USE_SPROC_INIT)
+ message(FATAL_ERROR "Unsupported thread package")
+endif()
if (enable_gcj_support)
add_definitions("-DGC_GCJ_SUPPORT")
- if (enable_threads)
+ if (enable_threads AND NOT (enable_thread_local_alloc AND HOST MATCHES .*-.*-kfreebsd.*-gnu))
+ # FIXME: For a reason, gctest hangs up on kFreeBSD if both of
+ # THREAD_LOCAL_ALLOC and GC_ENABLE_SUSPEND_THREAD are defined.
add_definitions("-DGC_ENABLE_SUSPEND_THREAD")
endif()
set(SRC ${SRC} gcj_mlc.c)
endif()
add_library(gc ${SRC})
+if (enable_threads)
+ target_link_libraries(gc PRIVATE ${THREADDLLIBS})
+endif()
if (enable_cplusplus)
add_library(gccpp gc_cpp.cc)
endif(enable_cplusplus)
add_executable(gctest WIN32 tests/test.c)
- target_link_libraries(gctest PRIVATE gc)
+ target_link_libraries(gctest PRIVATE gc ${THREADDLLIBS})
add_test(NAME gctest COMMAND gctest)
if (WATCOM)
# Suppress "conditional expression in if statement is always true/false"
add_test(NAME tracetest COMMAND tracetest)
endif()
+ if (enable_threads)
+ add_executable(test_atomic_ops tests/test_atomic_ops.c)
+ target_link_libraries(test_atomic_ops PRIVATE gc)
+ add_test(NAME test_atomic_ops COMMAND test_atomic_ops)
+
+ add_executable(threadleaktest tests/thread_leak_test.c)
+ target_link_libraries(threadleaktest PRIVATE gc ${THREADDLLIBS})
+ add_test(NAME threadleaktest COMMAND threadleaktest)
+
+ if (NOT WIN32)
+ add_executable(threadkey_test tests/threadkey_test.c)
+ target_link_libraries(threadkey_test PRIVATE gc ${THREADDLLIBS})
+ add_test(NAME threadkey_test COMMAND threadkey_test)
+ endif()
+
+ add_executable(subthreadcreate_test tests/subthread_create.c)
+ target_link_libraries(subthreadcreate_test PRIVATE gc ${THREADDLLIBS})
+ add_test(NAME subthreadcreate_test COMMAND subthreadcreate_test)
+
+ add_executable(initsecondarythread_test tests/initsecondarythread.c)
+ target_link_libraries(initsecondarythread_test PRIVATE gc ${THREADDLLIBS})
+ add_test(NAME initsecondarythread_test COMMAND initsecondarythread_test)
+ endif(enable_threads)
+
if (enable_cplusplus)
add_executable(test_cpp WIN32 tests/test_cpp.cc)
target_link_libraries(test_cpp PRIVATE gc gccpp)
add_test(NAME disclaim_bench COMMAND disclaim_bench)
add_executable(disclaim_test tests/disclaim_test.c)
- target_link_libraries(disclaim_test PRIVATE gc)
+ target_link_libraries(disclaim_test PRIVATE gc ${THREADDLLIBS})
add_test(NAME disclaim_test COMMAND disclaim_test)
add_executable(disclaim_weakmap_test tests/disclaim_weakmap_test.c)
- target_link_libraries(disclaim_weakmap_test PRIVATE gc)
+ target_link_libraries(disclaim_weakmap_test PRIVATE gc ${THREADDLLIBS})
add_test(NAME disclaim_weakmap_test COMMAND disclaim_weakmap_test)
endif()
endif(build_tests)