pax_global_header00006660000000000000000000000064136752174220014523gustar00rootroot0000000000000052 comment=712e51fc50fee7c609a6ed38639288bd6030e876 nsync-1.24.0/000077500000000000000000000000001367521742200127415ustar00rootroot00000000000000nsync-1.24.0/.gitignore000066400000000000000000000000001367521742200147170ustar00rootroot00000000000000nsync-1.24.0/BUILD000066400000000000000000000616051367521742200135330ustar00rootroot00000000000000# -*- mode: python; -*- # nsync is a C library that exports synchronization primitives, such as reader # writer locks with conditional critical sections, designed to be open sourced # in portable C. See https://github.com/google/nsync # # See public/*.h for API. When compiled with C++11 rather than C, it's in the # "nsync" name space. # # BUILD file usage: # deps = "@nsync://nsync" for C version # deps = "@nsync://nsync_cpp" for C++11 version. # The latter uses no OS-specific system calls or architecture-specific atomic # operations. package(default_visibility = ["//visibility:public"]) licenses(["notice"]) # Apache 2.0 exports_files(["LICENSE", "VERSION"]) # --------------------------------------------- # Parameters to the compilation: compiler (e.g., for atomics), architecture # (e.g., for load and store barrier behaviour), and OS. # Bazel merges these into one, somewhat slippery, "cpu" string. # Bazel uses a rather verbose mechanism for choosing which implementations # are needed on given platforms; hence all the config_setting() rules below. config_setting( name = "gcc_linux_x86_32_1", values = {"cpu": "piii"}, ) config_setting( name = "gcc_linux_x86_64_1", values = {"cpu": "k8"}, ) config_setting( name = "gcc_linux_x86_64_2", values = {"cpu": "haswell"}, ) config_setting( name = "gcc_linux_aarch64", values = {"cpu": "aarch64"}, ) config_setting( name = "gcc_linux_ppc64", values = {"cpu": "ppc"}, ) config_setting( name = "gcc_linux_s390x", values = {"cpu": "s390x"}, ) config_setting( name = "clang_macos_x86_64", values = {"cpu": "darwin"}, ) config_setting( name = "android_x86_32", values = {"cpu": "x86"}, ) config_setting( name = "android_x86_64", values = {"cpu": "x86_64"}, ) config_setting( name = "android_armeabi", values = {"cpu": "armeabi"}, ) config_setting( name = "android_arm", values = {"cpu": "armeabi-v7a"}, ) config_setting( name = "android_arm64", values = {"cpu": "arm64-v8a"}, ) config_setting( name = "msvc_windows_x86_64", values = {"cpu": "x64_windows"}, ) config_setting( name = "freebsd", values = {"cpu": "freebsd"}, ) config_setting( name = "ios_x86_64", values = {"cpu": "ios_x86_64"}, ) # --------------------------------------------- # Compilation options. load(":bazel/pkg_path_name.bzl", "pkg_path_name") # Compilation options that apply to both C++11 and C. NSYNC_OPTS_GENERIC = select({ # Select the CPU architecture include directory. # This select() has no real effect in the C++11 build, but satisfies a # #include that would otherwise need a #if. ":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/x86_32"], ":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/x86_64"], ":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/x86_64"], ":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/aarch64"], ":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/ppc64"], ":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/s390x"], ":clang_macos_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"], ":freebsd": ["-I" + pkg_path_name() + "/platform/x86_64"], ":ios_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"], ":android_x86_32": ["-I" + pkg_path_name() + "/platform/x86_32"], ":android_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"], ":android_armeabi": ["-I" + pkg_path_name() + "/platform/arm"], ":android_arm": ["-I" + pkg_path_name() + "/platform/arm"], ":android_arm64": ["-I" + pkg_path_name() + "/platform/aarch64"], ":msvc_windows_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"], "//conditions:default": [], }) + [ "-I" + pkg_path_name() + "/public", "-I" + pkg_path_name() + "/internal", "-I" + pkg_path_name() + "/platform/posix", ] + select({ ":msvc_windows_x86_64": [ ], ":freebsd": ["-pthread"], "//conditions:default": [ "-D_POSIX_C_SOURCE=200809L", "-pthread", ], }) # Options for C build, rather then C++11 build. NSYNC_OPTS = select({ # Select the OS include directory. ":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/linux"], ":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/linux"], ":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/linux"], ":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/linux"], ":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/linux"], ":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/linux"], ":clang_macos_x86_64": ["-I" + pkg_path_name() + "/platform/macos"], ":freebsd": ["-I" + pkg_path_name() + "/platform/freebsd"], ":ios_x86_64": ["-I" + pkg_path_name() + "/platform/macos"], ":android_x86_32": ["-I" + pkg_path_name() + "/platform/linux"], ":android_x86_64": ["-I" + pkg_path_name() + "/platform/linux"], ":android_armeabi": ["-I" + pkg_path_name() + "/platform/linux"], ":android_arm": ["-I" + pkg_path_name() + "/platform/linux"], ":android_arm64": ["-I" + pkg_path_name() + "/platform/linux"], ":msvc_windows_x86_64": ["-I" + pkg_path_name() + "/platform/win32"], "//conditions:default": [], }) + select({ # Select the compiler include directory. ":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/gcc"], ":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/gcc"], ":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/gcc"], ":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/gcc"], ":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/gcc"], ":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/gcc"], ":clang_macos_x86_64": ["-I" + pkg_path_name() + "/platform/clang"], ":freebsd": ["-I" + pkg_path_name() + "/platform/clang"], ":ios_x86_64": ["-I" + pkg_path_name() + "/platform/clang"], ":android_x86_32": ["-I" + pkg_path_name() + "/platform/gcc"], ":android_x86_64": ["-I" + pkg_path_name() + "/platform/gcc"], ":android_armeabi": ["-I" + pkg_path_name() + "/platform/gcc"], ":android_arm": ["-I" + pkg_path_name() + "/platform/gcc"], ":android_arm64": ["-I" + pkg_path_name() + "/platform/gcc"], ":msvc_windows_x86_64": ["-I" + pkg_path_name() + "/platform/msvc"], }) + select({ # Apple deprecated their atomics library, yet recent versions have no # working version of stdatomic.h; so some recent versions need one, and # other versions prefer the other. For the moment, just ignore the # depreaction. ":clang_macos_x86_64": ["-Wno-deprecated-declarations"], "//conditions:default": [], }) + NSYNC_OPTS_GENERIC # Options for C++11 build, rather then C build. NSYNC_OPTS_CPP = select({ ":msvc_windows_x86_64": [ "/TP", ], "//conditions:default": [ "-x", "c++", "-std=c++11", ], }) + select({ # Some versions of MacOS (notably Sierra) require -D_DARWIN_C_SOURCE # to include some standard C++11 headers, like . ":clang_macos_x86_64": ["-D_DARWIN_C_SOURCE"], "//conditions:default": [], }) + select({ # On Linux, the C++11 library's synchronization primitives are # surprisingly slow. See also NSYNC_SRC_PLATFORM_CPP, below. ":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/c++11.futex"], ":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/c++11.futex"], ":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/c++11.futex"], ":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/c++11.futex"], ":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/c++11.futex"], ":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/c++11.futex"], "//conditions:default": [], }) + [ "-DNSYNC_ATOMIC_CPP11", "-DNSYNC_USE_CPP11_TIMEPOINT", "-I" + pkg_path_name() + "/platform/c++11", ] + select({ # must follow the -I...platform/c++11 ":ios_x86_64": ["-I" + pkg_path_name() + "/platform/gcc_no_tls"], ":msvc_windows_x86_64": [ "-I" + pkg_path_name() + "/platform/win32", "-I" + pkg_path_name() + "/platform/msvc", ], "//conditions:default": ["-I" + pkg_path_name() + "/platform/gcc"], }) + NSYNC_OPTS_GENERIC # Link options (for tests) built in C (rather than C++11). NSYNC_LINK_OPTS = select({ ":msvc_windows_x86_64": [], "//conditions:default": ["-pthread"], }) # Link options (for tests) built in C++11 (rather than C). NSYNC_LINK_OPTS_CPP = select({ ":msvc_windows_x86_64": [], "//conditions:default": ["-pthread"], }) # --------------------------------------------- # Header files the source may include. # Internal library headers. NSYNC_INTERNAL_HEADERS = [ "internal/common.h", "internal/dll.h", "internal/headers.h", "internal/sem.h", "internal/wait_internal.h", ] # Internal test headers. NSYNC_TEST_HEADERS = NSYNC_INTERNAL_HEADERS + [ "testing/array.h", "testing/atm_log.h", "testing/closure.h", "testing/heap.h", "testing/smprintf.h", "testing/testing.h", "testing/time_extra.h", ] # Platform specific headers. # This declares headers for all platforms, not just the one # we're building for, to avoid a more complex build file. NSYNC_INTERNAL_HEADERS_PLATFORM = [ "platform/aarch64/cputype.h", "platform/alpha/cputype.h", "platform/arm/cputype.h", "platform/atomic_ind/atomic.h", "platform/c++11/atomic.h", "platform/c++11/platform.h", "platform/c++11.futex/platform.h", "platform/c11/atomic.h", "platform/clang/atomic.h", "platform/clang/compiler.h", "platform/cygwin/platform.h", "platform/decc/compiler.h", "platform/freebsd/platform.h", "platform/gcc/atomic.h", "platform/gcc/compiler.h", "platform/gcc_new/atomic.h", "platform/gcc_new_debug/atomic.h", "platform/gcc_no_tls/compiler.h", "platform/gcc_old/atomic.h", "platform/lcc/compiler.h", "platform/lcc/nsync_time_init.h", "platform/linux/platform.h", "platform/win32/atomic.h", "platform/macos/platform_c++11_os.h", "platform/msvc/compiler.h", "platform/netbsd/atomic.h", "platform/netbsd/platform.h", "platform/openbsd/platform.h", "platform/osf1/platform.h", "platform/macos/atomic.h", "platform/macos/platform.h", "platform/pmax/cputype.h", "platform/posix/cputype.h", "platform/posix/nsync_time_init.h", "platform/posix/platform_c++11_os.h", "platform/ppc32/cputype.h", "platform/ppc64/cputype.h", "platform/s390x/cputype.h", "platform/shark/cputype.h", "platform/tcc/compiler.h", "platform/win32/platform.h", "platform/win32/platform_c++11_os.h", "platform/x86_32/cputype.h", "platform/x86_64/cputype.h", ] # --------------------------------------------- # The nsync library. # Linux-specific library source. NSYNC_SRC_LINUX = [ "platform/linux/src/nsync_semaphore_futex.c", "platform/posix/src/per_thread_waiter.c", "platform/posix/src/yield.c", "platform/posix/src/time_rep.c", "platform/posix/src/nsync_panic.c", ] # Android-specific library source. NSYNC_SRC_ANDROID = [ "platform/posix/src/nsync_semaphore_sem_t.c", "platform/posix/src/per_thread_waiter.c", "platform/posix/src/yield.c", "platform/posix/src/time_rep.c", "platform/posix/src/nsync_panic.c", ] # MacOS-specific library source. NSYNC_SRC_MACOS = [ "platform/posix/src/clock_gettime.c", "platform/posix/src/nsync_semaphore_mutex.c", "platform/posix/src/per_thread_waiter.c", "platform/posix/src/yield.c", "platform/posix/src/time_rep.c", "platform/posix/src/nsync_panic.c", ] # Windows-specific library source. NSYNC_SRC_WINDOWS = [ "platform/posix/src/nsync_panic.c", "platform/posix/src/per_thread_waiter.c", "platform/posix/src/time_rep.c", "platform/posix/src/yield.c", "platform/win32/src/clock_gettime.c", "platform/win32/src/init_callback_win32.c", "platform/win32/src/nanosleep.c", "platform/win32/src/nsync_semaphore_win32.c", "platform/win32/src/pthread_cond_timedwait_win32.c", "platform/win32/src/pthread_key_win32.cc", ] # FreeBSD-specific library source. NSYNC_SRC_FREEBSD = [ "platform/posix/src/nsync_semaphore_sem_t.c", "platform/posix/src/per_thread_waiter.c", "platform/posix/src/yield.c", "platform/posix/src/time_rep.c", "platform/posix/src/nsync_panic.c", ] # OS-specific library source. NSYNC_SRC_PLATFORM = select({ ":gcc_linux_x86_32_1": NSYNC_SRC_LINUX, ":gcc_linux_x86_64_1": NSYNC_SRC_LINUX, ":gcc_linux_x86_64_2": NSYNC_SRC_LINUX, ":gcc_linux_aarch64": NSYNC_SRC_LINUX, ":gcc_linux_ppc64": NSYNC_SRC_LINUX, ":gcc_linux_s390x": NSYNC_SRC_LINUX, ":clang_macos_x86_64": NSYNC_SRC_MACOS, ":freebsd": NSYNC_SRC_FREEBSD, ":ios_x86_64": NSYNC_SRC_MACOS, ":android_x86_32": NSYNC_SRC_ANDROID, ":android_x86_64": NSYNC_SRC_ANDROID, ":android_armeabi": NSYNC_SRC_ANDROID, ":android_arm": NSYNC_SRC_ANDROID, ":android_arm64": NSYNC_SRC_ANDROID, ":msvc_windows_x86_64": NSYNC_SRC_WINDOWS, }) # C++11-specific (OS and architecture independent) library source. NSYNC_SRC_PLATFORM_CPP = [ "platform/c++11/src/time_rep_timespec.cc", "platform/c++11/src/nsync_panic.cc", "platform/c++11/src/yield.cc", ] + select({ # On Linux, the C++11 library's synchronization primitives are surprisingly # slow, at least at the time or writing (early 2018). Raw kernel # primitives are ten times faster for wakeups. ":gcc_linux_x86_32_1": ["platform/linux/src/nsync_semaphore_futex.c"], ":gcc_linux_x86_64_1": ["platform/linux/src/nsync_semaphore_futex.c"], ":gcc_linux_x86_64_2": ["platform/linux/src/nsync_semaphore_futex.c"], ":gcc_linux_aarch64": ["platform/linux/src/nsync_semaphore_futex.c"], ":gcc_linux_ppc64": ["platform/linux/src/nsync_semaphore_futex.c"], ":gcc_linux_s390x": ["platform/linux/src/nsync_semaphore_futex.c"], "//conditions:default": ["platform/c++11/src/nsync_semaphore_mutex.cc"], }) + select({ # MacOS and Android don't have working C++11 thread local storage. ":clang_macos_x86_64": ["platform/posix/src/per_thread_waiter.c"], ":android_x86_32": ["platform/posix/src/per_thread_waiter.c"], ":android_x86_64": ["platform/posix/src/per_thread_waiter.c"], ":android_armeabi": ["platform/posix/src/per_thread_waiter.c"], ":android_arm": ["platform/posix/src/per_thread_waiter.c"], ":android_arm64": ["platform/posix/src/per_thread_waiter.c"], ":ios_x86_64": ["platform/posix/src/per_thread_waiter.c"], ":msvc_windows_x86_64": [ "platform/win32/src/clock_gettime.c", # Windows has no thread-specific data with thread-exit destructors; we # must emulate it with C++ per-thread class destructors. "platform/win32/src/pthread_key_win32.cc", "platform/win32/src/per_thread_waiter.c", ], # It's dangerous to use C++ class destructors if we can avoid it, because # nsync may be linked into the address space multiple times. "//conditions:default": ["platform/posix/src/per_thread_waiter.c"], }) # Generic library source. NSYNC_SRC_GENERIC = [ "internal/common.c", "internal/counter.c", "internal/cv.c", "internal/debug.c", "internal/dll.c", "internal/mu.c", "internal/mu_wait.c", "internal/note.c", "internal/once.c", "internal/sem_wait.c", "internal/time_internal.c", "internal/wait.c", ] # Generic library header files. NSYNC_HDR_GENERIC = [ "public/nsync.h", "public/nsync_atomic.h", "public/nsync_counter.h", "public/nsync_cpp.h", "public/nsync_cv.h", "public/nsync_debug.h", "public/nsync_mu.h", "public/nsync_mu_wait.h", "public/nsync_note.h", "public/nsync_once.h", "public/nsync_time.h", "public/nsync_time_internal.h", "public/nsync_waiter.h", ] # The library compiled in C, rather than C++11. cc_library( name = "nsync", srcs = NSYNC_SRC_GENERIC + NSYNC_SRC_PLATFORM, hdrs = NSYNC_HDR_GENERIC, copts = NSYNC_OPTS, includes = ["public"], textual_hdrs = NSYNC_INTERNAL_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM, ) # The library compiled in C++11, rather than C. cc_library( name = "nsync_cpp", srcs = NSYNC_SRC_GENERIC + NSYNC_SRC_PLATFORM_CPP, hdrs = NSYNC_HDR_GENERIC, copts = NSYNC_OPTS_CPP, includes = ["public"], textual_hdrs = NSYNC_INTERNAL_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM, ) # nsync_headers provides just the header files for use in projects that need to # build shared libraries for dynamic loading. Bazel seems unable to cope # otherwise. cc_library( name = "nsync_headers", hdrs = glob(["public/*.h"]), includes = ["public"], ) # --------------------------------------------- # Test code. # Linux-specific test library source. NSYNC_TEST_SRC_LINUX = [ "platform/posix/src/start_thread.c", ] # Android-specific test library source. NSYNC_TEST_SRC_ANDROID = [ "platform/posix/src/start_thread.c", ] # MacOS-specific test library source. NSYNC_TEST_SRC_MACOS = [ "platform/posix/src/start_thread.c", ] # Windows-specific test library source. NSYNC_TEST_SRC_WINDOWS = [ "platform/win32/src/start_thread.c", ] # FreeBSD-specific test library source. NSYNC_TEST_SRC_FREEBSD = [ "platform/posix/src/start_thread.c", ] # OS-specific test library source. NSYNC_TEST_SRC_PLATFORM = select({ ":gcc_linux_x86_32_1": NSYNC_TEST_SRC_LINUX, ":gcc_linux_x86_64_1": NSYNC_TEST_SRC_LINUX, ":gcc_linux_x86_64_2": NSYNC_TEST_SRC_LINUX, ":gcc_linux_aarch64": NSYNC_TEST_SRC_LINUX, ":gcc_linux_ppc64": NSYNC_TEST_SRC_LINUX, ":gcc_linux_s390x": NSYNC_TEST_SRC_LINUX, ":clang_macos_x86_64": NSYNC_TEST_SRC_MACOS, ":freebsd": NSYNC_TEST_SRC_FREEBSD, ":ios_x86_64": NSYNC_TEST_SRC_MACOS, ":android_x86_32": NSYNC_TEST_SRC_ANDROID, ":android_x86_64": NSYNC_TEST_SRC_ANDROID, ":android_armeabi": NSYNC_TEST_SRC_ANDROID, ":android_arm": NSYNC_TEST_SRC_ANDROID, ":android_arm64": NSYNC_TEST_SRC_ANDROID, ":msvc_windows_x86_64": NSYNC_TEST_SRC_WINDOWS, }) # C++11-specific (OS and architecture independent) test library source. NSYNC_TEST_SRC_PLATFORM_CPP = [ "platform/c++11/src/start_thread.cc", ] # Generic test library source. NSYNC_TEST_SRC_GENERIC = [ "testing/array.c", "testing/atm_log.c", "testing/closure.c", "testing/smprintf.c", "testing/testing.c", "testing/time_extra.c", ] # The test library compiled in C, rather than C++11. cc_library( name = "nsync_test_lib", testonly = 1, srcs = NSYNC_TEST_SRC_GENERIC + NSYNC_TEST_SRC_PLATFORM, hdrs = ["testing/testing.h"], copts = NSYNC_OPTS, textual_hdrs = NSYNC_TEST_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM, deps = [":nsync"], ) # The test library compiled in C++11, rather than C. cc_library( name = "nsync_test_lib_cpp", testonly = 1, srcs = NSYNC_TEST_SRC_GENERIC + NSYNC_TEST_SRC_PLATFORM_CPP, hdrs = ["testing/testing.h"], copts = NSYNC_OPTS_CPP, textual_hdrs = NSYNC_TEST_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM, deps = [":nsync_cpp"], ) # --------------------------------------------- # The tests, compiled in C rather than C++11. cc_test( name = "counter_test", size = "small", srcs = ["testing/counter_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "cv_mu_timeout_stress_test", size = "small", srcs = ["testing/cv_mu_timeout_stress_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "cv_test", size = "small", srcs = ["testing/cv_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "cv_wait_example_test", size = "small", srcs = ["testing/cv_wait_example_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "dll_test", size = "small", srcs = ["testing/dll_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "mu_starvation_test", size = "small", srcs = ["testing/mu_starvation_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "mu_test", size = "small", srcs = ["testing/mu_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "mu_wait_example_test", size = "small", srcs = ["testing/mu_wait_example_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "mu_wait_test", size = "small", srcs = ["testing/mu_wait_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "note_test", size = "small", srcs = ["testing/note_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "once_test", size = "small", srcs = ["testing/once_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "pingpong_test", size = "small", srcs = ["testing/pingpong_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "wait_test", size = "small", srcs = ["testing/wait_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) # --------------------------------------------- # The tests, compiled in C++11, rather than C. cc_test( name = "counter_cpp_test", size = "small", srcs = ["testing/counter_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "cv_mu_timeout_stress_cpp_test", size = "small", srcs = ["testing/cv_mu_timeout_stress_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "cv_cpp_test", size = "small", srcs = ["testing/cv_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "cv_wait_example_cpp_test", size = "small", srcs = ["testing/cv_wait_example_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "dll_cpp_test", size = "small", srcs = ["testing/dll_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "mu_starvation_cpp_test", size = "small", srcs = ["testing/mu_starvation_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "mu_cpp_test", size = "small", srcs = ["testing/mu_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "mu_wait_example_cpp_test", size = "small", srcs = ["testing/mu_wait_example_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "mu_wait_cpp_test", size = "small", srcs = ["testing/mu_wait_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "note_cpp_test", size = "small", srcs = ["testing/note_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "once_cpp_test", size = "small", srcs = ["testing/once_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "pingpong_cpp_test", size = "small", srcs = ["testing/pingpong_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "wait_cpp_test", size = "small", srcs = ["testing/wait_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) nsync-1.24.0/CMakeLists.txt000066400000000000000000000320741367521742200155070ustar00rootroot00000000000000cmake_minimum_required (VERSION 2.8.12) # nsync provides portable synchronization primitives, such as mutexes and # condition variables. if ("${CMAKE_MAJOR_VERSION}X" STREQUAL "2X") project (nsync) else () # fetch from VERSION file in root file (STRINGS VERSION VERSION_STRING) cmake_policy(SET CMP0048 NEW) # remove when min ver >=3 project (nsync VERSION "${VERSION_STRING}") endif () # Some builds need position-independent code. set (CMAKE_POSITION_INDEPENDENT_CODE ON) # Allow nsync users to turn the tests on or off. option (NSYNC_ENABLE_TESTS "Enable for building tests" ON) # ----------------------------------------------------------------- # Functions to set common options on targets and files. # Should be called on all targets. function (set_c_target tgtname files) if ("${CMAKE_SYSTEM_NAME}X" STREQUAL "LinuxX") target_include_directories ("${tgtname}" BEFORE PRIVATE "${PROJECT_SOURCE_DIR}/platform/linux" ) endif () endfunction (set_c_target) function (set_cpp_target tgtname files) target_include_directories ("${tgtname}" BEFORE PRIVATE "${PROJECT_SOURCE_DIR}/platform/c++11" ) if ("${CMAKE_SYSTEM_NAME}X" STREQUAL "LinuxX") target_include_directories ("${tgtname}" BEFORE PRIVATE "${PROJECT_SOURCE_DIR}/platform/c++11.futex" ) endif () target_compile_definitions ("${tgtname}" PRIVATE "${NSYNC_CPP_DEFINITIONS}") foreach (s IN ITEMS ${files}) set_source_files_properties ("${s}" PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${NSYNC_CPP_FLAGS}") endforeach (s) endfunction (set_cpp_target) # ----------------------------------------------------------------- # Platform dependencies # Many platforms use these posix related sources; even Win32. set (NSYNC_POSIX_SRC "platform/posix/src/nsync_panic.c" "platform/posix/src/per_thread_waiter.c" "platform/posix/src/time_rep.c" "platform/posix/src/yield.c" ) set (NSYNC_CPP_DEFINITIONS NSYNC_USE_CPP11_TIMEPOINT NSYNC_ATOMIC_CPP11) set (NSYNC_OS_CPP_SRC # Avoid use of the C++11 version of per_thread_waiter. It behaves # badly if multiple copies of nsync are linked into an address space. "platform/posix/src/per_thread_waiter.c" "platform/c++11/src/yield.cc" "platform/c++11/src/time_rep_timespec.cc" "platform/c++11/src/nsync_panic.cc" ) # Many of the string matches below use a literal "X" suffix on both sides. # This is because some versions of cmake treat (for example) "MSVC" (in quotes) # as a reference to the variable MSVC, thus the expression # "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC" # is false when ${CMAKE_C_COMPILER_ID} has the value "MSVC"! See # https://cmake.org/cmake/help/v3.1/policy/CMP0054.html # Pick the include directory for the operating system. if ("${CMAKE_SYSTEM_NAME}X" STREQUAL "WindowsX") include_directories ("${PROJECT_SOURCE_DIR}/platform/win32") set (NSYNC_CPP_FLAGS "/TP") set (NSYNC_OS_SRC ${NSYNC_POSIX_SRC} "platform/win32/src/clock_gettime.c" "platform/win32/src/init_callback_win32.c" "platform/win32/src/nanosleep.c" "platform/win32/src/nsync_semaphore_win32.c" "platform/win32/src/pthread_cond_timedwait_win32.c" "platform/win32/src/pthread_key_win32.cc" ) set (NSYNC_OS_CPP_SRC ${NSYNC_OS_CPP_SRC} "platform/c++11/src/nsync_semaphore_mutex.cc" "platform/win32/src/clock_gettime.c" "platform/win32/src/pthread_key_win32.cc" ) set (NSYNC_TEST_OS_SRC "platform/win32/src/start_thread.c" ) # Suppress warnings to reduce build log size. add_definitions (/wd4057 /wd4100 /wd4152 /wd4242 /wd4244 /wd4255 /wd4267) add_definitions (/wd4365 /wd4389 /wd4458 /wd4571 /wd4625 /wd4626 /wd4668) add_definitions (/wd4702 /wd4710 /wd4774 /wd4820 /wd5026 /wd5027 /wd5039) add_definitions (/wd5045) elseif ("${CMAKE_SYSTEM_NAME}X" STREQUAL "DarwinX") include_directories ("${PROJECT_SOURCE_DIR}/platform/macos") # Some versions of MacOS, such as Sierra, require _DARWIN_C_SOURCE # when including certin C++ standard header files, such as . set (NSYNC_CPP_DEFINITIONS ${NSYNC_CPP_DEFINITIONS} _DARWIN_C_SOURCE) set (NSYNC_POSIX ON) set (NSYNC_OS_EXTRA_SRC "platform/posix/src/clock_gettime.c" "platform/posix/src/nsync_semaphore_mutex.c" ) set (NSYNC_OS_CPP_SRC ${NSYNC_OS_CPP_SRC} "platform/c++11/src/nsync_semaphore_mutex.cc" "platform/posix/src/clock_gettime.c" "platform/posix/src/nsync_semaphore_mutex.c" ) elseif ("${CMAKE_SYSTEM_NAME}X" STREQUAL "LinuxX") set (NSYNC_POSIX ON) set (NSYNC_OS_EXTRA_SRC "platform/linux/src/nsync_semaphore_futex.c" ) set (NSYNC_OS_CPP_SRC "platform/linux/src/nsync_semaphore_futex.c" ${NSYNC_OS_CPP_SRC} ) elseif ("${CMAKE_SYSTEM_NAME}X" STREQUAL "NetBSDX") include_directories ("${PROJECT_SOURCE_DIR}/platform/netbsd") set (NSYNC_POSIX ON) set (NSYNC_OS_EXTRA_SRC "platform/posix/src/nsync_semaphore_mutex.c" ) set (NSYNC_OS_CPP_SRC "platform/c++11/src/nsync_semaphore_mutex.cc" ${NSYNC_OS_CPP_SRC} ) elseif ("${CMAKE_SYSTEM_NAME}X" STREQUAL "FreeBSDX") include_directories ("${PROJECT_SOURCE_DIR}/platform/freebsd") set (NSYNC_POSIX ON) set (NSYNC_OS_EXTRA_SRC "platform/posix/src/nsync_semaphore_mutex.c" ) set (NSYNC_OS_CPP_SRC "platform/c++11/src/nsync_semaphore_mutex.cc" ${NSYNC_OS_CPP_SRC} ) elseif ("${CMAKE_SYSTEM_NAME}X" STREQUAL "OpenBSDX") include_directories ("${PROJECT_SOURCE_DIR}/platform/openbsd") set (NSYNC_POSIX ON) set (NSYNC_OS_EXTRA_SRC "platform/posix/src/nsync_semaphore_mutex.c" ) set (NSYNC_OS_CPP_SRC "platform/c++11/src/nsync_semaphore_mutex.cc" ${NSYNC_OS_CPP_SRC} ) else () set (NSYNC_POSIX ON) set (NSYNC_OS_EXTRA_SRC "platform/posix/src/nsync_semaphore_mutex.c" ) set (NSYNC_OS_CPP_SRC "platform/c++11/src/nsync_semaphore_mutex.cc" ${NSYNC_OS_CPP_SRC} ) endif () # Pick the include directory for the compiler. if ("${CMAKE_C_COMPILER_ID}X" STREQUAL "GNUX") include_directories ("${PROJECT_SOURCE_DIR}/platform/gcc") set (THREADS_HAVE_PTHREAD_ARG ON) elseif ("${CMAKE_C_COMPILER_ID}X" STREQUAL "ClangX") include_directories ("${PROJECT_SOURCE_DIR}/platform/clang") set (THREADS_HAVE_PTHREAD_ARG ON) elseif ("${CMAKE_C_COMPILER_ID}X" STREQUAL "MSVCX") include_directories ("${PROJECT_SOURCE_DIR}/platform/msvc") else () message (WARNING "CMAKE_C_COMPILER_ID (${CMAKE_C_COMPILER_ID}) matched NOTHING") endif () if (NSYNC_POSIX) include_directories ("${PROJECT_SOURCE_DIR}/platform/posix") set (NSYNC_CPP_FLAGS "-std=c++11") set (NSYNC_OS_SRC ${NSYNC_POSIX_SRC} ${NSYNC_OS_EXTRA_SRC} ) set (NSYNC_TEST_OS_SRC "platform/posix/src/start_thread.c" ) endif () # Pick the include directory for the architecture. if (("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "x86_64X") OR ("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "amd64X") OR ("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "AMD64X")) include_directories ("${PROJECT_SOURCE_DIR}/platform/x86_64") elseif (("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "x86_32X") OR ("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "i386X") OR ("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "i686X")) include_directories ("${PROJECT_SOURCE_DIR}/platform/x86_32") elseif (("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "armv6lX") OR ("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "armv7lX") OR ("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "armX")) include_directories ("${PROJECT_SOURCE_DIR}/platform/arm") elseif (("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "aarch64X") OR ("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "arm64X")) include_directories ("${PROJECT_SOURCE_DIR}/platform/aarch64") elseif (("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "ppcX") OR ("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "ppc32X")) include_directories ("${PROJECT_SOURCE_DIR}/platform/ppc32") elseif (("${CMAKE_SYSTEM_PROCESSOR}X" STREQUAL "ppc64X")) include_directories ("${PROJECT_SOURCE_DIR}/platform/ppc64") endif () # Windows uses some include files from the posix directory also. if ("${CMAKE_SYSTEM_NAME}X" STREQUAL "WindowsX") include_directories ("${PROJECT_SOURCE_DIR}/platform/posix") endif () # ----------------------------------------------------------------- include_directories ("${PROJECT_SOURCE_DIR}/public") include_directories ("${PROJECT_SOURCE_DIR}/internal") include (GNUInstallDirs) set (NSYNC_COMMON_SRC "internal/common.c" "internal/counter.c" "internal/cv.c" "internal/debug.c" "internal/dll.c" "internal/mu.c" "internal/mu_wait.c" "internal/note.c" "internal/once.c" "internal/sem_wait.c" "internal/time_internal.c" "internal/wait.c" ) add_library (nsync ${NSYNC_COMMON_SRC} ${NSYNC_OS_SRC}) set_target_properties (nsync PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) set_c_target (nsync "${NSYNC_COMMON_SRC} ${NSYNC_OS_SRC}") foreach (s IN ITEMS ${NSYNC_COMMON_SRC} ${NSYNC_OS_CPP_SRC}) # The C and C++ libraries are built from the same source files but # compiled with either the C or C++ compiler. CMake normally detects # the filetype based on the extension so we need to override LANGUAGE # manually. A custom command first copies the source files (only if # changed) so the LANGUAGE property does not conflict. add_custom_command ( OUTPUT cpp/${s} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_SOURCE_DIR}/${s} cpp/${s} DEPENDS ${PROJECT_SOURCE_DIR}/${s} ) set (NSYNC_CPP_SRC_COPY ${NSYNC_CPP_SRC_COPY} cpp/${s} ) endforeach (s) add_library (nsync_cpp ${NSYNC_CPP_SRC_COPY}) set_target_properties (nsync_cpp PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) set_cpp_target (nsync_cpp "${NSYNC_CPP_SRC_COPY}") if (NSYNC_ENABLE_TESTS) set (NSYNC_TEST_SRC "testing/array.c" "testing/atm_log.c" "testing/closure.c" "testing/smprintf.c" "testing/testing.c" "testing/time_extra.c" ${NSYNC_TEST_OS_SRC} ) add_library (nsync_test ${NSYNC_TEST_SRC}) set_target_properties (nsync_test PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) set_c_target (nsync_test "${NSYNC_TEST_SRC}") target_include_directories (nsync_test PUBLIC "${PROJECT_SOURCE_DIR}/testing" ) foreach (t IN ITEMS ${NSYNC_TEST_SRC}) add_custom_command ( OUTPUT cpp/${t} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_SOURCE_DIR}/${t} cpp/${t} DEPENDS ${PROJECT_SOURCE_DIR}/${t} ) set (NSYNC_TEST_CPP_SRC "${NSYNC_TEST_CPP_SRC}" "cpp/${t}" ) endforeach (t) add_library (nsync_test_cpp ${NSYNC_TEST_CPP_SRC}) set_target_properties (nsync_test_cpp PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) set_cpp_target (nsync_test_cpp "${NSYNC_TEST_CPP_SRC}") target_include_directories (nsync_test_cpp PUBLIC "${PROJECT_SOURCE_DIR}/testing" ) # Test names should not end with _cpp set (NSYNC_TESTS "counter_test" "cv_mu_timeout_stress_test" "cv_test" "cv_wait_example_test" "dll_test" "mu_starvation_test" "mu_test" "mu_wait_example_test" "mu_wait_test" "note_test" "once_test" "pingpong_test" "wait_test" ) enable_testing () # Test targets to only run C or C++ tests add_custom_target(test_c COMMAND ${CMAKE_CTEST_COMMAND} -E '_cpp$$') add_custom_target(test_cpp COMMAND ${CMAKE_CTEST_COMMAND} -R '_cpp$$') foreach (t IN ITEMS ${NSYNC_TESTS}) add_executable (${t} "testing/${t}.c") set_c_target (${t} "testing/${t}.c") target_include_directories (${t} PUBLIC "${PROJECT_SOURCE_DIR}/testing" ) target_link_libraries (${t} nsync_test nsync) add_test (NAME ${t} COMMAND ${t}) add_dependencies (test_c ${t}) add_custom_command ( OUTPUT cpp/testing/${t}.c COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_SOURCE_DIR}/testing/${t}.c cpp/testing/${t}.c DEPENDS ${PROJECT_SOURCE_DIR}/testing/${t}.c ) set (NSYNC_TEST_CPP_SRC ${NSYNC_TEST_CPP_SRC} cpp/testing/${t}.c ) add_executable (${t}_cpp "cpp/testing/${t}.c") set_cpp_target (${t}_cpp "cpp/testing/${t}.c") target_include_directories (${t}_cpp PUBLIC "${PROJECT_SOURCE_DIR}/testing" ) target_link_libraries (${t}_cpp nsync_test_cpp nsync_cpp) add_test (NAME ${t}_cpp COMMAND ${t}_cpp) add_dependencies (test_cpp ${t}_cpp) endforeach (t) find_package (Threads REQUIRED) set (THREADS_PREFER_PTHREAD_FLAG ON) foreach (t IN ITEMS "nsync" "nsync_test" ${NSYNC_TESTS}) if (THREADS_HAVE_PTHREAD_ARG) target_compile_options (${t} PUBLIC "-pthread") target_compile_options (${t}_cpp PUBLIC "-pthread") endif () if (CMAKE_THREAD_LIBS_INIT) target_link_libraries (${t} "${CMAKE_THREAD_LIBS_INIT}") target_link_libraries (${t}_cpp "${CMAKE_THREAD_LIBS_INIT}") endif () endforeach (t) endif () set (CMAKE_SKIP_INSTALL_ALL_DEPENDENCY ON) install (TARGETS nsync LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT RuntimeLibraries ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development) install (TARGETS nsync_cpp OPTIONAL LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT RuntimeLibraries ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development) set (NSYNC_INCLUDES "public/nsync.h" "public/nsync_atomic.h" "public/nsync_counter.h" "public/nsync_cpp.h" "public/nsync_cv.h" "public/nsync_debug.h" "public/nsync_mu.h" "public/nsync_mu_wait.h" "public/nsync_note.h" "public/nsync_once.h" "public/nsync_time.h" "public/nsync_time_internal.h" "public/nsync_waiter.h" ) foreach (NSYNC_INCLUDE ${NSYNC_INCLUDES}) install (FILES ${NSYNC_INCLUDE} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT Development) endforeach () nsync-1.24.0/CONTRIBUTING000066400000000000000000000017461367521742200146030ustar00rootroot00000000000000How to contribute ----------------- Contributions to this project are welcome, especially changes that improve portability without reducing readability. Contributor License Agreement ----------------------------- Contributions to this project must be accompanied by a Contributor License Agreement. You (or your employer) retain the copyright to your contribution, this simply gives us permission to use and redistribute your contributions as part of the project. Visit https://cla.developers.google.com/ to see your current agreements on file or to sign a new one. You generally only need to submit a CLA once, so if you've already submitted one (even if it was for a different project), you probably don't need to do it again. Code reviews ------------ All submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose. Consult https://help.github.com/articles/about-pull-requests/ for more information on using pull requests. nsync-1.24.0/LICENSE000066400000000000000000000261361367521742200137560ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. nsync-1.24.0/README000066400000000000000000000233221367521742200136230ustar00rootroot00000000000000nsync is a C library that exports various synchronization primitives: locks condition variables run-once initialization waitable counter (useful for barriers) waitable bit (useful for cancellation, or other conditions) It is not an offical Google product. nsync may be desirable in place of pthread primitives in some cases: - nsync locks are reader-writer locks (but are as efficient as mutexes). - nsync locks and condition variables occupy only two words each. - nsync works on Unix-like systems and Windows. It should be portable to other platforms straightforwardly. - nsync provides conditional critical sections. These fill the same role as condition variables, but are usually easier to use, and in most common cases are comparable in speed. They can be easier to use in two ways: - it's not necessary to surround the "wait" operation in a while loop; instead the condition is passed to the call as a function and arbitrary pointer argument. - it's not necessary to wake or signal explicitly when the condition(s) become true; they are checked automatically. The primary downsides are: - they are not available in most other common synchronization APIs, and so they may be unfamiliar (even though they date back to the 1960s), and - if threads routinely wait on many distinct, false conditions associated with the same lock, they may be slower than condition variables. In this case, clients can use condition variables in the normal way; conditional critical sections and condition variables can be used with the same lock. - nsync waits can be cancelled via an object passed to the wait calls, unlike the pthread model in which threads are cancelled. This difference can be useful if the computation needs multiple threads, or if cancellation affects only sub-operations within a larger operation by the thread. See the section "Extensions to locks and condition variables" below. Portability =========== The library is intended to be portable, and to be compilable on a system with only a C90 compiler, assuming atomic operations are available from the compiler, operating system, or assembler routines. It is able to use C11 or C++11 atomic operations if they are available. It can be compiled with a C++ compiler, and in its own C++ name space, if desired, though no attempt has been made to present a class-based interface. Building ======== The builds/ directory may already contain a subdirectory that matches your platform. For example, if you're on an x86_64, running Linux, using gcc, you might pick "x86_64.linux.gcc". If there is an appropriate subdirectory, in that subdirectory type: make depend test which will calculate dependencies, build the library and its tests, and then run them. (On Windows, using Visual Studio ("x86_64.win32.msvc") use "nmake" instead of "make".) If there is no suitable subdirectory, on most Unix-like systems you can create one with tools/mkmakefile.sh The main reason it might fail is if it cannot find a suitable implementation of atomic operations on the platform. Atomic operations may be provided by - compiler-dependent interfaces (currently, gcc and clang) These are auto detected by mkmakefile.sh. - language-specific standards (currently, C11 and C++11) Selected in mkmakefile.sh via "-atomic c11" or "-atomic c++11". - operating system-dependent libraries (e.g., NetBSD, MacOS, Windows) Selected in mkmakefile.sh via "-atomic os". - architecture-dependent libraries (e.g., x86_64, x86_32, aarch64, arm, mips, alpha) Selected in mkmakefile.sh via "-atomic asm"; file should be named platforms//src/nsync_atm_.[csS] to be found by mkmakefile.sh. If none of these match your platform, you may need to provide an assembly language implementation. Other possible issues: - Some platforms put clock_gettime() in the realtime library. Give "-lrt" to mkmakefile.sh. - The version identifier of "clang" can vary by installation, and so it may not be identified if invoked as "cc". Give "-cc clang" to mkmakefile.sh, if clang is not detected automatically. - Some CPU architectures have many variants, making it difficult to rely on a single identifier. Give "-arch " to mkmakefile.sh to specify a particular string. mkmakefile.sh recognises a couple of special cases: - MacOS doesn't provide clock_gettime(); a compatibility routine is found in platform/posix/src/clock_gettime.c See builds/x86_64.macos.clang/Makefile - OpenBSD and Irix do not provide thread-local storage, which is accommodated by adding -I../../platform/gcc_no_tls to the include path. See, for example, builds/x86_64.openbsd.gcc/Makefile. Further customization is possible by editing the Makefile, directly. For Unix-like systems is typically only a few lines long. For example, compare builds/x86_64.linux.g++/Makefile with builds/x86_64.linux.gcc/Makefile to see how to compile the entire library in C++, rather than C. CMake ----- CMake can also be used to build: $ mkdir out $ cd out/ $ cmake .. $ make $ make install The C library will be called libnsync and C++ is libnsync_cpp. Tests can be disabled with the CMake option: -DNSYNC_ENABLE_TESTS=0. To build shared libraries instead of static use: -DBUILD_SHARED_LIBS=ON. CMake version >= 3.0 is strongly recommended. Code structure ============== public/ Public header files for library. builds/*/ Platform-dependent build directories, each with Makefile. internal/ Platform-independent library source code, and Makefile fragment. platform/*/ Platform-dependent source code. testing/ Platform-independent testing source code is in "testing". tools/ Optional tools that can be used to create Makefile dependencies and run tests. Where possible, the code avoids conditional compilation (#if, etc.), to avoid becoming a mess of C-preprocessor directives. The platform-dependent Makefiles set the appropriate include paths and specify platform-dependent modules where needed. The build directories of the various platforms are kept separate to allow multiple platforms to be accommodated in one shared file system. Differences from pthread locks and condition variables ====================================================== Conditional critical sections ----------------------------- Consider the following use of a condition variable: /* variable declarations */ nsync_mu mu = NSYNC_MU_INIT; /* protects i */ int i = 1; nsync_cv cv = NSYNC_CV_INIT; /* signalled when i reaches 0 */ ... /* Waiter */ nsync_mu_lock (&mu); while (i != 0) { nsync_cv_wait (&cv, &mu); } /* i is zero ... */ nsync_mu_unlock (&mu); ... /* Decrementer */ nsync_mu_lock (&mu) i--; if (i == 0) { nsync_cv_broadcast (&cv); } nsync_mu_unlock (&mu); With conditional critical sections, the equivalent is: /* variable declarations */ nsync_mu mu = NSYNC_MU_INIT; /* protects i */ int i = 1; /* Condition */ int int_is_zero (void *v) { return (*(int *)v == 0); } ... /* Waiter */ nsync_mu_lock (&mu); nsync_mu_wait (&mu, &int_is_zero, &i) /* i is zero ... */ nsync_mu_unlock (&mu); ... /* Decrementer */ nsync_mu_lock (&mu) i--; nsync_mu_unlock (&mu); For the cost of writing a function that evaluates the desired condition, the waiter's while-loop, and the decrementer's signalling are handled by the implementation. In most cases, this makes code easier to write and debug. The primary cost is that the implementation must check whether any waiters' conditions have become true when releasing the lock. This cost becomes most noticable when threads wait on many distinct, false conditions. In such cases, some or all of the conditions can be converted to use condition variables and explicit signalling. C++ users may be tempted to wrap this functionality in a way that uses lambda expressions for the conditions. This will work, but may be less efficient, because C++ does not provide a means to detect whether two lambda expressions evaluate the same function. This may force the implementation to evaluate the same false condition many more times than it otherwise might. Reader/writer locks ------------------- There is no particular reason why a reader/writer lock need be significantly slower than a simple mutex. In both cases, the lock can be acquired or released with a single atomic read-modify-write sequence. Thus, the type nsync_mu is a reader/writer lock. Locks with reader-sections can be used with condition variables and conditional critical sections without affecting correctness. Cancellation ------------ The pthread API allows the cancellation of individual threads, and once a thread has been cancelled, it is expected to terminate soon. This can work well in some cases, but may not be convenient if an activity is associated with many threads, or if threads routinely act on behalf of multiple activities. In nsync, cancellation involves an object separate from the thread, called an nsync_note. An nsync_note is conceptually a boolean that makes a single transition from false to true: it starts off "unnotified", can be notified: - by an explicit nsync_note_notify() call, - due to a timeout, or - due to the transition of an optional parent nsync_note. So, for example, in a network server, a request with a deadline might have an nsync_note associated with it. Activities associated with that request might each have a child nsync_note, possibly with shorter deadlines. A cancellation request from the original caller might cancel the parent, which would cancel all the children. The calls nsync_cv_wait_with_deadline() and nsync_mu_wait_with_deadline() take both a deadline and a pointer to an nsync_note, and will wake when the awaited condition becomes true, when the deadline (if any) expires, or when the nsync_note becomes notified. The return value indicates which of these occurred. nsync-1.24.0/VERSION000066400000000000000000000000071367521742200140060ustar00rootroot000000000000001.24.0 nsync-1.24.0/WORKSPACE000066400000000000000000000000001367521742200142100ustar00rootroot00000000000000nsync-1.24.0/bazel/000077500000000000000000000000001367521742200140365ustar00rootroot00000000000000nsync-1.24.0/bazel/bazel_BUILD000066400000000000000000000616051367521742200160050ustar00rootroot00000000000000# -*- mode: python; -*- # nsync is a C library that exports synchronization primitives, such as reader # writer locks with conditional critical sections, designed to be open sourced # in portable C. See https://github.com/google/nsync # # See public/*.h for API. When compiled with C++11 rather than C, it's in the # "nsync" name space. # # BUILD file usage: # deps = "@nsync://nsync" for C version # deps = "@nsync://nsync_cpp" for C++11 version. # The latter uses no OS-specific system calls or architecture-specific atomic # operations. package(default_visibility = ["//visibility:public"]) licenses(["notice"]) # Apache 2.0 exports_files(["LICENSE", "VERSION"]) # --------------------------------------------- # Parameters to the compilation: compiler (e.g., for atomics), architecture # (e.g., for load and store barrier behaviour), and OS. # Bazel merges these into one, somewhat slippery, "cpu" string. # Bazel uses a rather verbose mechanism for choosing which implementations # are needed on given platforms; hence all the config_setting() rules below. config_setting( name = "gcc_linux_x86_32_1", values = {"cpu": "piii"}, ) config_setting( name = "gcc_linux_x86_64_1", values = {"cpu": "k8"}, ) config_setting( name = "gcc_linux_x86_64_2", values = {"cpu": "haswell"}, ) config_setting( name = "gcc_linux_aarch64", values = {"cpu": "aarch64"}, ) config_setting( name = "gcc_linux_ppc64", values = {"cpu": "ppc"}, ) config_setting( name = "gcc_linux_s390x", values = {"cpu": "s390x"}, ) config_setting( name = "clang_macos_x86_64", values = {"cpu": "darwin"}, ) config_setting( name = "android_x86_32", values = {"cpu": "x86"}, ) config_setting( name = "android_x86_64", values = {"cpu": "x86_64"}, ) config_setting( name = "android_armeabi", values = {"cpu": "armeabi"}, ) config_setting( name = "android_arm", values = {"cpu": "armeabi-v7a"}, ) config_setting( name = "android_arm64", values = {"cpu": "arm64-v8a"}, ) config_setting( name = "msvc_windows_x86_64", values = {"cpu": "x64_windows"}, ) config_setting( name = "freebsd", values = {"cpu": "freebsd"}, ) config_setting( name = "ios_x86_64", values = {"cpu": "ios_x86_64"}, ) # --------------------------------------------- # Compilation options. load(":bazel/pkg_path_name.bzl", "pkg_path_name") # Compilation options that apply to both C++11 and C. NSYNC_OPTS_GENERIC = select({ # Select the CPU architecture include directory. # This select() has no real effect in the C++11 build, but satisfies a # #include that would otherwise need a #if. ":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/x86_32"], ":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/x86_64"], ":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/x86_64"], ":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/aarch64"], ":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/ppc64"], ":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/s390x"], ":clang_macos_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"], ":freebsd": ["-I" + pkg_path_name() + "/platform/x86_64"], ":ios_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"], ":android_x86_32": ["-I" + pkg_path_name() + "/platform/x86_32"], ":android_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"], ":android_armeabi": ["-I" + pkg_path_name() + "/platform/arm"], ":android_arm": ["-I" + pkg_path_name() + "/platform/arm"], ":android_arm64": ["-I" + pkg_path_name() + "/platform/aarch64"], ":msvc_windows_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"], "//conditions:default": [], }) + [ "-I" + pkg_path_name() + "/public", "-I" + pkg_path_name() + "/internal", "-I" + pkg_path_name() + "/platform/posix", ] + select({ ":msvc_windows_x86_64": [ ], ":freebsd": ["-pthread"], "//conditions:default": [ "-D_POSIX_C_SOURCE=200809L", "-pthread", ], }) # Options for C build, rather then C++11 build. NSYNC_OPTS = select({ # Select the OS include directory. ":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/linux"], ":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/linux"], ":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/linux"], ":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/linux"], ":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/linux"], ":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/linux"], ":clang_macos_x86_64": ["-I" + pkg_path_name() + "/platform/macos"], ":freebsd": ["-I" + pkg_path_name() + "/platform/freebsd"], ":ios_x86_64": ["-I" + pkg_path_name() + "/platform/macos"], ":android_x86_32": ["-I" + pkg_path_name() + "/platform/linux"], ":android_x86_64": ["-I" + pkg_path_name() + "/platform/linux"], ":android_armeabi": ["-I" + pkg_path_name() + "/platform/linux"], ":android_arm": ["-I" + pkg_path_name() + "/platform/linux"], ":android_arm64": ["-I" + pkg_path_name() + "/platform/linux"], ":msvc_windows_x86_64": ["-I" + pkg_path_name() + "/platform/win32"], "//conditions:default": [], }) + select({ # Select the compiler include directory. ":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/gcc"], ":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/gcc"], ":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/gcc"], ":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/gcc"], ":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/gcc"], ":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/gcc"], ":clang_macos_x86_64": ["-I" + pkg_path_name() + "/platform/clang"], ":freebsd": ["-I" + pkg_path_name() + "/platform/clang"], ":ios_x86_64": ["-I" + pkg_path_name() + "/platform/clang"], ":android_x86_32": ["-I" + pkg_path_name() + "/platform/gcc"], ":android_x86_64": ["-I" + pkg_path_name() + "/platform/gcc"], ":android_armeabi": ["-I" + pkg_path_name() + "/platform/gcc"], ":android_arm": ["-I" + pkg_path_name() + "/platform/gcc"], ":android_arm64": ["-I" + pkg_path_name() + "/platform/gcc"], ":msvc_windows_x86_64": ["-I" + pkg_path_name() + "/platform/msvc"], }) + select({ # Apple deprecated their atomics library, yet recent versions have no # working version of stdatomic.h; so some recent versions need one, and # other versions prefer the other. For the moment, just ignore the # depreaction. ":clang_macos_x86_64": ["-Wno-deprecated-declarations"], "//conditions:default": [], }) + NSYNC_OPTS_GENERIC # Options for C++11 build, rather then C build. NSYNC_OPTS_CPP = select({ ":msvc_windows_x86_64": [ "/TP", ], "//conditions:default": [ "-x", "c++", "-std=c++11", ], }) + select({ # Some versions of MacOS (notably Sierra) require -D_DARWIN_C_SOURCE # to include some standard C++11 headers, like . ":clang_macos_x86_64": ["-D_DARWIN_C_SOURCE"], "//conditions:default": [], }) + select({ # On Linux, the C++11 library's synchronization primitives are # surprisingly slow. See also NSYNC_SRC_PLATFORM_CPP, below. ":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/c++11.futex"], ":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/c++11.futex"], ":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/c++11.futex"], ":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/c++11.futex"], ":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/c++11.futex"], ":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/c++11.futex"], "//conditions:default": [], }) + [ "-DNSYNC_ATOMIC_CPP11", "-DNSYNC_USE_CPP11_TIMEPOINT", "-I" + pkg_path_name() + "/platform/c++11", ] + select({ # must follow the -I...platform/c++11 ":ios_x86_64": ["-I" + pkg_path_name() + "/platform/gcc_no_tls"], ":msvc_windows_x86_64": [ "-I" + pkg_path_name() + "/platform/win32", "-I" + pkg_path_name() + "/platform/msvc", ], "//conditions:default": ["-I" + pkg_path_name() + "/platform/gcc"], }) + NSYNC_OPTS_GENERIC # Link options (for tests) built in C (rather than C++11). NSYNC_LINK_OPTS = select({ ":msvc_windows_x86_64": [], "//conditions:default": ["-pthread"], }) # Link options (for tests) built in C++11 (rather than C). NSYNC_LINK_OPTS_CPP = select({ ":msvc_windows_x86_64": [], "//conditions:default": ["-pthread"], }) # --------------------------------------------- # Header files the source may include. # Internal library headers. NSYNC_INTERNAL_HEADERS = [ "internal/common.h", "internal/dll.h", "internal/headers.h", "internal/sem.h", "internal/wait_internal.h", ] # Internal test headers. NSYNC_TEST_HEADERS = NSYNC_INTERNAL_HEADERS + [ "testing/array.h", "testing/atm_log.h", "testing/closure.h", "testing/heap.h", "testing/smprintf.h", "testing/testing.h", "testing/time_extra.h", ] # Platform specific headers. # This declares headers for all platforms, not just the one # we're building for, to avoid a more complex build file. NSYNC_INTERNAL_HEADERS_PLATFORM = [ "platform/aarch64/cputype.h", "platform/alpha/cputype.h", "platform/arm/cputype.h", "platform/atomic_ind/atomic.h", "platform/c++11/atomic.h", "platform/c++11/platform.h", "platform/c++11.futex/platform.h", "platform/c11/atomic.h", "platform/clang/atomic.h", "platform/clang/compiler.h", "platform/cygwin/platform.h", "platform/decc/compiler.h", "platform/freebsd/platform.h", "platform/gcc/atomic.h", "platform/gcc/compiler.h", "platform/gcc_new/atomic.h", "platform/gcc_new_debug/atomic.h", "platform/gcc_no_tls/compiler.h", "platform/gcc_old/atomic.h", "platform/lcc/compiler.h", "platform/lcc/nsync_time_init.h", "platform/linux/platform.h", "platform/win32/atomic.h", "platform/macos/platform_c++11_os.h", "platform/msvc/compiler.h", "platform/netbsd/atomic.h", "platform/netbsd/platform.h", "platform/openbsd/platform.h", "platform/osf1/platform.h", "platform/macos/atomic.h", "platform/macos/platform.h", "platform/pmax/cputype.h", "platform/posix/cputype.h", "platform/posix/nsync_time_init.h", "platform/posix/platform_c++11_os.h", "platform/ppc32/cputype.h", "platform/ppc64/cputype.h", "platform/s390x/cputype.h", "platform/shark/cputype.h", "platform/tcc/compiler.h", "platform/win32/platform.h", "platform/win32/platform_c++11_os.h", "platform/x86_32/cputype.h", "platform/x86_64/cputype.h", ] # --------------------------------------------- # The nsync library. # Linux-specific library source. NSYNC_SRC_LINUX = [ "platform/linux/src/nsync_semaphore_futex.c", "platform/posix/src/per_thread_waiter.c", "platform/posix/src/yield.c", "platform/posix/src/time_rep.c", "platform/posix/src/nsync_panic.c", ] # Android-specific library source. NSYNC_SRC_ANDROID = [ "platform/posix/src/nsync_semaphore_sem_t.c", "platform/posix/src/per_thread_waiter.c", "platform/posix/src/yield.c", "platform/posix/src/time_rep.c", "platform/posix/src/nsync_panic.c", ] # MacOS-specific library source. NSYNC_SRC_MACOS = [ "platform/posix/src/clock_gettime.c", "platform/posix/src/nsync_semaphore_mutex.c", "platform/posix/src/per_thread_waiter.c", "platform/posix/src/yield.c", "platform/posix/src/time_rep.c", "platform/posix/src/nsync_panic.c", ] # Windows-specific library source. NSYNC_SRC_WINDOWS = [ "platform/posix/src/nsync_panic.c", "platform/posix/src/per_thread_waiter.c", "platform/posix/src/time_rep.c", "platform/posix/src/yield.c", "platform/win32/src/clock_gettime.c", "platform/win32/src/init_callback_win32.c", "platform/win32/src/nanosleep.c", "platform/win32/src/nsync_semaphore_win32.c", "platform/win32/src/pthread_cond_timedwait_win32.c", "platform/win32/src/pthread_key_win32.cc", ] # FreeBSD-specific library source. NSYNC_SRC_FREEBSD = [ "platform/posix/src/nsync_semaphore_sem_t.c", "platform/posix/src/per_thread_waiter.c", "platform/posix/src/yield.c", "platform/posix/src/time_rep.c", "platform/posix/src/nsync_panic.c", ] # OS-specific library source. NSYNC_SRC_PLATFORM = select({ ":gcc_linux_x86_32_1": NSYNC_SRC_LINUX, ":gcc_linux_x86_64_1": NSYNC_SRC_LINUX, ":gcc_linux_x86_64_2": NSYNC_SRC_LINUX, ":gcc_linux_aarch64": NSYNC_SRC_LINUX, ":gcc_linux_ppc64": NSYNC_SRC_LINUX, ":gcc_linux_s390x": NSYNC_SRC_LINUX, ":clang_macos_x86_64": NSYNC_SRC_MACOS, ":freebsd": NSYNC_SRC_FREEBSD, ":ios_x86_64": NSYNC_SRC_MACOS, ":android_x86_32": NSYNC_SRC_ANDROID, ":android_x86_64": NSYNC_SRC_ANDROID, ":android_armeabi": NSYNC_SRC_ANDROID, ":android_arm": NSYNC_SRC_ANDROID, ":android_arm64": NSYNC_SRC_ANDROID, ":msvc_windows_x86_64": NSYNC_SRC_WINDOWS, }) # C++11-specific (OS and architecture independent) library source. NSYNC_SRC_PLATFORM_CPP = [ "platform/c++11/src/time_rep_timespec.cc", "platform/c++11/src/nsync_panic.cc", "platform/c++11/src/yield.cc", ] + select({ # On Linux, the C++11 library's synchronization primitives are surprisingly # slow, at least at the time or writing (early 2018). Raw kernel # primitives are ten times faster for wakeups. ":gcc_linux_x86_32_1": ["platform/linux/src/nsync_semaphore_futex.c"], ":gcc_linux_x86_64_1": ["platform/linux/src/nsync_semaphore_futex.c"], ":gcc_linux_x86_64_2": ["platform/linux/src/nsync_semaphore_futex.c"], ":gcc_linux_aarch64": ["platform/linux/src/nsync_semaphore_futex.c"], ":gcc_linux_ppc64": ["platform/linux/src/nsync_semaphore_futex.c"], ":gcc_linux_s390x": ["platform/linux/src/nsync_semaphore_futex.c"], "//conditions:default": ["platform/c++11/src/nsync_semaphore_mutex.cc"], }) + select({ # MacOS and Android don't have working C++11 thread local storage. ":clang_macos_x86_64": ["platform/posix/src/per_thread_waiter.c"], ":android_x86_32": ["platform/posix/src/per_thread_waiter.c"], ":android_x86_64": ["platform/posix/src/per_thread_waiter.c"], ":android_armeabi": ["platform/posix/src/per_thread_waiter.c"], ":android_arm": ["platform/posix/src/per_thread_waiter.c"], ":android_arm64": ["platform/posix/src/per_thread_waiter.c"], ":ios_x86_64": ["platform/posix/src/per_thread_waiter.c"], ":msvc_windows_x86_64": [ "platform/win32/src/clock_gettime.c", # Windows has no thread-specific data with thread-exit destructors; we # must emulate it with C++ per-thread class destructors. "platform/win32/src/pthread_key_win32.cc", "platform/win32/src/per_thread_waiter.c", ], # It's dangerous to use C++ class destructors if we can avoid it, because # nsync may be linked into the address space multiple times. "//conditions:default": ["platform/posix/src/per_thread_waiter.c"], }) # Generic library source. NSYNC_SRC_GENERIC = [ "internal/common.c", "internal/counter.c", "internal/cv.c", "internal/debug.c", "internal/dll.c", "internal/mu.c", "internal/mu_wait.c", "internal/note.c", "internal/once.c", "internal/sem_wait.c", "internal/time_internal.c", "internal/wait.c", ] # Generic library header files. NSYNC_HDR_GENERIC = [ "public/nsync.h", "public/nsync_atomic.h", "public/nsync_counter.h", "public/nsync_cpp.h", "public/nsync_cv.h", "public/nsync_debug.h", "public/nsync_mu.h", "public/nsync_mu_wait.h", "public/nsync_note.h", "public/nsync_once.h", "public/nsync_time.h", "public/nsync_time_internal.h", "public/nsync_waiter.h", ] # The library compiled in C, rather than C++11. cc_library( name = "nsync", srcs = NSYNC_SRC_GENERIC + NSYNC_SRC_PLATFORM, hdrs = NSYNC_HDR_GENERIC, copts = NSYNC_OPTS, includes = ["public"], textual_hdrs = NSYNC_INTERNAL_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM, ) # The library compiled in C++11, rather than C. cc_library( name = "nsync_cpp", srcs = NSYNC_SRC_GENERIC + NSYNC_SRC_PLATFORM_CPP, hdrs = NSYNC_HDR_GENERIC, copts = NSYNC_OPTS_CPP, includes = ["public"], textual_hdrs = NSYNC_INTERNAL_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM, ) # nsync_headers provides just the header files for use in projects that need to # build shared libraries for dynamic loading. Bazel seems unable to cope # otherwise. cc_library( name = "nsync_headers", hdrs = glob(["public/*.h"]), includes = ["public"], ) # --------------------------------------------- # Test code. # Linux-specific test library source. NSYNC_TEST_SRC_LINUX = [ "platform/posix/src/start_thread.c", ] # Android-specific test library source. NSYNC_TEST_SRC_ANDROID = [ "platform/posix/src/start_thread.c", ] # MacOS-specific test library source. NSYNC_TEST_SRC_MACOS = [ "platform/posix/src/start_thread.c", ] # Windows-specific test library source. NSYNC_TEST_SRC_WINDOWS = [ "platform/win32/src/start_thread.c", ] # FreeBSD-specific test library source. NSYNC_TEST_SRC_FREEBSD = [ "platform/posix/src/start_thread.c", ] # OS-specific test library source. NSYNC_TEST_SRC_PLATFORM = select({ ":gcc_linux_x86_32_1": NSYNC_TEST_SRC_LINUX, ":gcc_linux_x86_64_1": NSYNC_TEST_SRC_LINUX, ":gcc_linux_x86_64_2": NSYNC_TEST_SRC_LINUX, ":gcc_linux_aarch64": NSYNC_TEST_SRC_LINUX, ":gcc_linux_ppc64": NSYNC_TEST_SRC_LINUX, ":gcc_linux_s390x": NSYNC_TEST_SRC_LINUX, ":clang_macos_x86_64": NSYNC_TEST_SRC_MACOS, ":freebsd": NSYNC_TEST_SRC_FREEBSD, ":ios_x86_64": NSYNC_TEST_SRC_MACOS, ":android_x86_32": NSYNC_TEST_SRC_ANDROID, ":android_x86_64": NSYNC_TEST_SRC_ANDROID, ":android_armeabi": NSYNC_TEST_SRC_ANDROID, ":android_arm": NSYNC_TEST_SRC_ANDROID, ":android_arm64": NSYNC_TEST_SRC_ANDROID, ":msvc_windows_x86_64": NSYNC_TEST_SRC_WINDOWS, }) # C++11-specific (OS and architecture independent) test library source. NSYNC_TEST_SRC_PLATFORM_CPP = [ "platform/c++11/src/start_thread.cc", ] # Generic test library source. NSYNC_TEST_SRC_GENERIC = [ "testing/array.c", "testing/atm_log.c", "testing/closure.c", "testing/smprintf.c", "testing/testing.c", "testing/time_extra.c", ] # The test library compiled in C, rather than C++11. cc_library( name = "nsync_test_lib", testonly = 1, srcs = NSYNC_TEST_SRC_GENERIC + NSYNC_TEST_SRC_PLATFORM, hdrs = ["testing/testing.h"], copts = NSYNC_OPTS, textual_hdrs = NSYNC_TEST_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM, deps = [":nsync"], ) # The test library compiled in C++11, rather than C. cc_library( name = "nsync_test_lib_cpp", testonly = 1, srcs = NSYNC_TEST_SRC_GENERIC + NSYNC_TEST_SRC_PLATFORM_CPP, hdrs = ["testing/testing.h"], copts = NSYNC_OPTS_CPP, textual_hdrs = NSYNC_TEST_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM, deps = [":nsync_cpp"], ) # --------------------------------------------- # The tests, compiled in C rather than C++11. cc_test( name = "counter_test", size = "small", srcs = ["testing/counter_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "cv_mu_timeout_stress_test", size = "small", srcs = ["testing/cv_mu_timeout_stress_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "cv_test", size = "small", srcs = ["testing/cv_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "cv_wait_example_test", size = "small", srcs = ["testing/cv_wait_example_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "dll_test", size = "small", srcs = ["testing/dll_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "mu_starvation_test", size = "small", srcs = ["testing/mu_starvation_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "mu_test", size = "small", srcs = ["testing/mu_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "mu_wait_example_test", size = "small", srcs = ["testing/mu_wait_example_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "mu_wait_test", size = "small", srcs = ["testing/mu_wait_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "note_test", size = "small", srcs = ["testing/note_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "once_test", size = "small", srcs = ["testing/once_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "pingpong_test", size = "small", srcs = ["testing/pingpong_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) cc_test( name = "wait_test", size = "small", srcs = ["testing/wait_test.c"], copts = NSYNC_OPTS, linkopts = NSYNC_LINK_OPTS, deps = [ ":nsync", ":nsync_test_lib", ], ) # --------------------------------------------- # The tests, compiled in C++11, rather than C. cc_test( name = "counter_cpp_test", size = "small", srcs = ["testing/counter_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "cv_mu_timeout_stress_cpp_test", size = "small", srcs = ["testing/cv_mu_timeout_stress_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "cv_cpp_test", size = "small", srcs = ["testing/cv_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "cv_wait_example_cpp_test", size = "small", srcs = ["testing/cv_wait_example_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "dll_cpp_test", size = "small", srcs = ["testing/dll_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "mu_starvation_cpp_test", size = "small", srcs = ["testing/mu_starvation_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "mu_cpp_test", size = "small", srcs = ["testing/mu_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "mu_wait_example_cpp_test", size = "small", srcs = ["testing/mu_wait_example_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "mu_wait_cpp_test", size = "small", srcs = ["testing/mu_wait_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "note_cpp_test", size = "small", srcs = ["testing/note_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "once_cpp_test", size = "small", srcs = ["testing/once_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "pingpong_cpp_test", size = "small", srcs = ["testing/pingpong_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) cc_test( name = "wait_cpp_test", size = "small", srcs = ["testing/wait_test.c"], copts = NSYNC_OPTS_CPP, linkopts = NSYNC_LINK_OPTS_CPP, deps = [ ":nsync_cpp", ":nsync_test_lib_cpp", ], ) nsync-1.24.0/bazel/pkg_path_name.bzl000066400000000000000000000006201367521742200173420ustar00rootroot00000000000000# -*- mode: python; -*- # Return the pathname of the calling package. # (This is used to recover the directory name to pass to cc -I, when # choosing from among alternative header files for different platforms.) def pkg_path_name(): return "./" + Label(native.repository_name() + "//" + native.package_name() + ":nsync").workspace_root + "/" + native.package_name() nsync-1.24.0/builds/000077500000000000000000000000001367521742200142235ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.c++11/000077500000000000000000000000001367521742200173225ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.c++11/Makefile000066400000000000000000000024771367521742200207740ustar00rootroot00000000000000# On Linux, wakeups from C++11 condition variables are surprisingly slow, so we # use futex directly. CC=g++ PLATFORM_CPPFLAGS=-DNSYNC_USE_CPP11_TIMEPOINT -DNSYNC_ATOMIC_CPP11 -I../../platform/c++11.futex -I../../platform/c++11 -I../../platform/gcc -I../../platform/posix -pthread PLATFORM_CFLAGS=-std=c++11 -Werror -Wall -Wextra -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M -std=c++11 # It's dangerous to use C++ class destructors if we can avoid it, because nsync # may be linked into the address space multiple times, so we use the posix # per_thread_waiter. PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/c++11/src/yield.cc ../../platform/c++11/src/time_rep_timespec.cc ../../platform/c++11/src/nsync_panic.cc PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep_timespec.o nsync_panic.o TEST_PLATFORM_C=../../platform/c++11/src/start_thread.cc TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile time_rep_timespec_test.o: ../../platform/c++11/src/time_rep_timespec_test.cc; ${CC} ${CFLAGS} -I../../testing -c ../../platform/c++11/src/time_rep_timespec_test.cc time_rep_timespec_test: time_rep_timespec_test.o ${TEST_LIB} ${LIB}; ${CC} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} nsync-1.24.0/builds/aarch64.linux.c++11/dependfile000066400000000000000000000000001367521742200213320ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.clang/000077500000000000000000000000001367521742200176745ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.clang/Makefile000066400000000000000000000013451367521742200213370ustar00rootroot00000000000000CC=clang PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/clang -I../../platform/linux -I../../platform/aarch64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/aarch64.linux.clang/dependfile000066400000000000000000000000001367521742200217040ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.g++/000077500000000000000000000000001367521742200171645ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.g++/Makefile000066400000000000000000000014101367521742200206200ustar00rootroot00000000000000CC=g++ PLATFORM_CPPFLAGS=-DNSYNC_ATOMIC_CPP11 -I../../platform/linux -I../../platform/c++11 -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/aarch64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-x c++ -std=c++11 -Werror -Wall -Wextra -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M -x c++ -std=c++11 PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/aarch64.linux.g++/dependfile000066400000000000000000000000001367521742200211740ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc.atm-asm/000077500000000000000000000000001367521742200207025ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc.atm-asm/Makefile000066400000000000000000000014411367521742200223420ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/aarch64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/aarch64/src/nsync_atm_aarch64.s PLATFORM_OBJS=nsync_atm_aarch64.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/aarch64.linux.gcc.atm-asm/dependfile000066400000000000000000000000001367521742200227120ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc.atm-c++11/000077500000000000000000000000001367521742200206345ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc.atm-c++11/Makefile000066400000000000000000000016111367521742200222730ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/aarch64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread PLATFORM_CXXFLAGS=-Werror -Wall -Wextra -std=c++11 -pedantic PLATFORM_CXX=../../platform/c_from_c++11/src/nsync_atm_c++.cc MKDEP_DEPEND=mkdep MKDEP=./mkdep ${CC} -E -c++=-std=c++11 PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_atm_c++.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/aarch64.linux.gcc.atm-c++11/dependfile000066400000000000000000000000001367521742200226440ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc.atm-c11/000077500000000000000000000000001367521742200205065ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc.atm-c11/Makefile000066400000000000000000000013371367521742200221520ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-DNSYNC_ATOMIC_C11 -I../../platform/c11 -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/aarch64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/aarch64.linux.gcc.atm-c11/dependfile000066400000000000000000000000001367521742200225160ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc.sem-mutex/000077500000000000000000000000001367521742200212675ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc.sem-mutex/Makefile000066400000000000000000000012671367521742200227350ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/aarch64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/aarch64.linux.gcc.sem-mutex/dependfile000066400000000000000000000000001367521742200232770ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc.sem-sem_t/000077500000000000000000000000001367521742200212345ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc.sem-sem_t/Makefile000066400000000000000000000012671367521742200227020ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/aarch64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_sem_t.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_sem_t.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/aarch64.linux.gcc.sem-sem_t/dependfile000066400000000000000000000000001367521742200232440ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc/000077500000000000000000000000001367521742200173445ustar00rootroot00000000000000nsync-1.24.0/builds/aarch64.linux.gcc/Makefile000066400000000000000000000012671367521742200210120ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/aarch64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/aarch64.linux.gcc/dependfile000066400000000000000000000000001367521742200213540ustar00rootroot00000000000000nsync-1.24.0/builds/alpha.linux.gcc/000077500000000000000000000000001367521742200172015ustar00rootroot00000000000000nsync-1.24.0/builds/alpha.linux.gcc/Makefile000066400000000000000000000012651367521742200206450ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/alpha -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/alpha.linux.gcc/dependfile000066400000000000000000000000001367521742200212110ustar00rootroot00000000000000nsync-1.24.0/builds/alpha.netbsd.gcc/000077500000000000000000000000001367521742200173215ustar00rootroot00000000000000nsync-1.24.0/builds/alpha.netbsd.gcc/Makefile000066400000000000000000000012661367521742200207660ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/netbsd -I../../platform/alpha -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/alpha.netbsd.gcc/dependfile000066400000000000000000000000001367521742200213310ustar00rootroot00000000000000nsync-1.24.0/builds/alpha.osf1.decc/000077500000000000000000000000001367521742200170545ustar00rootroot00000000000000nsync-1.24.0/builds/alpha.osf1.decc/Makefile000066400000000000000000000014411367521742200205140ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/decc -I../../platform/osf1 -I../../platform/alpha -I../../platform/posix -pthread -Duintmax_t=uint64_t PLATFORM_CFLAGS=-std1 PLATFORM_LDFLAGS=-pthread PLATFORM_LIBS=-lrt MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/alpha/src/nsync_atm_alpha.s PLATFORM_OBJS=nsync_atm_alpha.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/alpha.osf1.decc/dependfile000066400000000000000000000000001367521742200210640ustar00rootroot00000000000000nsync-1.24.0/builds/alpha.osf1.lcc/000077500000000000000000000000001367521742200167175ustar00rootroot00000000000000nsync-1.24.0/builds/alpha.osf1.lcc/Makefile000066400000000000000000000014041367521742200203560ustar00rootroot00000000000000CC=lcc PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/lcc -I../../platform/osf1 -I../../platform/alpha -I../../platform/posix PLATFORM_LIBS=-lpthread -lexc -lrt MKDEP_DEPEND=mkdep MKDEP=./mkdep ${CC} -E PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/alpha/src/nsync_atm_alpha.s PLATFORM_OBJS=nsync_atm_alpha.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/alpha.osf1.lcc/dependfile000066400000000000000000000000001367521742200207270ustar00rootroot00000000000000nsync-1.24.0/builds/arm.linux.gcc.atm-asm.lrt/000077500000000000000000000000001367521742200210315ustar00rootroot00000000000000nsync-1.24.0/builds/arm.linux.gcc.atm-asm.lrt/Makefile000066400000000000000000000014441367521742200224740ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/arm -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread PLATFORM_LIBS=-lrt MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/arm/src/nsync_atm_arm.s PLATFORM_OBJS=nsync_atm_arm.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/arm.linux.gcc.atm-asm.lrt/dependfile000066400000000000000000000000001367521742200230410ustar00rootroot00000000000000nsync-1.24.0/builds/arm.linux.gcc.lrt/000077500000000000000000000000001367521742200174735ustar00rootroot00000000000000nsync-1.24.0/builds/arm.linux.gcc.lrt/Makefile000066400000000000000000000013061367521742200211330ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/arm -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread PLATFORM_LIBS=-lrt MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/arm.linux.gcc.lrt/dependfile000066400000000000000000000000001367521742200215030ustar00rootroot00000000000000nsync-1.24.0/builds/generic_unix/000077500000000000000000000000001367521742200167025ustar00rootroot00000000000000nsync-1.24.0/builds/generic_unix/Makefile000066400000000000000000000005011367521742200203360ustar00rootroot00000000000000DETECT=../../tools/detect.sh all:; ${DETECT} "${CC}" ${MAKE} -f Makefile.helper all tests:; ${DETECT} "${CC}" ${MAKE} -f Makefile.helper tests test:; ${DETECT} "${CC}" ${MAKE} -f Makefile.helper test depend:; ${DETECT} "${CC}" ${MAKE} -f Makefile.helper depend clean:; ${DETECT} "${CC}" ${MAKE} -f Makefile.helper clean nsync-1.24.0/builds/generic_unix/Makefile.helper000066400000000000000000000013271367521742200216230ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L ${NSYNC_EXTRA_INC_DIR} -I../../platform/${NSYNC_CC} -I../../platform/${NSYNC_OS} -I../../platform/${NSYNC_ARCH} -I../../platform/${NSYNC_OS_TYPE} ${NSYNC_PTHREAD} PLATFORM_CFLAGS= PLATFORM_LDFLAGS=${NSYNC_PTHREAD} MKDEP=${CC} -M PLATFORM_C=${NSYNC_EXTRA_PLATFORM_C} ../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=${NSYNC_EXTRA_OBJS} nsync_semaphore_mutex.o per_thread_waiter.o yield.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/generic_unix/dependfile000066400000000000000000000000001367521742200207120ustar00rootroot00000000000000nsync-1.24.0/builds/ia64.linux.gcc.atm-asm.lrt/000077500000000000000000000000001367521742200210155ustar00rootroot00000000000000nsync-1.24.0/builds/ia64.linux.gcc.atm-asm.lrt/Makefile000066400000000000000000000014501367521742200224550ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/ia64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread PLATFORM_LIBS=-lrt MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/ia64/src/nsync_atm_ia64.s PLATFORM_OBJS=nsync_atm_ia64.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/ia64.linux.gcc.atm-asm.lrt/dependfile000066400000000000000000000000001367521742200230250ustar00rootroot00000000000000nsync-1.24.0/builds/ia64.linux.gcc.lrt/000077500000000000000000000000001367521742200174575ustar00rootroot00000000000000nsync-1.24.0/builds/ia64.linux.gcc.lrt/Makefile000066400000000000000000000013071367521742200211200ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/ia64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread PLATFORM_LIBS=-lrt MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/ia64.linux.gcc.lrt/dependfile000066400000000000000000000000001367521742200214670ustar00rootroot00000000000000nsync-1.24.0/builds/mips.irix64.gcc/000077500000000000000000000000001367521742200170525ustar00rootroot00000000000000nsync-1.24.0/builds/mips.irix64.gcc/Makefile000066400000000000000000000014341367521742200205140ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc_no_tls -I../../platform/gcc -I../../platform/irix64 -I../../platform/mips -I../../platform/posix PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LIBS=-lpthread MKDEP=${CC} -M PLATFORM_C=../../platform/mips/src/nsync_atm_mips.S ../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_atm_mips.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/mips.irix64.gcc/dependfile000066400000000000000000000000001367521742200210620ustar00rootroot00000000000000nsync-1.24.0/builds/parisc64.linux.gcc.atm-asm/000077500000000000000000000000001367521742200211055ustar00rootroot00000000000000nsync-1.24.0/builds/parisc64.linux.gcc.atm-asm/Makefile000066400000000000000000000014451367521742200225510ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/parisc64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/parisc64/src/nsync_atm_parisc64.s PLATFORM_OBJS=nsync_atm_parisc64.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/parisc64.linux.gcc.atm-asm/dependfile000066400000000000000000000000001367521742200231150ustar00rootroot00000000000000nsync-1.24.0/builds/parisc64.linux.gcc/000077500000000000000000000000001367521742200175475ustar00rootroot00000000000000nsync-1.24.0/builds/parisc64.linux.gcc/Makefile000066400000000000000000000012701367521742200212070ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/parisc64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/parisc64.linux.gcc/dependfile000066400000000000000000000000001367521742200215570ustar00rootroot00000000000000nsync-1.24.0/builds/pmax.netbsd.gcc.atm-os/000077500000000000000000000000001367521742200204005ustar00rootroot00000000000000nsync-1.24.0/builds/pmax.netbsd.gcc.atm-os/Makefile000066400000000000000000000012651367521742200220440ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/netbsd -I../../platform/gcc -I../../platform/pmax -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/pmax.netbsd.gcc.atm-os/dependfile000066400000000000000000000000001367521742200224100ustar00rootroot00000000000000nsync-1.24.0/builds/ppc64.linux.gcc.atm-asm.lrt/000077500000000000000000000000001367521742200212065ustar00rootroot00000000000000nsync-1.24.0/builds/ppc64.linux.gcc.atm-asm.lrt/Makefile000066400000000000000000000014541367521742200226520ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/ppc64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread PLATFORM_LIBS=-lrt MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/ppc64/src/nsync_atm_ppc64.s PLATFORM_OBJS=nsync_atm_ppc64.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/ppc64.linux.gcc.atm-asm.lrt/dependfile000066400000000000000000000000001367521742200232160ustar00rootroot00000000000000nsync-1.24.0/builds/ppc64.linux.gcc.lrt/000077500000000000000000000000001367521742200176505ustar00rootroot00000000000000nsync-1.24.0/builds/ppc64.linux.gcc.lrt/Makefile000066400000000000000000000013101367521742200213030ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/ppc64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread PLATFORM_LIBS=-lrt MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/ppc64.linux.gcc.lrt/dependfile000066400000000000000000000000001367521742200216600ustar00rootroot00000000000000nsync-1.24.0/builds/s390x.linux.gcc.atm-asm/000077500000000000000000000000001367521742200203405ustar00rootroot00000000000000nsync-1.24.0/builds/s390x.linux.gcc.atm-asm/Makefile000066400000000000000000000014311367521742200217770ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/s390x -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/s390x/src/nsync_atm_s390x.s PLATFORM_OBJS=nsync_atm_s390x.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/s390x.linux.gcc.atm-asm/dependfile000066400000000000000000000000001367521742200223500ustar00rootroot00000000000000nsync-1.24.0/builds/s390x.linux.gcc/000077500000000000000000000000001367521742200170025ustar00rootroot00000000000000nsync-1.24.0/builds/s390x.linux.gcc/Makefile000066400000000000000000000012651367521742200204460ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/s390x -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/s390x.linux.gcc/dependfile000066400000000000000000000000001367521742200210120ustar00rootroot00000000000000nsync-1.24.0/builds/shark.netbsd.gcc.atm-os/000077500000000000000000000000001367521742200205435ustar00rootroot00000000000000nsync-1.24.0/builds/shark.netbsd.gcc.atm-os/Makefile000066400000000000000000000012661367521742200222100ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/netbsd -I../../platform/gcc -I../../platform/shark -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/shark.netbsd.gcc.atm-os/dependfile000066400000000000000000000000001367521742200225530ustar00rootroot00000000000000nsync-1.24.0/builds/sparc64.netbsd.gcc.atm-asm/000077500000000000000000000000001367521742200210545ustar00rootroot00000000000000nsync-1.24.0/builds/sparc64.netbsd.gcc.atm-asm/Makefile000066400000000000000000000014421367521742200225150ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/netbsd -I../../platform/sparc64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/sparc64/src/nsync_atm_sparc64.s PLATFORM_OBJS=nsync_atm_sparc64.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/sparc64.netbsd.gcc.atm-asm/dependfile000066400000000000000000000000001367521742200230640ustar00rootroot00000000000000nsync-1.24.0/builds/sparc64.netbsd.gcc/000077500000000000000000000000001367521742200175165ustar00rootroot00000000000000nsync-1.24.0/builds/sparc64.netbsd.gcc/Makefile000066400000000000000000000012701367521742200211560ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/netbsd -I../../platform/sparc64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/sparc64.netbsd.gcc/dependfile000066400000000000000000000000001367521742200215260ustar00rootroot00000000000000nsync-1.24.0/builds/vax.netbsd.gcc.atm-asm/000077500000000000000000000000001367521742200203705ustar00rootroot00000000000000nsync-1.24.0/builds/vax.netbsd.gcc.atm-asm/Makefile000066400000000000000000000014221367521742200220270ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/netbsd -I../../platform/vax -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/vax/src/nsync_atm_vax.s PLATFORM_OBJS=nsync_atm_vax.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/vax.netbsd.gcc.atm-asm/dependfile000066400000000000000000000000001367521742200224000ustar00rootroot00000000000000nsync-1.24.0/builds/vax.netbsd.gcc/000077500000000000000000000000001367521742200170325ustar00rootroot00000000000000nsync-1.24.0/builds/vax.netbsd.gcc/Makefile000066400000000000000000000012641367521742200204750ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/netbsd -I../../platform/vax -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/vax.netbsd.gcc/dependfile000066400000000000000000000000001367521742200210420ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.cygwin.gcc/000077500000000000000000000000001367521742200172065ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.cygwin.gcc/Makefile000066400000000000000000000012671367521742200206540ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/cygwin -I../../platform/x86_32 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.cygwin.gcc/dependfile000066400000000000000000000000001367521742200212160ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.freebsd.clang/000077500000000000000000000000001367521742200176505ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.freebsd.clang/Makefile000066400000000000000000000013351367521742200213120ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/clang -I../../platform/freebsd -I../../platform/x86_32 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.freebsd.clang/dependfile000066400000000000000000000000001367521742200216600ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.linux.clang/000077500000000000000000000000001367521742200173755ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.linux.clang/Makefile000066400000000000000000000013671367521742200210440ustar00rootroot00000000000000CC=clang PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/clang -I../../platform/linux -I../../platform/x86_32 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration PLATFORM_LIBS=-lrt PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.linux.clang/dependfile000066400000000000000000000000001367521742200214050ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.linux.gcc/000077500000000000000000000000001367521742200170455ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.linux.gcc/Makefile000066400000000000000000000013111367521742200205010ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/x86_32 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LIBS=-lrt PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.linux.gcc/dependfile000066400000000000000000000000001367521742200210550ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.linux.tcc/000077500000000000000000000000001367521742200170625ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.linux.tcc/Makefile000066400000000000000000000014721367521742200205260ustar00rootroot00000000000000CC=tcc PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/tcc -I../../platform/linux -I../../platform/x86_32 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall PLATFORM_LIBS=-lrt PLATFORM_LDFLAGS=-pthread MKDEP_DEPEND=mkdep MKDEP=./mkdep ${CC} -E PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/x86_32/src/nsync_atm_x86_32.s PLATFORM_OBJS=nsync_atm_x86_32.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.linux.tcc/dependfile000066400000000000000000000000001367521742200210720ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.c++11/000077500000000000000000000000001367521742200171435ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.c++11/Makefile000066400000000000000000000022751367521742200206110ustar00rootroot00000000000000CC=g++ PLATFORM_CPPFLAGS=-DNSYNC_USE_CPP11_TIMEPOINT -DNSYNC_ATOMIC_CPP11 -I../../platform/c++11 -I../../platform/gcc -I../../platform/posix -pthread PLATFORM_CFLAGS=-std=c++11 -Werror -Wall -Wextra -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M -std=c++11 # It's dangerous to use C++ class destructors if we can avoid it, because nsync # may be linked into the address space multiple times, so we use the posix # per_thread_waiter. PLATFORM_C=../../platform/c++11/src/nsync_semaphore_mutex.cc ../../platform/posix/src/per_thread_waiter.c ../../platform/c++11/src/yield.cc ../../platform/c++11/src/time_rep_timespec.cc ../../platform/c++11/src/nsync_panic.cc PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep_timespec.o nsync_panic.o TEST_PLATFORM_C=../../platform/c++11/src/start_thread.cc TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile time_rep_timespec_test.o: ../../platform/c++11/src/time_rep_timespec_test.cc; ${CC} ${CFLAGS} -I../../testing -c ../../platform/c++11/src/time_rep_timespec_test.cc time_rep_timespec_test: time_rep_timespec_test.o ${TEST_LIB} ${LIB}; ${CC} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} nsync-1.24.0/builds/x86_32.netbsd.c++11/dependfile000066400000000000000000000000001367521742200211530ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.clang.atm-c11/000077500000000000000000000000001367521742200206575ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.clang.atm-c11/Makefile000066400000000000000000000014411367521742200223170ustar00rootroot00000000000000CC=clang PLATFORM_CPPFLAGS=-DNSYNC_ATOMIC_C11 -I../../platform/c11 -D_POSIX_C_SOURCE=200809L -I../../platform/clang -I../../platform/netbsd -I../../platform/x86_32 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration -Wno-c99-extensions PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.netbsd.clang.atm-c11/dependfile000066400000000000000000000000001367521742200226670ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.clang/000077500000000000000000000000001367521742200175155ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.clang/Makefile000066400000000000000000000013711367521742200211570ustar00rootroot00000000000000CC=clang PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/clang -I../../platform/netbsd -I../../platform/x86_32 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration -Wno-c99-extensions PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.netbsd.clang/dependfile000066400000000000000000000000001367521742200215250ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.gcc.time_debug/000077500000000000000000000000001367521742200212705ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.gcc.time_debug/Makefile000066400000000000000000000013341367521742200227310ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/netbsd -I../../platform/x86_32 -I../../platform/posix -DNSYNC_USE_DEBUG_TIME=1 -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep_debug.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep_debug.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.netbsd.gcc.time_debug/dependfile000066400000000000000000000000001367521742200233000ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.gcc/000077500000000000000000000000001367521742200171655ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.gcc/Makefile000066400000000000000000000012671367521742200206330ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/netbsd -I../../platform/x86_32 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.netbsd.gcc/dependfile000066400000000000000000000000001367521742200211750ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.lcc/000077500000000000000000000000001367521742200171725ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.netbsd.lcc/Makefile000066400000000000000000000013771367521742200206420ustar00rootroot00000000000000CC=lcc PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/lcc -I../../platform/netbsd -I../../platform/x86_32 -I../../platform/posix PLATFORM_LIBS=-lpthread MKDEP_DEPEND=mkdep MKDEP=./mkdep ${CC} -E PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/x86_32/src/nsync_atm_x86_32.s PLATFORM_OBJS=nsync_atm_x86_32.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.netbsd.lcc/dependfile000066400000000000000000000000001367521742200212020ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.openbsd.gcc/000077500000000000000000000000001367521742200173405ustar00rootroot00000000000000nsync-1.24.0/builds/x86_32.openbsd.gcc/Makefile000066400000000000000000000013241367521742200210000ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc_no_tls -I../../platform/gcc -I../../platform/openbsd -I../../platform/x86_32 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_32.openbsd.gcc/dependfile000066400000000000000000000000001367521742200213500ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.cygwin.gcc/000077500000000000000000000000001367521742200172135ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.cygwin.gcc/Makefile000066400000000000000000000012671367521742200206610ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/cygwin -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.cygwin.gcc/dependfile000066400000000000000000000000001367521742200212230ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.freebsd.c++11/000077500000000000000000000000001367521742200173035ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.freebsd.c++11/Makefile000066400000000000000000000023231367521742200207430ustar00rootroot00000000000000CC=clang++ -x c++ PLATFORM_CPPFLAGS=-DNSYNC_USE_CPP11_TIMEPOINT -DNSYNC_ATOMIC_CPP11 -I../../platform/c++11 -I../../platform/gcc -I../../platform/posix -pthread PLATFORM_CFLAGS=-std=c++11 -Werror -Wall -Wextra -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M -std=c++11 # It's dangerous to use C++ class destructors if we can avoid it, because nsync # may be linked into the address space multiple times, so we use the posix # per_thread_waiter. PLATFORM_C=../../platform/c++11/src/nsync_semaphore_mutex.cc ../../platform/posix/src/per_thread_waiter.c ../../platform/c++11/src/yield.cc ../../platform/c++11/src/time_rep_timespec.cc ../../platform/c++11/src/nsync_panic.cc PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep_timespec.o nsync_panic.o TEST_PLATFORM_C=../../platform/c++11/src/start_thread.cc TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile LD=clang++ time_rep_timespec_test.o: ../../platform/c++11/src/time_rep_timespec_test.cc; ${CC} ${CFLAGS} -I../../testing -c ../../platform/c++11/src/time_rep_timespec_test.cc time_rep_timespec_test: time_rep_timespec_test.o ${TEST_LIB} ${LIB}; ${CC} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} nsync-1.24.0/builds/x86_64.freebsd.c++11/dependfile000066400000000000000000000000001367521742200213130ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.freebsd.clang/000077500000000000000000000000001367521742200176555ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.freebsd.clang/Makefile000066400000000000000000000013351367521742200213170ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/clang -I../../platform/freebsd -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.freebsd.clang/dependfile000066400000000000000000000000001367521742200216650ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.c++11/000077500000000000000000000000001367521742200170305ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.c++11/Makefile000066400000000000000000000024771367521742200205020ustar00rootroot00000000000000# On Linux, wakeups from C++11 condition variables are surprisingly slow, so we # use futex directly. CC=g++ PLATFORM_CPPFLAGS=-DNSYNC_USE_CPP11_TIMEPOINT -DNSYNC_ATOMIC_CPP11 -I../../platform/c++11.futex -I../../platform/c++11 -I../../platform/gcc -I../../platform/posix -pthread PLATFORM_CFLAGS=-std=c++11 -Werror -Wall -Wextra -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M -std=c++11 # It's dangerous to use C++ class destructors if we can avoid it, because nsync # may be linked into the address space multiple times, so we use the posix # per_thread_waiter. PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/c++11/src/yield.cc ../../platform/c++11/src/time_rep_timespec.cc ../../platform/c++11/src/nsync_panic.cc PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep_timespec.o nsync_panic.o TEST_PLATFORM_C=../../platform/c++11/src/start_thread.cc TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile time_rep_timespec_test.o: ../../platform/c++11/src/time_rep_timespec_test.cc; ${CC} ${CFLAGS} -I../../testing -c ../../platform/c++11/src/time_rep_timespec_test.cc time_rep_timespec_test: time_rep_timespec_test.o ${TEST_LIB} ${LIB}; ${CC} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} nsync-1.24.0/builds/x86_64.linux.c++11/dependfile000066400000000000000000007037001367521742200210610ustar00rootroot00000000000000common.o: ../../internal/common.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../platform/c++11/atomic.h \ ../../public/nsync_atomic.h ../../internal/sem.h ../../internal/dll.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_waiter.h ../../public/nsync_mu.h \ ../../public/nsync_note.h counter.o: ../../internal/counter.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../platform/c++11/atomic.h \ ../../public/nsync_atomic.h ../../internal/dll.h ../../internal/sem.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_waiter.h ../../public/nsync_mu.h \ ../../public/nsync_note.h cv.o: ../../internal/cv.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../internal/dll.h ../../internal/sem.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_atomic.h ../../public/nsync_waiter.h \ ../../public/nsync_mu.h ../../public/nsync_note.h \ ../../platform/c++11/atomic.h debug.o: ../../internal/debug.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../internal/dll.h ../../internal/sem.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_atomic.h ../../public/nsync_waiter.h \ ../../public/nsync_mu.h ../../public/nsync_note.h \ ../../platform/c++11/atomic.h dll.o: ../../internal/dll.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../internal/dll.h mu.o: ../../internal/mu.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../internal/dll.h ../../internal/sem.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_atomic.h ../../public/nsync_waiter.h \ ../../public/nsync_mu.h ../../public/nsync_note.h \ ../../platform/c++11/atomic.h mu_wait.o: ../../internal/mu_wait.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../internal/dll.h ../../internal/sem.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_atomic.h ../../public/nsync_waiter.h \ ../../public/nsync_mu.h ../../public/nsync_note.h \ ../../platform/c++11/atomic.h note.o: ../../internal/note.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../internal/dll.h ../../internal/sem.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_atomic.h ../../public/nsync_waiter.h \ ../../public/nsync_mu.h ../../public/nsync_note.h \ ../../platform/c++11/atomic.h once.o: ../../internal/once.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../internal/dll.h ../../internal/sem.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_atomic.h ../../public/nsync_waiter.h \ ../../public/nsync_mu.h ../../public/nsync_note.h \ ../../platform/c++11/atomic.h sem_wait.o: ../../internal/sem_wait.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../internal/dll.h ../../internal/sem.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_atomic.h ../../public/nsync_waiter.h \ ../../public/nsync_mu.h ../../public/nsync_note.h \ ../../platform/c++11/atomic.h sem_wait_no_note.o: ../../internal/sem_wait_no_note.c \ /usr/include/stdc-predef.h ../../public/nsync_cpp.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../internal/dll.h ../../internal/sem.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_atomic.h ../../public/nsync_waiter.h \ ../../public/nsync_mu.h ../../public/nsync_note.h \ ../../platform/c++11/atomic.h time_internal.o: ../../internal/time_internal.c \ /usr/include/stdc-predef.h ../../public/nsync_cpp.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync_time.h \ ../../public/nsync_cpp.h ../../public/nsync_time_internal.h wait.o: ../../internal/wait.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../internal/sem.h ../../internal/dll.h \ ../../internal/wait_internal.h ../../internal/common.h \ ../../public/nsync_atomic.h ../../public/nsync_waiter.h \ ../../public/nsync_mu.h ../../public/nsync_note.h \ ../../platform/c++11/atomic.h array.o: ../../testing/array.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../testing/array.h atm_log.o: ../../testing/atm_log.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h closure.o: ../../testing/closure.c /usr/include/stdc-predef.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../testing/closure.h counter_test.o: ../../testing/counter_test.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync.h ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/time_extra.h \ ../../testing/smprintf.h ../../testing/closure.h ../../testing/testing.h cv_mu_timeout_stress_test.o: ../../testing/cv_mu_timeout_stress_test.c \ /usr/include/stdc-predef.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync.h ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/smprintf.h \ ../../testing/testing.h ../../testing/closure.h cv_test.o: ../../testing/cv_test.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync.h ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/time_extra.h \ ../../testing/smprintf.h ../../testing/testing.h ../../testing/closure.h cv_wait_example_test.o: ../../testing/cv_wait_example_test.c \ /usr/include/stdc-predef.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../platform/gcc/compiler.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/time_extra.h \ ../../testing/smprintf.h ../../testing/testing.h ../../testing/closure.h \ ../../testing/array.h ../../testing/heap.h dll_test.o: ../../testing/dll_test.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync_time.h ../../public/nsync_cpp.h \ ../../public/nsync_time_internal.h ../../internal/dll.h \ ../../testing/smprintf.h ../../testing/testing.h ../../testing/array.h mu_starvation_test.o: ../../testing/mu_starvation_test.c \ /usr/include/stdc-predef.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync.h ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/time_extra.h \ ../../testing/smprintf.h ../../testing/testing.h ../../testing/closure.h mu_test.o: ../../testing/mu_test.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync.h ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/time_extra.h \ ../../testing/smprintf.h ../../testing/testing.h ../../testing/closure.h mu_wait_example_test.o: ../../testing/mu_wait_example_test.c \ /usr/include/stdc-predef.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../platform/gcc/compiler.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/time_extra.h \ ../../testing/smprintf.h ../../testing/testing.h ../../testing/closure.h \ ../../testing/array.h ../../testing/heap.h mu_wait_test.o: ../../testing/mu_wait_test.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../platform/gcc/compiler.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/time_extra.h \ ../../testing/smprintf.h ../../testing/testing.h ../../testing/closure.h note_test.o: ../../testing/note_test.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync.h ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/time_extra.h \ ../../testing/smprintf.h ../../testing/closure.h ../../testing/testing.h once_test.o: ../../testing/once_test.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync.h ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/testing.h \ ../../testing/closure.h ../../testing/smprintf.h pingpong_test.o: ../../testing/pingpong_test.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync.h ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/smprintf.h \ ../../testing/testing.h ../../testing/closure.h smprintf.o: ../../testing/smprintf.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../testing/smprintf.h testing.o: ../../testing/testing.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../testing/atm_log.h ../../public/nsync.h ../../public/nsync_mu.h \ ../../public/nsync_cpp.h ../../public/nsync_atomic.h \ /usr/include/c++/4.8/atomic /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../platform/c++11/atomic.h \ ../../public/nsync_atomic.h ../../testing/time_extra.h \ ../../testing/smprintf.h ../../testing/testing.h ../../internal/dll.h \ ../../testing/closure.h ../../internal/wait_internal.h \ ../../internal/common.h ../../internal/sem.h ../../public/nsync_waiter.h \ ../../internal/dll.h ../../public/nsync_mu.h ../../public/nsync_note.h time_extra.o: ../../testing/time_extra.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync_time.h ../../public/nsync_cpp.h \ ../../public/nsync_time_internal.h ../../testing/time_extra.h \ ../../testing/smprintf.h wait_test.o: ../../testing/wait_test.c /usr/include/stdc-predef.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../public/nsync_cpp.h \ ../../public/nsync.h ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../testing/time_extra.h \ ../../testing/smprintf.h ../../testing/closure.h ../../testing/testing.h \ ../../testing/array.h nsync_semaphore_mutex.o: \ ../../platform/c++11/src/nsync_semaphore_mutex.cc \ /usr/include/stdc-predef.h ../../internal/headers.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../platform/c++11/atomic.h \ ../../public/nsync_atomic.h ../../internal/sem.h per_thread_waiter.o: ../../platform/c++11/src/per_thread_waiter.cc \ /usr/include/stdc-predef.h ../../internal/headers.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../platform/c++11/atomic.h \ ../../public/nsync_atomic.h ../../internal/sem.h yield.o: ../../platform/c++11/src/yield.cc /usr/include/stdc-predef.h \ ../../internal/headers.h ../../public/nsync_cpp.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../platform/c++11/atomic.h \ ../../public/nsync_atomic.h ../../internal/sem.h \ /usr/include/c++/4.8/thread /usr/include/c++/4.8/memory \ /usr/include/c++/4.8/bits/stl_construct.h \ /usr/include/c++/4.8/ext/alloc_traits.h \ /usr/include/c++/4.8/bits/alloc_traits.h \ /usr/include/c++/4.8/bits/ptr_traits.h \ /usr/include/c++/4.8/bits/stl_uninitialized.h \ /usr/include/c++/4.8/bits/stl_tempbuf.h \ /usr/include/c++/4.8/bits/stl_raw_storage_iter.h \ /usr/include/c++/4.8/ext/concurrence.h \ /usr/include/c++/4.8/bits/unique_ptr.h \ /usr/include/c++/4.8/bits/shared_ptr.h \ /usr/include/c++/4.8/bits/shared_ptr_base.h \ /usr/include/c++/4.8/backward/auto_ptr.h time_rep_timespec.o: ../../platform/c++11/src/time_rep_timespec.cc \ /usr/include/stdc-predef.h ../../public/nsync_cpp.h \ ../../platform/c++11/platform.h /usr/include/string.h \ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../platform/posix/nsync_time_init.h \ ../../public/nsync_time.h ../../public/nsync_cpp.h \ ../../public/nsync_time_internal.h /usr/include/c++/4.8/thread \ /usr/include/c++/4.8/memory /usr/include/c++/4.8/bits/stl_construct.h \ /usr/include/c++/4.8/ext/alloc_traits.h \ /usr/include/c++/4.8/bits/alloc_traits.h \ /usr/include/c++/4.8/bits/ptr_traits.h \ /usr/include/c++/4.8/bits/stl_uninitialized.h \ /usr/include/c++/4.8/bits/stl_tempbuf.h \ /usr/include/c++/4.8/bits/stl_raw_storage_iter.h \ /usr/include/c++/4.8/ext/concurrence.h \ /usr/include/c++/4.8/bits/unique_ptr.h \ /usr/include/c++/4.8/bits/shared_ptr.h \ /usr/include/c++/4.8/bits/shared_ptr_base.h \ /usr/include/c++/4.8/backward/auto_ptr.h nsync_panic.o: ../../platform/c++11/src/nsync_panic.cc \ /usr/include/stdc-predef.h ../../internal/headers.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../platform/c++11/atomic.h \ ../../public/nsync_atomic.h ../../internal/sem.h \ /usr/include/c++/4.8/iostream /usr/include/c++/4.8/ostream \ /usr/include/c++/4.8/ios /usr/include/c++/4.8/bits/ios_base.h \ /usr/include/c++/4.8/bits/locale_classes.h \ /usr/include/c++/4.8/bits/locale_classes.tcc \ /usr/include/c++/4.8/streambuf /usr/include/c++/4.8/bits/streambuf.tcc \ /usr/include/c++/4.8/bits/basic_ios.h \ /usr/include/c++/4.8/bits/locale_facets.h /usr/include/c++/4.8/cwctype \ /usr/include/wctype.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/ctype_base.h \ /usr/include/c++/4.8/bits/streambuf_iterator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/ctype_inline.h \ /usr/include/c++/4.8/bits/locale_facets.tcc \ /usr/include/c++/4.8/bits/basic_ios.tcc \ /usr/include/c++/4.8/bits/ostream.tcc /usr/include/c++/4.8/istream \ /usr/include/c++/4.8/bits/istream.tcc start_thread.o: ../../platform/c++11/src/start_thread.cc \ /usr/include/stdc-predef.h ../../internal/headers.h \ ../../public/nsync_cpp.h ../../platform/c++11/platform.h \ /usr/include/string.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \ /usr/include/xlocale.h /usr/include/errno.h \ /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ /usr/include/x86_64-linux-gnu/asm/errno.h \ /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ /usr/include/x86_64-linux-gnu/bits/waitstatus.h /usr/include/endian.h \ /usr/include/x86_64-linux-gnu/bits/endian.h \ /usr/include/x86_64-linux-gnu/bits/byteswap.h \ /usr/include/x86_64-linux-gnu/bits/types.h \ /usr/include/x86_64-linux-gnu/bits/typesizes.h \ /usr/include/x86_64-linux-gnu/bits/byteswap-16.h \ /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/time.h \ /usr/include/x86_64-linux-gnu/sys/select.h \ /usr/include/x86_64-linux-gnu/bits/select.h \ /usr/include/x86_64-linux-gnu/bits/sigset.h \ /usr/include/x86_64-linux-gnu/bits/time.h \ /usr/include/x86_64-linux-gnu/sys/sysmacros.h \ /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h /usr/include/alloca.h \ /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ /usr/include/inttypes.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h /usr/include/stdint.h \ /usr/include/x86_64-linux-gnu/bits/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/limits.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed/syslimits.h \ /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ /usr/include/x86_64-linux-gnu/bits/local_lim.h \ /usr/include/linux/limits.h \ /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ /usr/include/c++/4.8/mutex /usr/include/c++/4.8/tuple \ /usr/include/c++/4.8/utility \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++config.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/os_defines.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/cpu_defines.h \ /usr/include/c++/4.8/bits/stl_relops.h \ /usr/include/c++/4.8/bits/stl_pair.h /usr/include/c++/4.8/bits/move.h \ /usr/include/c++/4.8/bits/concept_check.h \ /usr/include/c++/4.8/type_traits /usr/include/c++/4.8/initializer_list \ /usr/include/c++/4.8/array /usr/include/c++/4.8/stdexcept \ /usr/include/c++/4.8/exception \ /usr/include/c++/4.8/bits/atomic_lockfree_defines.h \ /usr/include/c++/4.8/bits/exception_ptr.h \ /usr/include/c++/4.8/bits/exception_defines.h \ /usr/include/c++/4.8/bits/nested_exception.h /usr/include/c++/4.8/string \ /usr/include/c++/4.8/bits/stringfwd.h \ /usr/include/c++/4.8/bits/memoryfwd.h \ /usr/include/c++/4.8/bits/char_traits.h \ /usr/include/c++/4.8/bits/stl_algobase.h \ /usr/include/c++/4.8/bits/functexcept.h \ /usr/include/c++/4.8/bits/cpp_type_traits.h \ /usr/include/c++/4.8/ext/type_traits.h \ /usr/include/c++/4.8/ext/numeric_traits.h \ /usr/include/c++/4.8/bits/stl_iterator_base_types.h \ /usr/include/c++/4.8/bits/stl_iterator_base_funcs.h \ /usr/include/c++/4.8/debug/debug.h \ /usr/include/c++/4.8/bits/stl_iterator.h \ /usr/include/c++/4.8/bits/postypes.h /usr/include/c++/4.8/cwchar \ /usr/include/c++/4.8/cstdint /usr/include/c++/4.8/bits/allocator.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h \ /usr/include/c++/4.8/ext/new_allocator.h /usr/include/c++/4.8/new \ /usr/include/c++/4.8/bits/localefwd.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++locale.h \ /usr/include/c++/4.8/clocale /usr/include/locale.h \ /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/c++/4.8/iosfwd \ /usr/include/c++/4.8/cctype /usr/include/ctype.h \ /usr/include/c++/4.8/bits/ostream_insert.h \ /usr/include/c++/4.8/bits/cxxabi_forced.h \ /usr/include/c++/4.8/bits/stl_function.h \ /usr/include/c++/4.8/backward/binders.h \ /usr/include/c++/4.8/bits/range_access.h \ /usr/include/c++/4.8/bits/basic_string.h \ /usr/include/c++/4.8/ext/atomicity.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h \ /usr/include/pthread.h /usr/include/sched.h \ /usr/include/x86_64-linux-gnu/bits/sched.h \ /usr/include/x86_64-linux-gnu/bits/timex.h \ /usr/include/x86_64-linux-gnu/bits/setjmp.h \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/atomic_word.h \ /usr/include/c++/4.8/ext/string_conversions.h \ /usr/include/c++/4.8/cstdlib /usr/include/c++/4.8/cstdio \ /usr/include/c++/4.8/cerrno /usr/include/c++/4.8/bits/functional_hash.h \ /usr/include/c++/4.8/bits/hash_bytes.h \ /usr/include/c++/4.8/bits/basic_string.tcc \ /usr/include/c++/4.8/bits/uses_allocator.h /usr/include/c++/4.8/chrono \ /usr/include/c++/4.8/ratio /usr/include/c++/4.8/limits \ /usr/include/c++/4.8/ctime /usr/include/c++/4.8/functional \ /usr/include/c++/4.8/typeinfo /usr/include/c++/4.8/system_error \ /usr/include/x86_64-linux-gnu/c++/4.8/bits/error_constants.h \ /usr/include/c++/4.8/condition_variable ../../platform/gcc/compiler.h \ ../../platform/posix/cputype.h ../../public/nsync.h \ ../../public/nsync_mu.h ../../public/nsync_cpp.h \ ../../public/nsync_atomic.h /usr/include/c++/4.8/atomic \ /usr/include/c++/4.8/bits/atomic_base.h \ /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdbool.h \ ../../public/nsync_mu_wait.h ../../public/nsync_time.h \ ../../public/nsync_time_internal.h ../../public/nsync_cv.h \ ../../public/nsync_note.h ../../public/nsync_counter.h \ ../../public/nsync_waiter.h ../../public/nsync_once.h \ ../../public/nsync_debug.h ../../platform/c++11/atomic.h \ ../../public/nsync_atomic.h ../../internal/sem.h \ /usr/include/c++/4.8/thread /usr/include/c++/4.8/memory \ /usr/include/c++/4.8/bits/stl_construct.h \ /usr/include/c++/4.8/ext/alloc_traits.h \ /usr/include/c++/4.8/bits/alloc_traits.h \ /usr/include/c++/4.8/bits/ptr_traits.h \ /usr/include/c++/4.8/bits/stl_uninitialized.h \ /usr/include/c++/4.8/bits/stl_tempbuf.h \ /usr/include/c++/4.8/bits/stl_raw_storage_iter.h \ /usr/include/c++/4.8/ext/concurrence.h \ /usr/include/c++/4.8/bits/unique_ptr.h \ /usr/include/c++/4.8/bits/shared_ptr.h \ /usr/include/c++/4.8/bits/shared_ptr_base.h \ /usr/include/c++/4.8/backward/auto_ptr.h nsync-1.24.0/builds/x86_64.linux.clang/000077500000000000000000000000001367521742200174025ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.clang/Makefile000066400000000000000000000013441367521742200210440ustar00rootroot00000000000000CC=clang PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/clang -I../../platform/linux -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.linux.clang/dependfile000066400000000000000000000000001367521742200214120ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.g++/000077500000000000000000000000001367521742200166725ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.g++/Makefile000066400000000000000000000014001367521742200203250ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-DNSYNC_ATOMIC_CPP11 -I../../platform/linux -I../../platform/c++11 -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-x c++ -std=c++11 -Werror -Wall -Wextra -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M -x c++ -std=c++11 PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.linux.g++/dependfile000066400000000000000000000000001367521742200207020ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc.atm-asm/000077500000000000000000000000001367521742200204105ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc.atm-asm/Makefile000066400000000000000000000014351367521742200220530ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/x86_64/src/nsync_atm_x86_64.s PLATFORM_OBJS=nsync_atm_x86_64.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.linux.gcc.atm-asm/dependfile000066400000000000000000000000001367521742200224200ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc.atm-c++11/000077500000000000000000000000001367521742200203425ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc.atm-c++11/Makefile000066400000000000000000000016101367521742200220000ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread PLATFORM_CXXFLAGS=-Werror -Wall -Wextra -std=c++11 -pedantic PLATFORM_CXX=../../platform/c_from_c++11/src/nsync_atm_c++.cc MKDEP_DEPEND=mkdep MKDEP=./mkdep ${CC} -E -c++=-std=c++11 PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_atm_c++.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.linux.gcc.atm-c++11/dependfile000066400000000000000000000000001367521742200223520ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc.atm-c11/000077500000000000000000000000001367521742200202145ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc.atm-c11/Makefile000066400000000000000000000014011367521742200216500ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-DNSYNC_ATOMIC_C11 -I../../platform/c11 -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.linux.gcc.atm-c11/dependfile000066400000000000000000000000001367521742200222240ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc.sem-mutex/000077500000000000000000000000001367521742200207755ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc.sem-mutex/Makefile000066400000000000000000000012661367521742200224420ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.linux.gcc.sem-mutex/dependfile000066400000000000000000000000001367521742200230050ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc.sem-sem_t/000077500000000000000000000000001367521742200207425ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc.sem-sem_t/Makefile000066400000000000000000000012661367521742200224070ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_sem_t.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_sem_t.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.linux.gcc.sem-sem_t/dependfile000066400000000000000000000000001367521742200227520ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc/000077500000000000000000000000001367521742200170525ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.gcc/Makefile000066400000000000000000000012661367521742200205170ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/linux -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.linux.gcc/dependfile000066400000000000000000000000001367521742200210620ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.old_gcc/000077500000000000000000000000001367521742200177105ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.old_gcc/Makefile000066400000000000000000000013631367521742200213530ustar00rootroot00000000000000# Force the use of old gcc atomics. PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc_old -I../../platform/gcc -I../../platform/linux -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.linux.old_gcc/dependfile000066400000000000000000000000001367521742200217200ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.tcc/000077500000000000000000000000001367521742200170675ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.linux.tcc/Makefile000066400000000000000000000014471367521742200205350ustar00rootroot00000000000000CC=tcc PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/tcc -I../../platform/linux -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall PLATFORM_LDFLAGS=-pthread MKDEP_DEPEND=mkdep MKDEP=./mkdep ${CC} -E PLATFORM_C=../../platform/linux/src/nsync_semaphore_futex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/x86_64/src/nsync_atm_x86_64.s PLATFORM_OBJS=nsync_atm_x86_64.o nsync_semaphore_futex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.linux.tcc/dependfile000066400000000000000000000000001367521742200210770ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.c++11/000077500000000000000000000000001367521742200167735ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.c++11/Makefile000066400000000000000000000030011367521742200204250ustar00rootroot00000000000000CC=clang++ # Some versions of MacOS (such as Sierra) require _DARWIN_C_SOURCE to include , , and (!) PLATFORM_CPPFLAGS=-DNSYNC_USE_CPP11_TIMEPOINT -DNSYNC_ATOMIC_CPP11 -D_DARWIN_C_SOURCE -I../../platform/c++11 -I../../platform/gcc -I../../platform/macos -I../../platform/posix -pthread PLATFORM_CFLAGS=-x c++ -std=c++11 -Werror -Wall -Wextra -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -x c++ -M -std=c++11 # Currently, MacOS's C++11 implementation is incomplete, and does not support # thread_local; hence the use of posix/src/per_thread_waiter.c rather than # c++11/src/per_thread_waiter.cc # Similarly, MacOS omits various posix calls, such as clock_gettime(). PLATFORM_C=../../platform/posix/src/clock_gettime.c ../../platform/c++11/src/nsync_semaphore_mutex.cc ../../platform/posix/src/per_thread_waiter.c ../../platform/c++11/src/yield.cc ../../platform/c++11/src/time_rep_timespec.cc ../../platform/c++11/src/nsync_panic.cc PLATFORM_OBJS=clock_gettime.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep_timespec.o nsync_panic.o TEST_PLATFORM_C=../../platform/c++11/src/start_thread.cc TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile time_rep_timespec_test.o: ../../platform/c++11/src/time_rep_timespec_test.cc; ${CC} ${CFLAGS} -I../../testing -c ../../platform/c++11/src/time_rep_timespec_test.cc time_rep_timespec_test: time_rep_timespec_test.o ${TEST_LIB} ${LIB}; ${CC} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} nsync-1.24.0/builds/x86_64.macos.c++11/dependfile000066400000000000000000000000001367521742200210030ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.clang.atm-c++11/000077500000000000000000000000001367521742200206355ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.clang.atm-c++11/Makefile000066400000000000000000000017461367521742200223050ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/clang -I../../platform/macos -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration PLATFORM_LDFLAGS=-pthread PLATFORM_CXXFLAGS=-Werror -Wall -Wextra -std=c++11 -pedantic PLATFORM_CXX=../../platform/c_from_c++11/src/nsync_atm_c++.cc MKDEP_DEPEND=mkdep MKDEP=./mkdep ${CC} -E -c++=-std=c++11 PLATFORM_C=../../platform/posix/src/clock_gettime.c ../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_atm_c++.o clock_gettime.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.macos.clang.atm-c++11/dependfile000066400000000000000000000000001367521742200226450ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.clang.atm-c11/000077500000000000000000000000001367521742200205075ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.clang.atm-c11/Makefile000066400000000000000000000014741367521742200221550ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -DNSYNC_ATOMIC_C11 -I../../platform/c11 -I../../platform/macos -I../../platform/clang -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/clock_gettime.c ../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=clock_gettime.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.macos.clang.atm-c11/dependfile000066400000000000000000000000001367521742200225170ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.clang.atm-os/000077500000000000000000000000001367521742200205445ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.clang.atm-os/Makefile000066400000000000000000000014611367521742200222060ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/macos -I../../platform/clang -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration -Wno-deprecated-declarations PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/clock_gettime.c ../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=clock_gettime.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.macos.clang.atm-os/dependfile000066400000000000000000000000001367521742200225540ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.clang.sem-gcd/000077500000000000000000000000001367521742200206635ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.clang.sem-gcd/Makefile000066400000000000000000000014201367521742200223200ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/clang -I../../platform/macos -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/clock_gettime.c ../../platform/macos/src/nsync_semaphore_gcd.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=clock_gettime.o nsync_semaphore_gcd.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.macos.clang.sem-gcd/dependfile000066400000000000000000000000001367521742200226730ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.clang/000077500000000000000000000000001367521742200173455ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.macos.clang/Makefile000066400000000000000000000014241367521742200210060ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/clang -I../../platform/macos -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/clock_gettime.c ../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=clock_gettime.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.macos.clang/dependfile000066400000000000000000000000001367521742200213550ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.netbsd.gcc.atm-asm/000077500000000000000000000000001367521742200205305ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.netbsd.gcc.atm-asm/Makefile000066400000000000000000000014361367521742200221740ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-I../../platform/atomic_ind -D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/netbsd -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_S=../../platform/x86_64/src/nsync_atm_x86_64.s PLATFORM_OBJS=nsync_atm_x86_64.o nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.netbsd.gcc.atm-asm/dependfile000066400000000000000000000000001367521742200225400ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.netbsd.gcc/000077500000000000000000000000001367521742200171725ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.netbsd.gcc/Makefile000066400000000000000000000012671367521742200206400ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc -I../../platform/netbsd -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.netbsd.gcc/dependfile000066400000000000000000000000001367521742200212020ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.openbsd.gcc/000077500000000000000000000000001367521742200173455ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.openbsd.gcc/Makefile000066400000000000000000000013241367521742200210050ustar00rootroot00000000000000PLATFORM_CPPFLAGS=-D_POSIX_C_SOURCE=200809L -I../../platform/gcc_no_tls -I../../platform/gcc -I../../platform/openbsd -I../../platform/x86_64 -I../../platform/posix -pthread PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic PLATFORM_LDFLAGS=-pthread MKDEP=${CC} -M PLATFORM_C=../../platform/posix/src/nsync_semaphore_mutex.c ../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c ../../platform/posix/src/time_rep.c ../../platform/posix/src/nsync_panic.c PLATFORM_OBJS=nsync_semaphore_mutex.o per_thread_waiter.o yield.o time_rep.o nsync_panic.o TEST_PLATFORM_C=../../platform/posix/src/start_thread.c TEST_PLATFORM_OBJS=start_thread.o include ../../platform/posix/make.common include dependfile nsync-1.24.0/builds/x86_64.openbsd.gcc/dependfile000066400000000000000000000000001367521742200213550ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.win32.c++11/000077500000000000000000000000001367521742200166335ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.win32.c++11/Makefile000066400000000000000000000202171367521742200202750ustar00rootroot00000000000000PLATFORM_CPPFLAGS=/I../../platform/msvc /I../../platform/c++11 /I../../platform/win32 /I../../platform/posix /DNSYNC_ATOMIC_CPP11 PLATFORM_CFLAGS=/nologo /MT /TP PLATFORM_CXXFLAGS=/nologo /MT PLATFORM_LDFLAGS=/nologo /MT PLATFORM_OBJS=nsync_semaphore_mutex.OBJ yield.OBJ per_thread_waiter.OBJ time_rep_timespec.OBJ nsync_panic.OBJ TEST_PLATFORM_OBJS=start_thread.OBJ pthread_key_win32.OBJ clock_gettime.OBJ # --------------------------------------------- PUBLIC=../../public INTERNAL=../../internal TESTING=../../testing OPT=/std:c++14 /EHsc CPPFLAGS=$(PLATFORM_CPPFLAGS) /I$(PUBLIC) /I$(INTERNAL) CFLAGS=$(CPPFLAGS) $(OPT) $(PLATFORM_CFLAGS) CXXFLAGS=$(CPPFLAGS) $(OPT) $(PLATFORM_CXXFLAGS) LDFLAGS=$(PLATFORM_LDFLAGS) PAR_SUB_COUNT=1 PAR_COUNT=2 TESTS=counter_test.EXE cv_mu_timeout_stress_test.EXE cv_test.EXE cv_wait_example_test.EXE dll_test.EXE mu_starvation_test.EXE mu_test.EXE mu_wait_example_test.EXE mu_wait_test.EXE note_test.EXE once_test.EXE pingpong_test.EXE wait_test.EXE TEST_OBJS=counter_test.OBJ cv_mu_timeout_stress_test.OBJ cv_test.OBJ cv_wait_example_test.OBJ dll_test.OBJ mu_starvation_test.OBJ mu_test.OBJ mu_wait_example_test.OBJ mu_wait_test.OBJ note_test.OBJ once_test.OBJ pingpong_test.OBJ wait_test.OBJ TEST_LIB_OBJS=array.OBJ atm_log.OBJ closure.OBJ time_extra.OBJ smprintf.OBJ testing.OBJ $(TEST_PLATFORM_OBJS) LIB_OBJS=common.OBJ counter.OBJ cv.OBJ debug.OBJ dll.OBJ mu.OBJ mu_wait.OBJ note.OBJ time_internal.OBJ once.OBJ sem_wait.OBJ wait.OBJ $(PLATFORM_OBJS) XLIB=nsync.LIB TEST_LIB=nsync_test.LIB all: $(XLIB) $(XLIB): $(LIB_OBJS) lib /nologo /out:$(XLIB) $(LIB_OBJS) $(TEST_LIB): $(TEST_LIB_OBJS) lib /nologo /out:$(TEST_LIB) $(TEST_LIB_OBJS) clean: del $(XLIB) $(TEST_LIB) $(TESTS) $(TEST_OBJS) $(TEST_LIB_OBJS) $(LIB_OBJS) \ mkdep.OBJ mkdep.EXE run_tests.OBJ run_tests.EXE tests: $(TESTS) test: tests run_tests.EXE run_tests -b $(TESTS) partest: tests run_tests.EXE run_tests -p $(PAR_COUNT) -n $(PAR_SUB_COUNT) -b $(TESTS) run_tests.EXE: ../../tools/run_tests.c $(CC) /nologo ../../tools/run_tests.c mkdep.EXE: ../../tools/mkdep.c $(CC) /nologo ../../tools/mkdep.c depend: mkdep.EXE mkdep $(CC) /nologo /E $(CPPFLAGS) 2> NUL \ $(INTERNAL)/common.c $(INTERNAL)/mu.c $(INTERNAL)/sem_wait.c \ $(INTERNAL)/counter.c $(INTERNAL)/mu_wait.c $(INTERNAL)/sem_wait_no_note.c \ $(INTERNAL)/cv.c $(INTERNAL)/debug.c $(INTERNAL)/note.c $(INTERNAL)/time_internal.c \ $(INTERNAL)/dll.c $(INTERNAL)/once.c $(INTERNAL)/wait.c \ $(TESTING)/array.c $(TESTING)/mu_test.c $(TESTING)/atm_log.c \ $(TESTING)/mu_wait_example_test.c $(TESTING)/closure.c $(TESTING)/mu_wait_test.c \ $(TESTING)/counter_test.c $(TESTING)/note_test.c $(TESTING)/once_test.c \ $(TESTING)/cv_mu_timeout_stress_test.c \ $(TESTING)/pingpong_test.c $(TESTING)/cv_test.c $(TESTING)/smprintf.c \ $(TESTING)/cv_wait_example_test.c $(TESTING)/testing.c $(TESTING)/dll_test.c \ $(TESTING)/time_extra.c $(TESTING)/mu_starvation_test.c $(TESTING)/wait_test.c \ $(PLATFORM_C) $(PLATFORM_CXX) $(TEST_PLATFORM_C) > dependfile nsync_semaphore_mutex.OBJ: ../../platform/c++11/src/nsync_semaphore_mutex.cc $(CXX) $(CXXFLAGS) /c ../../platform/c++11/src/nsync_semaphore_mutex.cc yield.OBJ: ../../platform/c++11/src/yield.cc $(CXX) $(CXXFLAGS) /c ../../platform/c++11/src/yield.cc per_thread_waiter.OBJ: ../../platform/c++11/src/per_thread_waiter.cc $(CXX) $(CXXFLAGS) /c ../../platform/c++11/src/per_thread_waiter.cc start_thread.OBJ: ../../platform/c++11/src/start_thread.cc $(CXX) $(CXXFLAGS) /c ../../platform/c++11/src/start_thread.cc clock_gettime.OBJ: ../../platform/win32/src/clock_gettime.c $(CC) $(CFLAGS) /c ../../platform/win32/src/clock_gettime.c time_rep_timespec.OBJ: ../../platform/c++11/src/time_rep_timespec.cc $(CC) $(CFLAGS) /c ../../platform/c++11/src/time_rep_timespec.cc nsync_panic.OBJ: ../../platform/c++11/src/nsync_panic.cc $(CXX) $(CXXFLAGS) /c ../../platform/c++11/src/nsync_panic.cc pthread_key_win32.OBJ: ../../platform/win32/src/pthread_key_win32.cc $(CXX) $(CXXFLAGS) /c ../../platform/win32/src/pthread_key_win32.cc common.OBJ: $(INTERNAL)/common.c; $(CC) $(CFLAGS) /c $(INTERNAL)/common.c counter.OBJ: $(INTERNAL)/counter.c; $(CC) $(CFLAGS) /c $(INTERNAL)/counter.c cv.OBJ: $(INTERNAL)/cv.c; $(CC) $(CFLAGS) /c $(INTERNAL)/cv.c debug.OBJ: $(INTERNAL)/debug.c; $(CC) $(CFLAGS) /c $(INTERNAL)/debug.c dll.OBJ: $(INTERNAL)/dll.c; $(CC) $(CFLAGS) /c $(INTERNAL)/dll.c mu.OBJ: $(INTERNAL)/mu.c; $(CC) $(CFLAGS) /c $(INTERNAL)/mu.c mu_wait.OBJ: $(INTERNAL)/mu_wait.c; $(CC) $(CFLAGS) /c $(INTERNAL)/mu_wait.c note.OBJ: $(INTERNAL)/note.c; $(CC) $(CFLAGS) /c $(INTERNAL)/note.c time_internal.OBJ: $(INTERNAL)/time_internal.c; $(CC) $(CFLAGS) /c $(INTERNAL)/time_internal.c once.OBJ: $(INTERNAL)/once.c; $(CC) $(CFLAGS) /c $(INTERNAL)/once.c sem_wait.OBJ: $(INTERNAL)/sem_wait.c; $(CC) $(CFLAGS) /c $(INTERNAL)/sem_wait.c wait.OBJ: $(INTERNAL)/wait.c; $(CC) $(CFLAGS) /c $(INTERNAL)/wait.c array.OBJ: $(TESTING)/array.c; $(CC) $(CFLAGS) /c $(TESTING)/array.c atm_log.OBJ: $(TESTING)/atm_log.c; $(CC) $(CFLAGS) /c $(TESTING)/atm_log.c closure.OBJ: $(TESTING)/closure.c; $(CC) $(CFLAGS) /c $(TESTING)/closure.c counter_test.OBJ: $(TESTING)/counter_test.c; $(CC) $(CFLAGS) /c $(TESTING)/counter_test.c cv_mu_timeout_stress_test.OBJ: $(TESTING)/cv_mu_timeout_stress_test.c; $(CC) $(CFLAGS) /c $(TESTING)/cv_mu_timeout_stress_test.c cv_test.OBJ: $(TESTING)/cv_test.c; $(CC) $(CFLAGS) /c $(TESTING)/cv_test.c cv_wait_example_test.OBJ: $(TESTING)/cv_wait_example_test.c; $(CC) $(CFLAGS) /c $(TESTING)/cv_wait_example_test.c dll_test.OBJ: $(TESTING)/dll_test.c; $(CC) $(CFLAGS) /c $(TESTING)/dll_test.c mu_starvation_test.OBJ: $(TESTING)/mu_starvation_test.c; $(CC) $(CFLAGS) /c $(TESTING)/mu_starvation_test.c mu_test.OBJ: $(TESTING)/mu_test.c; $(CC) $(CFLAGS) /c $(TESTING)/mu_test.c mu_wait_example_test.OBJ: $(TESTING)/mu_wait_example_test.c; $(CC) $(CFLAGS) /c $(TESTING)/mu_wait_example_test.c mu_wait_test.OBJ: $(TESTING)/mu_wait_test.c; $(CC) $(CFLAGS) /c $(TESTING)/mu_wait_test.c note_test.OBJ: $(TESTING)/note_test.c; $(CC) $(CFLAGS) /c $(TESTING)/note_test.c once_test.OBJ: $(TESTING)/once_test.c; $(CC) $(CFLAGS) /c $(TESTING)/once_test.c time_extra.OBJ: $(TESTING)/time_extra.c; $(CC) $(CFLAGS) /c $(TESTING)/time_extra.c pingpong_test.OBJ: $(TESTING)/pingpong_test.c; $(CC) $(CFLAGS) /c $(TESTING)/pingpong_test.c smprintf.OBJ: $(TESTING)/smprintf.c; $(CC) $(CFLAGS) /c $(TESTING)/smprintf.c testing.OBJ: $(TESTING)/testing.c; $(CC) $(CFLAGS) /c $(TESTING)/testing.c wait_test.OBJ: $(TESTING)/wait_test.c; $(CC) $(CFLAGS) /c $(TESTING)/wait_test.c counter_test.EXE: counter_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) counter_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) cv_mu_timeout_stress_test.EXE: cv_mu_timeout_stress_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) cv_mu_timeout_stress_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) cv_test.EXE: cv_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) cv_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) cv_wait_example_test.EXE: cv_wait_example_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) cv_wait_example_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) dll_test.EXE: dll_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) dll_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) mu_starvation_test.EXE: mu_starvation_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) mu_starvation_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) mu_test.EXE: mu_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) mu_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) mu_wait_example_test.EXE: mu_wait_example_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) mu_wait_example_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) mu_wait_test.EXE: mu_wait_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) mu_wait_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) note_test.EXE: note_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) note_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) once_test.EXE: once_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) once_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) pingpong_test.EXE: pingpong_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) pingpong_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) wait_test.EXE: wait_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) wait_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) include dependfile nsync-1.24.0/builds/x86_64.win32.c++11/dependfile000066400000000000000000000000001367521742200206430ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.win32.msvc/000077500000000000000000000000001367521742200170715ustar00rootroot00000000000000nsync-1.24.0/builds/x86_64.win32.msvc/Makefile000066400000000000000000000207611367521742200205370ustar00rootroot00000000000000PLATFORM_CPPFLAGS=/I../../platform/msvc /I../../platform/win32 /I../../platform/x86_64 /I../../platform/posix PLATFORM_CFLAGS=/nologo /MT PLATFORM_LDFLAGS=/nologo /MT PLATFORM_OBJS=nsync_semaphore_win32.OBJ pthread_cond_timedwait_win32.OBJ init_callback_win32.OBJ yield.OBJ per_thread_waiter.OBJ clock_gettime.OBJ nanosleep.OBJ time_rep.OBJ nsync_panic.OBJ pthread_key_win32.OBJ TEST_PLATFORM_OBJS=start_thread.OBJ # --------------------------------------------- PUBLIC=../../public INTERNAL=../../internal TESTING=../../testing OPT=/O2 CPPFLAGS=$(PLATFORM_CPPFLAGS) /I$(PUBLIC) /I$(INTERNAL) CFLAGS=$(CPPFLAGS) $(OPT) $(PLATFORM_CFLAGS) CXXFLAGS=$(CPPFLAGS) $(OPT) $(PLATFORM_CXXFLAGS) LDFLAGS=$(PLATFORM_LDFLAGS) PAR_SUB_COUNT=1 PAR_COUNT=2 TESTS=counter_test.EXE cv_mu_timeout_stress_test.EXE cv_test.EXE cv_wait_example_test.EXE dll_test.EXE mu_starvation_test.EXE mu_test.EXE mu_wait_example_test.EXE mu_wait_test.EXE note_test.EXE once_test.EXE pingpong_test.EXE wait_test.EXE TEST_OBJS=counter_test.OBJ cv_mu_timeout_stress_test.OBJ cv_test.OBJ cv_wait_example_test.OBJ dll_test.OBJ mu_starvation_test.OBJ mu_test.OBJ mu_wait_example_test.OBJ mu_wait_test.OBJ note_test.OBJ once_test.OBJ pingpong_test.OBJ wait_test.OBJ TEST_LIB_OBJS=array.OBJ atm_log.OBJ closure.OBJ time_extra.OBJ smprintf.OBJ testing.OBJ $(TEST_PLATFORM_OBJS) LIB_OBJS=common.OBJ counter.OBJ cv.OBJ debug.OBJ dll.OBJ mu.OBJ mu_wait.OBJ note.OBJ time_internal.OBJ once.OBJ sem_wait.OBJ wait.OBJ $(PLATFORM_OBJS) XLIB=nsync.LIB TEST_LIB=nsync_test.LIB all: $(XLIB) $(XLIB): $(LIB_OBJS) lib /nologo /out:$(XLIB) $(LIB_OBJS) $(TEST_LIB): $(TEST_LIB_OBJS) lib /nologo /out:$(TEST_LIB) $(TEST_LIB_OBJS) clean: del $(XLIB) $(TEST_LIB) $(TESTS) $(TEST_OBJS) $(TEST_LIB_OBJS) $(LIB_OBJS) \ mkdep.OBJ mkdep.EXE run_tests.OBJ run_tests.EXE tests: $(TESTS) test: tests run_tests.EXE run_tests -b $(TESTS) partest: tests run_tests.EXE run_tests -p $(PAR_COUNT) -n $(PAR_SUB_COUNT) -b $(TESTS) run_tests.EXE: ../../tools/run_tests.c $(CC) /nologo ../../tools/run_tests.c mkdep.EXE: ../../tools/mkdep.c $(CC) /nologo ../../tools/mkdep.c depend: mkdep.EXE mkdep $(CC) /nologo /E $(CPPFLAGS) 2> NUL \ $(INTERNAL)/common.c $(INTERNAL)/mu.c $(INTERNAL)/sem_wait.c \ $(INTERNAL)/counter.c $(INTERNAL)/mu_wait.c $(INTERNAL)/sem_wait_no_note.c \ $(INTERNAL)/cv.c $(INTERNAL)/debug.c $(INTERNAL)/note.c $(INTERNAL)/time_internal.c \ $(INTERNAL)/dll.c $(INTERNAL)/once.c $(INTERNAL)/wait.c \ $(TESTING)/array.c $(TESTING)/mu_test.c $(TESTING)/atm_log.c \ $(TESTING)/mu_wait_example_test.c $(TESTING)/closure.c $(TESTING)/mu_wait_test.c \ $(TESTING)/counter_test.c $(TESTING)/note_test.c $(TESTING)/once_test.c \ $(TESTING)/cv_mu_timeout_stress_test.c \ $(TESTING)/pingpong_test.c $(TESTING)/cv_test.c $(TESTING)/smprintf.c \ $(TESTING)/cv_wait_example_test.c $(TESTING)/testing.c $(TESTING)/dll_test.c \ $(TESTING)/time_extra.c $(TESTING)/mu_starvation_test.c $(TESTING)/wait_test.c \ $(PLATFORM_C) $(PLATFORM_CXX) $(TEST_PLATFORM_C) > dependfile nsync_semaphore_win32.OBJ: ../../platform/win32/src/nsync_semaphore_win32.c $(CC) $(CFLAGS) /c ../../platform/win32/src/nsync_semaphore_win32.c pthread_cond_timedwait_win32.OBJ: ../../platform/win32/src/pthread_cond_timedwait_win32.c $(CC) $(CFLAGS) /c ../../platform/win32/src/pthread_cond_timedwait_win32.c init_callback_win32.OBJ: ../../platform/win32/src/init_callback_win32.c $(CC) $(CFLAGS) /c ../../platform/win32/src/init_callback_win32.c yield.OBJ: ../../platform/posix/src/yield.c $(CC) $(CFLAGS) /c ../../platform/posix/src/yield.c per_thread_waiter.OBJ: ../../platform/posix/src/per_thread_waiter.c $(CC) $(CFLAGS) /c ../../platform/posix/src/per_thread_waiter.c start_thread.OBJ: ../../platform/win32/src/start_thread.c $(CC) $(CFLAGS) /c ../../platform/win32/src/start_thread.c clock_gettime.OBJ: ../../platform/win32/src/clock_gettime.c $(CC) $(CFLAGS) /c ../../platform/win32/src/clock_gettime.c nanosleep.OBJ: ../../platform/win32/src/nanosleep.c $(CC) $(CFLAGS) /c ../../platform/win32/src/nanosleep.c time_rep.OBJ: ../../platform/posix/src/time_rep.c $(CC) $(CFLAGS) /c ../../platform/posix/src/time_rep.c nsync_panic.OBJ: ../../platform/posix/src/nsync_panic.c $(CC) $(CFLAGS) /c ../../platform/posix/src/nsync_panic.c pthread_key_win32.OBJ: ../../platform/win32/src/pthread_key_win32.cc $(CC) $(CFLAGS) /c ../../platform/win32/src/pthread_key_win32.cc common.OBJ: $(INTERNAL)/common.c; $(CC) $(CFLAGS) /c $(INTERNAL)/common.c counter.OBJ: $(INTERNAL)/counter.c; $(CC) $(CFLAGS) /c $(INTERNAL)/counter.c cv.OBJ: $(INTERNAL)/cv.c; $(CC) $(CFLAGS) /c $(INTERNAL)/cv.c debug.OBJ: $(INTERNAL)/debug.c; $(CC) $(CFLAGS) /c $(INTERNAL)/debug.c dll.OBJ: $(INTERNAL)/dll.c; $(CC) $(CFLAGS) /c $(INTERNAL)/dll.c mu.OBJ: $(INTERNAL)/mu.c; $(CC) $(CFLAGS) /c $(INTERNAL)/mu.c mu_wait.OBJ: $(INTERNAL)/mu_wait.c; $(CC) $(CFLAGS) /c $(INTERNAL)/mu_wait.c note.OBJ: $(INTERNAL)/note.c; $(CC) $(CFLAGS) /c $(INTERNAL)/note.c time_internal.OBJ: $(INTERNAL)/time_internal.c; $(CC) $(CFLAGS) /c $(INTERNAL)/time_internal.c once.OBJ: $(INTERNAL)/once.c; $(CC) $(CFLAGS) /c $(INTERNAL)/once.c sem_wait.OBJ: $(INTERNAL)/sem_wait.c; $(CC) $(CFLAGS) /c $(INTERNAL)/sem_wait.c wait.OBJ: $(INTERNAL)/wait.c; $(CC) $(CFLAGS) /c $(INTERNAL)/wait.c array.OBJ: $(TESTING)/array.c; $(CC) $(CFLAGS) /c $(TESTING)/array.c atm_log.OBJ: $(TESTING)/atm_log.c; $(CC) $(CFLAGS) /c $(TESTING)/atm_log.c closure.OBJ: $(TESTING)/closure.c; $(CC) $(CFLAGS) /c $(TESTING)/closure.c counter_test.OBJ: $(TESTING)/counter_test.c; $(CC) $(CFLAGS) /c $(TESTING)/counter_test.c cv_mu_timeout_stress_test.OBJ: $(TESTING)/cv_mu_timeout_stress_test.c; $(CC) $(CFLAGS) /c $(TESTING)/cv_mu_timeout_stress_test.c cv_test.OBJ: $(TESTING)/cv_test.c; $(CC) $(CFLAGS) /c $(TESTING)/cv_test.c cv_wait_example_test.OBJ: $(TESTING)/cv_wait_example_test.c; $(CC) $(CFLAGS) /c $(TESTING)/cv_wait_example_test.c dll_test.OBJ: $(TESTING)/dll_test.c; $(CC) $(CFLAGS) /c $(TESTING)/dll_test.c mu_starvation_test.OBJ: $(TESTING)/mu_starvation_test.c; $(CC) $(CFLAGS) /c $(TESTING)/mu_starvation_test.c mu_test.OBJ: $(TESTING)/mu_test.c; $(CC) $(CFLAGS) /c $(TESTING)/mu_test.c mu_wait_example_test.OBJ: $(TESTING)/mu_wait_example_test.c; $(CC) $(CFLAGS) /c $(TESTING)/mu_wait_example_test.c mu_wait_test.OBJ: $(TESTING)/mu_wait_test.c; $(CC) $(CFLAGS) /c $(TESTING)/mu_wait_test.c note_test.OBJ: $(TESTING)/note_test.c; $(CC) $(CFLAGS) /c $(TESTING)/note_test.c once_test.OBJ: $(TESTING)/once_test.c; $(CC) $(CFLAGS) /c $(TESTING)/once_test.c time_extra.OBJ: $(TESTING)/time_extra.c; $(CC) $(CFLAGS) /c $(TESTING)/time_extra.c pingpong_test.OBJ: $(TESTING)/pingpong_test.c; $(CC) $(CFLAGS) /c $(TESTING)/pingpong_test.c smprintf.OBJ: $(TESTING)/smprintf.c; $(CC) $(CFLAGS) /c $(TESTING)/smprintf.c testing.OBJ: $(TESTING)/testing.c; $(CC) $(CFLAGS) /c $(TESTING)/testing.c wait_test.OBJ: $(TESTING)/wait_test.c; $(CC) $(CFLAGS) /c $(TESTING)/wait_test.c counter_test.EXE: counter_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) counter_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) cv_mu_timeout_stress_test.EXE: cv_mu_timeout_stress_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) cv_mu_timeout_stress_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) cv_test.EXE: cv_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) cv_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) cv_wait_example_test.EXE: cv_wait_example_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) cv_wait_example_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) dll_test.EXE: dll_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) dll_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) mu_starvation_test.EXE: mu_starvation_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) mu_starvation_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) mu_test.EXE: mu_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) mu_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) mu_wait_example_test.EXE: mu_wait_example_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) mu_wait_example_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) mu_wait_test.EXE: mu_wait_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) mu_wait_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) note_test.EXE: note_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) note_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) once_test.EXE: once_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) once_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) pingpong_test.EXE: pingpong_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) pingpong_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) wait_test.EXE: wait_test.OBJ $(TEST_LIB) $(XLIB); $(CC) $(LDFLAGS) wait_test.OBJ $(TEST_LIB) $(XLIB) $(PLATFORM_LIBS) include dependfile nsync-1.24.0/builds/x86_64.win32.msvc/dependfile000066400000000000000000000000001367521742200211010ustar00rootroot00000000000000nsync-1.24.0/internal/000077500000000000000000000000001367521742200145555ustar00rootroot00000000000000nsync-1.24.0/internal/common.c000066400000000000000000000226411367521742200162160ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* This package provides a mutex nsync_mu and a Mesa-style condition variable nsync_cv. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "atomic.h" #include "sem.h" #include "dll.h" #include "wait_internal.h" #include "common.h" NSYNC_CPP_START_ /* Implementation notes The implementations of nsync_mu and nsync_cv both use spinlocks to protect their waiter queues. The spinlocks are implemented with atomic operations and a delay loop found below. They could use pthread_mutex_t, but I wished to have an implementation independent of pthread mutexes and condition variables. nsync_mu and nsync_cv use the same type of doubly-linked list of waiters (see waiter.c). This allows waiters to be transferred from the cv queue to the mu queue when a thread is logically woken from the cv but would immediately go to sleep on the mu. See the wake_waiters() call. In mu, the "designated waker" is a thread that was waiting on mu, has been woken up, but as yet has neither acquired nor gone back to waiting. The presence of such a thread is indicated by the MU_DESIG_WAKER bit in the mu word. This bit allows the nsync_mu_unlock() code to avoid waking a second waiter when there's already one that will wake the next thread when the time comes. This speeds things up when the lock is heavily contended, and the critical sections are small. The weasel words "with high probability" in the specification of nsync_mu_trylock() and nsync_mu_rtrylock() prevent clients from believing that they can determine with certainty whether another thread has given up a lock yet. This, together with the requirement that a thread that acquired a mutex must release it (rather than it being released by another thread), prohibits clients from using mu as a sort of semaphore. The intent is that it be used only for traditional mutual exclusion, and that clients that need a semaphore should use one. This leaves room for certain future optimizations, and make it easier to apply detection of potential races via candidate lock-set algorithms, should that ever be desired. The nsync_mu_wait_with_deadline() and nsync_mu_wait_with_deadline() calls use an absolute rather than a relative timeout. This is less error prone, as described in the comment on nsync_cv_wait_with_deadline(). Alas, relative timeouts are seductive in trivial examples (such as tests). These are the first things that people try, so they are likely to be requested. If enough people complain we could give them that particular piece of rope. Excessive evaluations of the same wait condition are avoided by maintaining waiter.same_condition as a doubly-linked list of waiters with the same non-NULL wait condition that are also adjacent in the waiter list. This does well even with large numbers of threads if there is at most one wait condition that can be false at any given time (such as in a producer/consumer queue, which cannot be both empty and full simultaneously). One could imagine a queueing mechanism that would guarantee to evaluate each condition at most once per wakeup, but that would be substantially more complex, and would still degrade if the number of distinct wakeup conditions were high. So clients are advised to resort to condition variables if they have many distinct wakeup conditions. */ /* Used in spinloops to delay resumption of the loop. Usage: unsigned attempts = 0; while (try_something) { attempts = nsync_spin_delay_ (attempts); } */ unsigned nsync_spin_delay_ (unsigned attempts) { if (attempts < 7) { volatile int i; for (i = 0; i != 1 << attempts; i++) { } attempts++; } else { nsync_yield_ (); } return (attempts); } /* Spin until (*w & test) == 0, then atomically perform *w = ((*w | set) & ~clear), perform an acquire barrier, and return the previous value of *w. */ uint32_t nsync_spin_test_and_set_ (nsync_atomic_uint32_ *w, uint32_t test, uint32_t set, uint32_t clear) { unsigned attempts = 0; /* CV_SPINLOCK retry count */ uint32_t old = ATM_LOAD (w); while ((old & test) != 0 || !ATM_CAS_ACQ (w, old, (old | set) & ~clear)) { attempts = nsync_spin_delay_ (attempts); old = ATM_LOAD (w); } return (old); } /* ====================================================================================== */ struct nsync_waiter_s *nsync_dll_nsync_waiter_ (nsync_dll_element_ *e) { struct nsync_waiter_s *nw = (struct nsync_waiter_s *) e->container; ASSERT (nw->tag == NSYNC_WAITER_TAG); ASSERT (e == &nw->q); return (nw); } waiter *nsync_dll_waiter_ (nsync_dll_element_ *e) { struct nsync_waiter_s *nw = DLL_NSYNC_WAITER (e); waiter *w = CONTAINER (waiter, nw, nw); ASSERT ((nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0); ASSERT (w->tag == WAITER_TAG); ASSERT (e == &w->nw.q); return (w); } waiter *nsync_dll_waiter_samecond_ (nsync_dll_element_ *e) { waiter *w = (waiter *) e->container; ASSERT (w->tag == WAITER_TAG); ASSERT (e == &w->same_condition); return (w); } /* -------------------------------- */ static nsync_dll_list_ free_waiters = NULL; /* free_waiters points to a doubly-linked list of free waiter structs. */ static nsync_atomic_uint32_ free_waiters_mu; /* spinlock; protects free_waiters */ static THREAD_LOCAL waiter *waiter_for_thread; static void waiter_destroy (void *v) { waiter *w = (waiter *) v; IGNORE_RACES_START (); ASSERT ((w->flags & (WAITER_RESERVED|WAITER_IN_USE)) == WAITER_RESERVED); w->flags &= ~WAITER_RESERVED; nsync_spin_test_and_set_ (&free_waiters_mu, 1, 1, 0); free_waiters = nsync_dll_make_first_in_list_ (free_waiters, &w->nw.q); ATM_STORE_REL (&free_waiters_mu, 0); /* release store */ IGNORE_RACES_END (); } /* If non-nil, nsync_malloc_ptr_ points to a malloc-like routine that allocated memory, used by mutex and condition variable code to allocate waiter structs. This would allow nsync's mutexes to be used inside an implementation of malloc(), by providing another, simpler allocator here. The intent is that the implicit NULL value here can be overridden by a client declaration that uses an initializer. */ void *(*nsync_malloc_ptr_) (size_t size); /* Return a pointer to an unused waiter struct. Ensures that the enclosed timer is stopped and its channel drained. */ waiter *nsync_waiter_new_ (void) { nsync_dll_element_ *q; waiter *tw; waiter *w; if (HAVE_THREAD_LOCAL) { tw = waiter_for_thread; } else { tw = (waiter *) nsync_per_thread_waiter_ (&waiter_destroy); } w = tw; if (w == NULL || (w->flags & (WAITER_RESERVED|WAITER_IN_USE)) != WAITER_RESERVED) { w = NULL; nsync_spin_test_and_set_ (&free_waiters_mu, 1, 1, 0); q = nsync_dll_first_ (free_waiters); if (q != NULL) { /* If free list is non-empty, dequeue an item. */ free_waiters = nsync_dll_remove_ (free_waiters, q); w = DLL_WAITER (q); } ATM_STORE_REL (&free_waiters_mu, 0); /* release store */ if (w == NULL) { /* If free list was empty, allocate an item. */ if (nsync_malloc_ptr_ != NULL) { /* Use client's malloc() */ w = (waiter *) (*nsync_malloc_ptr_) (sizeof (*w)); } else { /* standard malloc () */ w = (waiter *) malloc (sizeof (*w)); } w->tag = WAITER_TAG; w->nw.tag = NSYNC_WAITER_TAG; nsync_mu_semaphore_init (&w->sem); w->nw.sem = &w->sem; nsync_dll_init_ (&w->nw.q, &w->nw); NSYNC_ATOMIC_UINT32_STORE_ (&w->nw.waiting, 0); w->nw.flags = NSYNC_WAITER_FLAG_MUCV; ATM_STORE (&w->remove_count, 0); nsync_dll_init_ (&w->same_condition, w); w->flags = 0; } if (tw == NULL) { w->flags |= WAITER_RESERVED; nsync_set_per_thread_waiter_ (w, &waiter_destroy); if (HAVE_THREAD_LOCAL) { waiter_for_thread = w; } } } w->flags |= WAITER_IN_USE; return (w); } /* Return an unused waiter struct *w to the free pool. */ void nsync_waiter_free_ (waiter *w) { ASSERT ((w->flags & WAITER_IN_USE) != 0); w->flags &= ~WAITER_IN_USE; if ((w->flags & WAITER_RESERVED) == 0) { nsync_spin_test_and_set_ (&free_waiters_mu, 1, 1, 0); free_waiters = nsync_dll_make_first_in_list_ (free_waiters, &w->nw.q); ATM_STORE_REL (&free_waiters_mu, 0); /* release store */ } } /* ====================================================================================== */ /* writer_type points to a lock_type that describes how to manipulate a mu for a writer. */ static lock_type Xwriter_type = { MU_WZERO_TO_ACQUIRE, MU_WADD_TO_ACQUIRE, MU_WHELD_IF_NON_ZERO, MU_WSET_WHEN_WAITING, MU_WCLEAR_ON_ACQUIRE, MU_WCLEAR_ON_UNCONTENDED_RELEASE }; lock_type *nsync_writer_type_ = &Xwriter_type; /* reader_type points to a lock_type that describes how to manipulate a mu for a reader. */ static lock_type Xreader_type = { MU_RZERO_TO_ACQUIRE, MU_RADD_TO_ACQUIRE, MU_RHELD_IF_NON_ZERO, MU_RSET_WHEN_WAITING, MU_RCLEAR_ON_ACQUIRE, MU_RCLEAR_ON_UNCONTENDED_RELEASE }; lock_type *nsync_reader_type_ = &Xreader_type; NSYNC_CPP_END_ nsync-1.24.0/internal/common.h000066400000000000000000000312201367521742200162140ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_INTERNAL_COMMON_H_ #define NSYNC_INTERNAL_COMMON_H_ #include "nsync_cpp.h" #include "platform.h" #include "nsync_atomic.h" #include "sem.h" #include "nsync_waiter.h" #include "dll.h" #include "nsync_mu.h" #include "nsync_note.h" /* Annotations for race detectors. */ #if defined(__has_feature) && !defined(__SANITIZE_THREAD__) #if __has_feature(thread_sanitizer) /* used by clang */ #define __SANITIZE_THREAD__ 1 /* GCC uses this; fake it in clang */ #endif #endif #if defined(__SANITIZE_THREAD__) NSYNC_C_START_ void AnnotateIgnoreWritesBegin(const char* file, int line); void AnnotateIgnoreWritesEnd(const char* file, int line); void AnnotateIgnoreReadsBegin(const char* file, int line); void AnnotateIgnoreReadsEnd(const char* file, int line); NSYNC_C_END_ #define IGNORE_RACES_START() \ do { \ AnnotateIgnoreReadsBegin(__FILE__, __LINE__); \ AnnotateIgnoreWritesBegin(__FILE__, __LINE__); \ } while (0) #define IGNORE_RACES_END() \ do { \ AnnotateIgnoreWritesEnd(__FILE__, __LINE__); \ AnnotateIgnoreReadsEnd(__FILE__, __LINE__); \ } while (0) #else #define IGNORE_RACES_START() #define IGNORE_RACES_END() #endif #ifndef NSYNC_DEBUG #define NSYNC_DEBUG 0 #endif NSYNC_CPP_START_ /* Yield the CPU. Platform specific. */ void nsync_yield_ (void); /* Retrieve the per-thread cache of the waiter object. Platform specific. */ void *nsync_per_thread_waiter_ (void (*dest) (void *)); /* Set the per-thread cache of the waiter object. Platform specific. */ void nsync_set_per_thread_waiter_ (void *v, void (*dest) (void *)); /* Used in spinloops to delay resumption of the loop. Usage: unsigned attempts = 0; while (try_something) { attempts = nsync_spin_delay_ (attempts); } */ unsigned nsync_spin_delay_ (unsigned attempts); /* Spin until (*w & test) == 0, then atomically perform *w = ((*w | set) & ~clear), perform an acquire barrier, and return the previous value of *w. */ uint32_t nsync_spin_test_and_set_ (nsync_atomic_uint32_ *w, uint32_t test, uint32_t set, uint32_t clear); /* Abort after printing the nul-temrinated string s[]. */ void nsync_panic_ (const char *s); /* ---------- */ #define MIN_(a_,b_) ((a_) < (b_)? (a_) : (b_)) #define MAX_(a_,b_) ((a_) > (b_)? (a_) : (b_)) /* ---------- */ /* Fields in nsync_mu.word. - At least one of the MU_WLOCK or MU_RLOCK_FIELD fields must be zero. - MU_WLOCK indicates that a write lock is held. - MU_RLOCK_FIELD is a count of readers with read locks. - MU_SPINLOCK represents a spinlock that must be held when manipulating the waiter queue. - MU_DESIG_WAKER indicates that a former waiter has been woken, but has neither acquired the lock nor gone back to sleep. Legal to fail to set it; illegal to set it when no such waiter exists. - MU_WAITING indicates whether the waiter queue is non-empty. The following bits should be zero if MU_WAITING is zero. - MU_CONDITION indicates that some waiter may have an associated condition (from nsync_mu_wait, etc.). Legal to set it with no such waiter exists, but illegal to fail to set it with such a waiter. - MU_WRITER_WAITING indicates that a reader that has not yet blocked at least once should not acquire in order not to starve waiting writers. It set when a writer blocks or a reader is woken with a writer waiting. It is reset when a writer acquires, but set again when that writer releases if it wakes readers and there is a waiting writer. - MU_LONG_WAIT indicates that a waiter has been woken many times but repeatedly failed to acquire when competing for the lock. This is used only to prevent long-term starvation by writers. The thread that sets it clears it when if acquires. - MU_ALL_FALSE indicates that a complete scan of the waiter list found no waiters with true conditions, and the lock has not been acquired by a writer since then. This allows a reader lock to be released without testing conditions again. It is legal to fail to set this, but illegal to set it inappropriately. */ #define MU_WLOCK ((uint32_t) (1 << 0)) /* writer lock is held. */ #define MU_SPINLOCK ((uint32_t) (1 << 1)) /* spinlock is held (protects waiters). */ #define MU_WAITING ((uint32_t) (1 << 2)) /* waiter list is non-empty. */ #define MU_DESIG_WAKER ((uint32_t) (1 << 3)) /* a former waiter awoke, and hasn't yet acquired or slept anew */ #define MU_CONDITION ((uint32_t) (1 << 4)) /* the wait list contains some conditional waiters. */ #define MU_WRITER_WAITING ((uint32_t) (1 << 5)) /* there is a writer waiting */ #define MU_LONG_WAIT ((uint32_t) (1 << 6)) /* the waiter at the head of the queue has been waiting a long time */ #define MU_ALL_FALSE ((uint32_t) (1 << 7)) /* all waiter conditions are false */ #define MU_RLOCK ((uint32_t) (1 << 8)) /* low-order bit of reader count, which uses rest of word */ /* The constants below are derived from those above. */ #define MU_RLOCK_FIELD (~(uint32_t) (MU_RLOCK - 1)) /* mask of reader count field */ #define MU_ANY_LOCK (MU_WLOCK | MU_RLOCK_FIELD) /* mask for any lock held */ #define MU_WZERO_TO_ACQUIRE (MU_ANY_LOCK | MU_LONG_WAIT) /* bits to be zero to acquire write lock */ #define MU_WADD_TO_ACQUIRE (MU_WLOCK) /* add to acquire a write lock */ #define MU_WHELD_IF_NON_ZERO (MU_WLOCK) /* if any of these bits are set, write lock is held */ #define MU_WSET_WHEN_WAITING (MU_WAITING | MU_WRITER_WAITING) /* a writer is waiting */ #define MU_WCLEAR_ON_ACQUIRE (MU_WRITER_WAITING) /* clear MU_WRITER_WAITING when a writer acquires */ #define MU_WCLEAR_ON_UNCONTENDED_RELEASE (MU_ALL_FALSE) /* clear if a writer releases w/o waking */ /* bits to be zero to acquire read lock */ #define MU_RZERO_TO_ACQUIRE (MU_WLOCK | MU_WRITER_WAITING | MU_LONG_WAIT) #define MU_RADD_TO_ACQUIRE (MU_RLOCK) /* add to acquire a read lock */ #define MU_RHELD_IF_NON_ZERO (MU_RLOCK_FIELD) /* if any of these bits are set, read lock is held */ #define MU_RSET_WHEN_WAITING (MU_WAITING) /* indicate that some thread is waiting */ #define MU_RCLEAR_ON_ACQUIRE ((uint32_t) 0) /* nothing to clear when a read acquires */ #define MU_RCLEAR_ON_UNCONTENDED_RELEASE ((uint32_t) 0) /* nothing to clear when a read releases */ /* A lock_type holds the values needed to manipulate a mu in some mode (read or write). This allows some of the code to be generic, and parameterized by the lock type. */ typedef struct lock_type_s { uint32_t zero_to_acquire; /* bits that must be zero to acquire */ uint32_t add_to_acquire; /* constant to add to acquire */ uint32_t held_if_non_zero; /* if any of these bits are set, the lock is held */ uint32_t set_when_waiting; /* set when thread waits */ uint32_t clear_on_acquire; /* clear when thread acquires */ uint32_t clear_on_uncontended_release; /* clear when thread releases without waking */ } lock_type; /* writer_type points to a lock_type that describes how to manipulate a mu for a writer. */ extern lock_type *nsync_writer_type_; /* reader_type points to a lock_type that describes how to manipulate a mu for a reader. */ extern lock_type *nsync_reader_type_; /* ---------- */ /* Bits in nsync_cv.word */ #define CV_SPINLOCK ((uint32_t) (1 << 0)) /* protects waiters */ #define CV_NON_EMPTY ((uint32_t) (1 << 1)) /* waiters list is non-empty */ /* ---------- */ /* Hold a pair of condition function and its argument. */ struct wait_condition_s { int (*f) (const void *v); const void *v; int (*eq) (const void *a, const void *b); }; /* Return whether wait conditions *a_ and *b_ are equal and non-null. */ #define WAIT_CONDITION_EQ(a_, b_) ((a_)->f != NULL && (a_)->f == (b_)->f && \ ((a_)->v == (b_)->v || \ ((a_)->eq != NULL && (*(a_)->eq) ((a_)->v, (b_)->v)))) /* If a waiter has waited this many times, it may set the MU_LONG_WAIT bit. */ #define LONG_WAIT_THRESHOLD 30 /* ---------- */ #define NOTIFIED_TIME(n_) (ATM_LOAD_ACQ (&(n_)->notified) != 0? nsync_time_zero : \ (n_)->expiry_time_valid? (n_)->expiry_time : nsync_time_no_deadline) /* A waiter represents a single waiter on a cv or a mu. To wait: Allocate a waiter struct *w with new_waiter(), set w.waiting=1, and w.cv_mu=nil or to the associated mu if waiting on a condition variable, then queue w.nsync_dll on some queue, and then wait using: while (ATM_LOAD_ACQ (&w.waiting) != 0) { nsync_mu_semaphore_p (&w.sem); } Return *w to the freepool by calling free_waiter (w). To wakeup: Remove *w from the relevant queue then: ATM_STORE_REL (&w.waiting, 0); nsync_mu_semaphore_v (&w.sem); */ typedef struct { uint32_t tag; /* debug DLL_NSYNC_WAITER, DLL_WAITER, DLL_WAITER_SAMECOND */ nsync_semaphore sem; /* Thread waits on this semaphore. */ struct nsync_waiter_s nw; /* An embedded nsync_waiter_s. */ struct nsync_mu_s_ *cv_mu; /* pointer to nsync_mu associated with a cv wait */ lock_type *l_type; /* Lock type of the mu, or nil if not associated with a mu. */ nsync_atomic_uint32_ remove_count; /* count of removals from queue */ struct wait_condition_s cond; /* A condition on which to acquire a mu. */ nsync_dll_element_ same_condition; /* Links neighbours in nw.q with same non-nil condition. */ int flags; /* see WAITER_* bits below */ } waiter; static const uint32_t WAITER_TAG = 0x0590239f; static const uint32_t NSYNC_WAITER_TAG = 0x726d2ba9; #define WAITER_RESERVED 0x1 /* waiter reserved by a thread, even when not in use */ #define WAITER_IN_USE 0x2 /* waiter in use by a thread */ #define CONTAINER(t_,f_,p_) ((t_ *) (((char *) (p_)) - offsetof (t_, f_))) #define ASSERT(x) do { if (!(x)) { *(volatile int *)0 = 0; } } while (0) /* Return a pointer to the nsync_waiter_s containing nsync_dll_element_ *e. */ #define DLL_NSYNC_WAITER(e) (NSYNC_DEBUG? nsync_dll_nsync_waiter_ (e) : \ ((struct nsync_waiter_s *)((e)->container))) struct nsync_waiter_s *nsync_dll_nsync_waiter_ (nsync_dll_element_ *e); /* Return a pointer to the waiter struct that *e is embedded in, where *e is an nw.q field. */ #define DLL_WAITER(e) (NSYNC_DEBUG? nsync_dll_waiter_ (e) : \ CONTAINER (waiter, nw, DLL_NSYNC_WAITER(e))) waiter *nsync_dll_waiter_ (nsync_dll_element_ *e); /* Return a pointer to the waiter struct that *e is embedded in, where *e is a same_condition field. */ #define DLL_WAITER_SAMECOND(e) (NSYNC_DEBUG? nsync_dll_waiter_samecond_ (e) : \ ((waiter *) ((e)->container))) waiter *nsync_dll_waiter_samecond_ (nsync_dll_element_ *e); /* Return a pointer to an unused waiter struct. Ensures that the enclosed timer is stopped and its channel drained. */ waiter *nsync_waiter_new_ (void); /* Return an unused waiter struct *w to the free pool. */ void nsync_waiter_free_ (waiter *w); /* ---------- */ /* The internals of an nync_note. See internal/note.c for details of locking discipline. */ struct nsync_note_s_ { nsync_dll_element_ parent_child_link; /* parent's children, under parent->note_mu */ int expiry_time_valid; /* whether expiry_time is valid; r/o after init */ nsync_time expiry_time; /* expiry time, if expiry_time_valid != 0; r/o after init */ nsync_mu note_mu; /* protects fields below except "notified" */ nsync_cv no_children_cv; /* signalled when children becomes empty */ uint32_t disconnecting; /* non-zero => node is being disconnected */ nsync_atomic_uint32_ notified; /* non-zero if the note has been notified */ struct nsync_note_s_ *parent; /* points to parent, if any */ nsync_dll_element_ *children; /* list of children */ nsync_dll_element_ *waiters; /* list of waiters */ }; /* ---------- */ void nsync_mu_lock_slow_ (nsync_mu *mu, waiter *w, uint32_t clear, lock_type *l_type); void nsync_mu_unlock_slow_ (nsync_mu *mu, lock_type *l_type); nsync_dll_list_ nsync_remove_from_mu_queue_ (nsync_dll_list_ mu_queue, nsync_dll_element_ *e); void nsync_maybe_merge_conditions_ (nsync_dll_element_ *p, nsync_dll_element_ *n); nsync_time nsync_note_notified_deadline_ (nsync_note n); int nsync_sem_wait_with_cancel_ (waiter *w, nsync_time abs_deadline, nsync_note cancel_note); NSYNC_CPP_END_ #endif /*NSYNC_INTERNAL_COMMON_H_*/ nsync-1.24.0/internal/counter.c000066400000000000000000000103621367521742200164020ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "atomic.h" #include "dll.h" #include "sem.h" #include "wait_internal.h" #include "common.h" NSYNC_CPP_START_ /* Internal details of nsync_counter. */ struct nsync_counter_s_ { nsync_atomic_uint32_ waited; /* wait has been called */ nsync_mu counter_mu; /* protects fields below except reads of "value" */ nsync_atomic_uint32_ value; /* value of counter */ struct nsync_dll_element_s_ *waiters; /* list of waiters */ }; nsync_counter nsync_counter_new (uint32_t value) { nsync_counter c = (nsync_counter) malloc (sizeof (*c)); if (c != NULL) { memset ((void *) c, 0, sizeof (*c)); ATM_STORE (&c->value, value); } return (c); } void nsync_counter_free (nsync_counter c) { nsync_mu_lock (&c->counter_mu); ASSERT (nsync_dll_is_empty_ (c->waiters)); nsync_mu_unlock (&c->counter_mu); free (c); } uint32_t nsync_counter_add (nsync_counter c, int32_t delta) { uint32_t value; IGNORE_RACES_START (); if (delta == 0) { value = ATM_LOAD_ACQ (&c->value); } else { nsync_mu_lock (&c->counter_mu); do { value = ATM_LOAD (&c->value); } while (!ATM_CAS_RELACQ (&c->value, value, value+delta)); value += delta; if (delta > 0) { /* It's illegal to increase the count from zero if there has been a waiter. */ ASSERT (value != (uint32_t) delta || !ATM_LOAD (&c->waited)); ASSERT (value > value - delta); /* Crash on overflow. */ } else { ASSERT (value < value - delta); /* Crash on overflow. */ } if (value == 0) { nsync_dll_element_ *p; while ((p = nsync_dll_first_ (c->waiters)) != NULL) { struct nsync_waiter_s *nw = DLL_NSYNC_WAITER (p); c->waiters = nsync_dll_remove_ (c->waiters, p); ATM_STORE_REL (&nw->waiting, 0); nsync_mu_semaphore_v (nw->sem); } } nsync_mu_unlock (&c->counter_mu); } IGNORE_RACES_END (); return (value); } uint32_t nsync_counter_value (nsync_counter c) { uint32_t result; IGNORE_RACES_START (); result = ATM_LOAD_ACQ (&c->value); IGNORE_RACES_END (); return (result); } uint32_t nsync_counter_wait (nsync_counter c, nsync_time abs_deadline) { struct nsync_waitable_s waitable; struct nsync_waitable_s *pwaitable = &waitable; uint32_t result = 0; waitable.v = c; waitable.funcs = &nsync_counter_waitable_funcs; if (nsync_wait_n (NULL, NULL, NULL, abs_deadline, 1, &pwaitable) != 0) { IGNORE_RACES_START (); result = ATM_LOAD_ACQ (&c->value); IGNORE_RACES_END (); } return (result); } static nsync_time counter_ready_time (void *v, struct nsync_waiter_s *nw UNUSED) { nsync_counter c = (nsync_counter) v; nsync_time r; ATM_STORE (&c->waited, 1); r = (ATM_LOAD_ACQ (&c->value) == 0? nsync_time_zero : nsync_time_no_deadline); return (r); } static int counter_enqueue (void *v, struct nsync_waiter_s *nw) { nsync_counter c = (nsync_counter) v; int32_t value; nsync_mu_lock (&c->counter_mu); value = ATM_LOAD_ACQ (&c->value); if (value != 0) { c->waiters = nsync_dll_make_last_in_list_ (c->waiters, &nw->q); ATM_STORE (&nw->waiting, 1); } else { ATM_STORE (&nw->waiting, 0); } nsync_mu_unlock (&c->counter_mu); return (value != 0); } static int counter_dequeue (void *v, struct nsync_waiter_s *nw) { nsync_counter c = (nsync_counter) v; int32_t value; nsync_mu_lock (&c->counter_mu); value = ATM_LOAD_ACQ (&c->value); if (ATM_LOAD_ACQ (&nw->waiting) != 0) { c->waiters = nsync_dll_remove_ (c->waiters, &nw->q); ATM_STORE (&nw->waiting, 0); } nsync_mu_unlock (&c->counter_mu); return (value != 0); } const struct nsync_waitable_funcs_s nsync_counter_waitable_funcs = { &counter_ready_time, &counter_enqueue, &counter_dequeue }; NSYNC_CPP_END_ nsync-1.24.0/internal/cv.c000066400000000000000000000450351367521742200153400ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "dll.h" #include "sem.h" #include "wait_internal.h" #include "common.h" #include "atomic.h" NSYNC_CPP_START_ /* Initialize *cv. */ void nsync_cv_init (nsync_cv *cv) { memset ((void *) cv, 0, sizeof (*cv)); } /* Wake the cv waiters in the circular list pointed to by to_wake_list, which may not be NULL. If the waiter is associated with a nsync_mu, the "wakeup" may consist of transferring the waiters to the nsync_mu's queue. Requires that every waiter is associated with the same mutex. all_readers indicates whether all the waiters on the list are readers. */ static void wake_waiters (nsync_dll_list_ to_wake_list, int all_readers) { nsync_dll_element_ *p = NULL; nsync_dll_element_ *next = NULL; nsync_dll_element_ *first_waiter = nsync_dll_first_ (to_wake_list); struct nsync_waiter_s *first_nw = DLL_NSYNC_WAITER (first_waiter); waiter *first_w = NULL; nsync_mu *pmu = NULL; if ((first_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0) { first_w = DLL_WAITER (first_waiter); pmu = first_w->cv_mu; } if (pmu != NULL) { /* waiter is associated with the nsync_mu *pmu. */ /* We will transfer elements of to_wake_list to *pmu if all of: - some thread holds the lock, and - *pmu's spinlock is not held, and - either *pmu cannot be acquired in the mode of the first waiter, or there's more than one thread on to_wake_list and not all are readers, and - we acquire the spinlock on the first try. The spinlock acquisition also marks *pmu as having waiters. The requirement that some thread holds the lock ensures that at least one of the transferred waiters will be woken. */ uint32_t old_mu_word = ATM_LOAD (&pmu->word); int first_cant_acquire = ((old_mu_word & first_w->l_type->zero_to_acquire) != 0); next = nsync_dll_next_ (to_wake_list, first_waiter); if ((old_mu_word&MU_ANY_LOCK) != 0 && (old_mu_word&MU_SPINLOCK) == 0 && (first_cant_acquire || (next != NULL && !all_readers)) && ATM_CAS_ACQ (&pmu->word, old_mu_word, (old_mu_word|MU_SPINLOCK|MU_WAITING) & ~MU_ALL_FALSE)) { uint32_t set_on_release = 0; /* For any waiter that should be transferred, rather than woken, move it from to_wake_list to pmu->waiters. */ int first_is_writer = first_w->l_type == nsync_writer_type_; int transferred_a_writer = 0; int woke_areader = 0; /* Transfer the first waiter iff it can't acquire *pmu. */ if (first_cant_acquire) { to_wake_list = nsync_dll_remove_ (to_wake_list, first_waiter); pmu->waiters = nsync_dll_make_last_in_list_ (pmu->waiters, first_waiter); /* tell nsync_cv_wait_with_deadline() that we moved the waiter to *pmu's queue. */ first_w->cv_mu = NULL; /* first_nw.waiting is already 1, from being on cv's waiter queue. */ transferred_a_writer = first_is_writer; } else { woke_areader = !first_is_writer; } /* Now process the other waiters. */ for (p = next; p != NULL; p = next) { int p_is_writer; struct nsync_waiter_s *p_nw = DLL_NSYNC_WAITER (p); waiter *p_w = NULL; if ((p_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0) { p_w = DLL_WAITER (p); } next = nsync_dll_next_ (to_wake_list, p); p_is_writer = (p_w != NULL && DLL_WAITER (p)->l_type == nsync_writer_type_); /* We transfer this element if any of: - the first waiter can't acquire *pmu, or - the first waiter is a writer, or - this element is a writer. */ if (p_w == NULL) { /* wake non-native waiter */ } else if (first_cant_acquire || first_is_writer || p_is_writer) { to_wake_list = nsync_dll_remove_ (to_wake_list, p); pmu->waiters = nsync_dll_make_last_in_list_ (pmu->waiters, p); /* tell nsync_cv_wait_with_deadline() that we moved the waiter to *pmu's queue. */ p_w->cv_mu = NULL; /* p_nw->waiting is already 1, from being on cv's waiter queue. */ transferred_a_writer = transferred_a_writer || p_is_writer; } else { woke_areader = woke_areader || !p_is_writer; } } /* Claim a waiting writer if we transferred one, except if we woke readers, in which case we want those readers to be able to acquire immediately. */ if (transferred_a_writer && !woke_areader) { set_on_release |= MU_WRITER_WAITING; } /* release *pmu's spinlock (MU_WAITING was set by CAS above) */ old_mu_word = ATM_LOAD (&pmu->word); while (!ATM_CAS_REL (&pmu->word, old_mu_word, (old_mu_word|set_on_release) & ~MU_SPINLOCK)) { old_mu_word = ATM_LOAD (&pmu->word); } } } /* Wake any waiters we didn't manage to enqueue on the mu. */ for (p = nsync_dll_first_ (to_wake_list); p != NULL; p = next) { struct nsync_waiter_s *p_nw = DLL_NSYNC_WAITER (p); next = nsync_dll_next_ (to_wake_list, p); to_wake_list = nsync_dll_remove_ (to_wake_list, p); /* Wake the waiter. */ ATM_STORE_REL (&p_nw->waiting, 0); /* release store */ nsync_mu_semaphore_v (p_nw->sem); } } /* ------------------------------------------ */ /* Versions of nsync_mu_lock() and nsync_mu_unlock() that take "void *" arguments, to avoid call through a function pointer of a different type, which is undefined. */ static void void_mu_lock (void *mu) { nsync_mu_lock ((nsync_mu *) mu); } static void void_mu_unlock (void *mu) { nsync_mu_unlock ((nsync_mu *) mu); } /* Atomically release *pmu (which must be held on entry) and block the calling thread on *pcv. Then wait until awakened by a call to nsync_cv_signal() or nsync_cv_broadcast() (or a spurious wakeup), or by the time reaching abs_deadline, or by cancel_note being notified. In all cases, reacquire *pmu, and return the reason for the call returned (0, ETIMEDOUT, or ECANCELED). Callers should abs_deadline==nsync_time_no_deadline for no deadline, and cancel_note==NULL for no cancellation. nsync_cv_wait_with_deadline() should be used in a loop, as with all Mesa-style condition variables. See examples above. There are two reasons for using an absolute deadline, rather than a relative timeout---these are why pthread_cond_timedwait() also uses an absolute deadline. First, condition variable waits have to be used in a loop; with an absolute times, the deadline does not have to be recomputed on each iteration. Second, in most real programmes, some activity (such as an RPC to a server, or when guaranteeing response time in a UI), there is a deadline imposed by the specification or the caller/user; relative delays can shift arbitrarily with scheduling delays, and so after multiple waits might extend beyond the expected deadline. Relative delays tend to be more convenient mostly in tests and trivial examples than they are in real programmes. */ int nsync_cv_wait_with_deadline_generic (nsync_cv *pcv, void *pmu, void (*lock) (void *), void (*unlock) (void *), nsync_time abs_deadline, nsync_note cancel_note) { nsync_mu *cv_mu = NULL; int is_reader_mu; uint32_t old_word; uint32_t remove_count; int sem_outcome; unsigned attempts; int outcome = 0; waiter *w; IGNORE_RACES_START (); w = nsync_waiter_new_ (); ATM_STORE (&w->nw.waiting, 1); w->cond.f = NULL; /* Not using a conditional critical section. */ w->cond.v = NULL; w->cond.eq = NULL; if (lock == &void_mu_lock || lock == (void (*) (void *)) &nsync_mu_lock || lock == (void (*) (void *)) &nsync_mu_rlock) { cv_mu = (nsync_mu *) pmu; } w->cv_mu = cv_mu; /* If *pmu is an nsync_mu, record its address, else record NULL. */ is_reader_mu = 0; /* If true, an nsync_mu in reader mode. */ if (cv_mu == NULL) { w->l_type = NULL; } else { uint32_t old_mu_word = ATM_LOAD (&cv_mu->word); int is_writer = (old_mu_word & MU_WHELD_IF_NON_ZERO) != 0; int is_reader = (old_mu_word & MU_RHELD_IF_NON_ZERO) != 0; if (is_writer) { if (is_reader) { nsync_panic_ ("mu held in reader and writer mode simultaneously " "on entry to nsync_cv_wait_with_deadline()\n"); } w->l_type = nsync_writer_type_; } else if (is_reader) { w->l_type = nsync_reader_type_; is_reader_mu = 1; } else { nsync_panic_ ("mu not held on entry to nsync_cv_wait_with_deadline()\n"); } } /* acquire spinlock, set non-empty */ old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK|CV_NON_EMPTY, 0); pcv->waiters = nsync_dll_make_last_in_list_ (pcv->waiters, &w->nw.q); remove_count = ATM_LOAD (&w->remove_count); /* Release the spin lock. */ ATM_STORE_REL (&pcv->word, old_word|CV_NON_EMPTY); /* release store */ /* Release *pmu. */ if (is_reader_mu) { nsync_mu_runlock (cv_mu); } else { (*unlock) (pmu); } /* wait until awoken or a timeout. */ sem_outcome = 0; attempts = 0; while (ATM_LOAD_ACQ (&w->nw.waiting) != 0) { /* acquire load */ if (sem_outcome == 0) { sem_outcome = nsync_sem_wait_with_cancel_ (w, abs_deadline, cancel_note); } if (sem_outcome != 0 && ATM_LOAD (&w->nw.waiting) != 0) { /* A timeout or cancellation occurred, and no wakeup. Acquire *pcv's spinlock, and confirm. */ old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0); /* Check that w wasn't removed from the queue after we checked above, but before we acquired the spinlock. The test of remove_count confirms that the waiter *w is still governed by *pcv's spinlock; otherwise, some other thread is about to set w.waiting==0. */ if (ATM_LOAD (&w->nw.waiting) != 0) { if (remove_count == ATM_LOAD (&w->remove_count)) { uint32_t old_value; /* still in cv waiter queue */ /* Not woken, so remove *w from cv queue, and declare a timeout/cancellation. */ outcome = sem_outcome; pcv->waiters = nsync_dll_remove_ (pcv->waiters, &w->nw.q); do { old_value = ATM_LOAD (&w->remove_count); } while (!ATM_CAS (&w->remove_count, old_value, old_value+1)); if (nsync_dll_is_empty_ (pcv->waiters)) { old_word &= ~(CV_NON_EMPTY); } ATM_STORE_REL (&w->nw.waiting, 0); /* release store */ } } /* Release spinlock. */ ATM_STORE_REL (&pcv->word, old_word); /* release store */ } if (ATM_LOAD (&w->nw.waiting) != 0) { /* The delay here causes this thread ultimately to yield to another that has dequeued this thread, but has not yet set the waiting field to zero; a cancellation or timeout may prevent this thread from blocking above on the semaphore. */ attempts = nsync_spin_delay_ (attempts); } } if (cv_mu != NULL && w->cv_mu == NULL) { /* waiter was moved to *pmu's queue, and woken. */ /* Requeue on *pmu using existing waiter struct; current thread is the designated waker. */ nsync_mu_lock_slow_ (cv_mu, w, MU_DESIG_WAKER, w->l_type); nsync_waiter_free_ (w); } else { /* Traditional case: We've woken from the cv, and need to reacquire *pmu. */ nsync_waiter_free_ (w); if (is_reader_mu) { nsync_mu_rlock (cv_mu); } else { (*lock) (pmu); } } IGNORE_RACES_END (); return (outcome); } /* Wake at least one thread if any are currently blocked on *pcv. If the chosen thread is a reader on an nsync_mu, wake all readers and, if possible, a writer. */ void nsync_cv_signal (nsync_cv *pcv) { IGNORE_RACES_START (); if ((ATM_LOAD_ACQ (&pcv->word) & CV_NON_EMPTY) != 0) { /* acquire load */ nsync_dll_list_ to_wake_list = NULL; /* waiters that we will wake */ int all_readers = 0; /* acquire spinlock */ uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0); if (!nsync_dll_is_empty_ (pcv->waiters)) { /* Point to first waiter that enqueued itself, and detach it from all others. */ struct nsync_waiter_s *first_nw; nsync_dll_element_ *first = nsync_dll_first_ (pcv->waiters); pcv->waiters = nsync_dll_remove_ (pcv->waiters, first); first_nw = DLL_NSYNC_WAITER (first); if ((first_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0) { uint32_t old_value; do { old_value = ATM_LOAD (&DLL_WAITER (first)->remove_count); } while (!ATM_CAS (&DLL_WAITER (first)->remove_count, old_value, old_value+1)); } to_wake_list = nsync_dll_make_last_in_list_ (to_wake_list, first); if ((first_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0 && DLL_WAITER (first)->l_type == nsync_reader_type_) { int woke_writer; /* If the first waiter is a reader, wake all readers, and if it's possible, one writer. This allows reader-regions to be added to a monitor without invalidating code in which a client has optimized broadcast calls by converting them to signal calls. In particular, we wake a writer when waking readers because the readers will not invalidate the condition that motivated the client to call nsync_cv_signal(). But we wake at most one writer because the first writer may invalidate the condition; the client is expecting only one writer to be able make use of the wakeup, or he would have called nsync_cv_broadcast(). */ nsync_dll_element_ *p = NULL; nsync_dll_element_ *next = NULL; all_readers = 1; woke_writer = 0; for (p = nsync_dll_first_ (pcv->waiters); p != NULL; p = next) { struct nsync_waiter_s *p_nw = DLL_NSYNC_WAITER (p); int should_wake; next = nsync_dll_next_ (pcv->waiters, p); should_wake = 0; if ((p_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0 && DLL_WAITER (p)->l_type == nsync_reader_type_) { should_wake = 1; } else if (!woke_writer) { woke_writer = 1; all_readers = 0; should_wake = 1; } if (should_wake) { pcv->waiters = nsync_dll_remove_ (pcv->waiters, p); if ((p_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0) { uint32_t old_value; do { old_value = ATM_LOAD ( &DLL_WAITER (p)->remove_count); } while (!ATM_CAS (&DLL_WAITER (p)->remove_count, old_value, old_value+1)); } to_wake_list = nsync_dll_make_last_in_list_ ( to_wake_list, p); } } } if (nsync_dll_is_empty_ (pcv->waiters)) { old_word &= ~(CV_NON_EMPTY); } } /* Release spinlock. */ ATM_STORE_REL (&pcv->word, old_word); /* release store */ if (!nsync_dll_is_empty_ (to_wake_list)) { wake_waiters (to_wake_list, all_readers); } } IGNORE_RACES_END (); } /* Wake all threads currently blocked on *pcv. */ void nsync_cv_broadcast (nsync_cv *pcv) { IGNORE_RACES_START (); if ((ATM_LOAD_ACQ (&pcv->word) & CV_NON_EMPTY) != 0) { /* acquire load */ nsync_dll_element_ *p; nsync_dll_element_ *next; int all_readers; nsync_dll_list_ to_wake_list = NULL; /* waiters that we will wake */ /* acquire spinlock */ nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0); p = NULL; next = NULL; all_readers = 1; /* Wake entire waiter list, which we leave empty. */ for (p = nsync_dll_first_ (pcv->waiters); p != NULL; p = next) { struct nsync_waiter_s *p_nw = DLL_NSYNC_WAITER (p); next = nsync_dll_next_ (pcv->waiters, p); all_readers = all_readers && (p_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0 && (DLL_WAITER (p)->l_type == nsync_reader_type_); pcv->waiters = nsync_dll_remove_ (pcv->waiters, p); if ((p_nw->flags & NSYNC_WAITER_FLAG_MUCV) != 0) { uint32_t old_value; do { old_value = ATM_LOAD (&DLL_WAITER (p)->remove_count); } while (!ATM_CAS (&DLL_WAITER (p)->remove_count, old_value, old_value+1)); } to_wake_list = nsync_dll_make_last_in_list_ (to_wake_list, p); } /* Release spinlock and mark queue empty. */ ATM_STORE_REL (&pcv->word, 0); /* release store */ if (!nsync_dll_is_empty_ (to_wake_list)) { /* Wake them. */ wake_waiters (to_wake_list, all_readers); } } IGNORE_RACES_END (); } /* Wait with deadline, using an nsync_mu. */ int nsync_cv_wait_with_deadline (nsync_cv *pcv, nsync_mu *pmu, nsync_time abs_deadline, nsync_note cancel_note) { return (nsync_cv_wait_with_deadline_generic (pcv, pmu, &void_mu_lock, &void_mu_unlock, abs_deadline, cancel_note)); } /* Atomically release *pmu and block the caller on *pcv. Wait until awakened by a call to nsync_cv_signal() or nsync_cv_broadcast(), or a spurious wakeup. Then reacquires *pmu, and return. The call is equivalent to a call to nsync_cv_wait_with_deadline() with abs_deadline==nsync_time_no_deadline, and a NULL cancel_note. It should be used in a loop, as with all standard Mesa-style condition variables. See examples above. */ void nsync_cv_wait (nsync_cv *pcv, nsync_mu *pmu) { nsync_cv_wait_with_deadline (pcv, pmu, nsync_time_no_deadline, NULL); } static nsync_time cv_ready_time (void *v UNUSED, struct nsync_waiter_s *nw) { nsync_time r; r = (nw == NULL || ATM_LOAD_ACQ (&nw->waiting) != 0? nsync_time_no_deadline : nsync_time_zero); return (r); } static int cv_enqueue (void *v, struct nsync_waiter_s *nw) { nsync_cv *pcv = (nsync_cv *) v; /* acquire spinlock */ uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0); pcv->waiters = nsync_dll_make_last_in_list_ (pcv->waiters, &nw->q); ATM_STORE (&nw->waiting, 1); /* Release spinlock. */ ATM_STORE_REL (&pcv->word, old_word | CV_NON_EMPTY); /* release store */ return (1); } static int cv_dequeue (void *v, struct nsync_waiter_s *nw) { nsync_cv *pcv = (nsync_cv *) v; int was_queued = 0; /* acquire spinlock */ uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0); if (ATM_LOAD_ACQ (&nw->waiting) != 0) { pcv->waiters = nsync_dll_remove_ (pcv->waiters, &nw->q); ATM_STORE (&nw->waiting, 0); was_queued = 1; } if (nsync_dll_is_empty_ (pcv->waiters)) { old_word &= ~(CV_NON_EMPTY); } /* Release spinlock. */ ATM_STORE_REL (&pcv->word, old_word); /* release store */ return (was_queued); } const struct nsync_waitable_funcs_s nsync_cv_waitable_funcs = { &cv_ready_time, &cv_enqueue, &cv_dequeue }; NSYNC_CPP_END_ nsync-1.24.0/internal/debug.c000066400000000000000000000255221367521742200160150ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Routines for debugging. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "dll.h" #include "sem.h" #include "wait_internal.h" #include "common.h" #include "atomic.h" NSYNC_CPP_START_ /* ---------- */ /* An emit_buf represents a buffer into which debug information can be written. */ struct emit_buf { char *start; /* start of buffer */ int len; /* pength of buffer */ int pos; /* position of next character to bve written */ int overflow; /* non-zero iff buffer overflow has occurred */ }; /* Initialize *b to point to start[0, .., len-1], and return b. of to an internal static buffer if buf==NULL. */ static struct emit_buf *emit_init (struct emit_buf *b, char *start, int len) { b->start = start; b->len = len; b->pos = 0; b->overflow = 0; return (b); } /* Write character c to buffer *b. */ static void emit_c (struct emit_buf *b, int c) { if (b->pos < b->len) { b->start[b->pos++] = c; } else if (!b->overflow) { static const char suffix[] = "..."; const char *s = &suffix[sizeof (suffix)]; /* past nul */ char *p = &b->start[b->len]; /* past end */ while (s > suffix && p > b->start) { *--p = *--s; } b->overflow = 1; } } /* A printf-like function that writes to an emit_buf. It understands only the format specifiers %s (const char *), and %i (uintptr_t in hex), with no modifiers. */ static void emit_print (struct emit_buf *b, const char *fmt, ...) { va_list ap; va_start (ap, fmt); while (*fmt != 0) { int c = *fmt++; if (c != '%') { emit_c (b, c); } else { c = *fmt++; if (c == 's') { const char *s = va_arg (ap, const char *); while (*s != 0) { emit_c (b, *s++); } } else if (c == 'i') { uintptr_t n = va_arg (ap, uintptr_t); int i; for (i = 0; (n >> i) >= 0x10; i += 4) { } for (; i >= 0; i -= 4) { emit_c (b, "0123456789abcdef"[(n >> i) & 0xf]); } } else { ASSERT (0); } } } va_end (ap); } /* Map a bit in a uint32_t to a human-readable name. */ struct bit_name { uint32_t mask; const char *name; }; /* names for bits in a mu word */ static const struct bit_name mu_bit[] = { { MU_WLOCK, "wlock" }, { MU_SPINLOCK, "spin" }, { MU_WAITING, "wait" }, { MU_DESIG_WAKER, "desig" }, { MU_CONDITION, "cond" }, { MU_WRITER_WAITING, "writer" }, { MU_LONG_WAIT, "long" }, { MU_ALL_FALSE, "false" }, { 0, "" } /* sentinel */ }; /* names for bits in a cv word */ static const struct bit_name cv_bit[] = { { CV_SPINLOCK, "spin" }, { CV_NON_EMPTY, "wait" }, { 0, "" } /* sentinel */ }; /* names for bits in a waiter flags word */ static const struct bit_name waiter_flags_bit[] = { { WAITER_RESERVED, "rsrvd" }, { WAITER_IN_USE, "in_use" }, { 0, "" } /* sentinel */ }; /* Emit the names of bits in word to buffer *b using names[] */ static void emit_word (struct emit_buf *b, const struct bit_name *name, uint32_t word) { int i; for (i = 0; name[i].mask != 0; i++) { if ((word & name[i].mask) != 0) { emit_print (b, " %s", name[i].name); } } } /* Emit the waiter queue *q to *b. */ static void emit_waiters (struct emit_buf *b, nsync_dll_list_ list) { nsync_dll_element_ *p = nsync_dll_first_ (list); nsync_dll_element_ *next; if (p != NULL) { emit_print (b, "\nwaiters =\n"); } for (; p != NULL && !b->overflow; p = next) { struct nsync_waiter_s *nw = DLL_NSYNC_WAITER (p); waiter *w = DLL_WAITER (p); next = NULL; emit_print (b, " %i", (uintptr_t) w); if (w->tag != WAITER_TAG) { emit_print (b, "bad WAITER_TAG %i", (uintptr_t) w->tag); } else { next = nsync_dll_next_ (list, p); if (nw->tag != NSYNC_WAITER_TAG) { emit_print (b, " bad WAITER_TAG %i", (uintptr_t) nw->tag); } else { emit_print (b, " embedded=%i waiting=%i", (uintptr_t) (w->flags & NSYNC_WAITER_FLAG_MUCV), (uintptr_t) ATM_LOAD (&nw->waiting)); } emit_word (b, waiter_flags_bit, w->flags); emit_print (b, " %s removes=%i cond=(%i %i %i)", w->l_type == nsync_writer_type_? "writer" : w->l_type == nsync_reader_type_? "reader" : "??????", (uintptr_t) ATM_LOAD (&w->remove_count), (uintptr_t) w->cond.f, (uintptr_t) w->cond.v, (uintptr_t) w->cond.eq); if (w->same_condition.next != &w->same_condition) { emit_print (b, " same_as %i", (uintptr_t) DLL_WAITER_SAMECOND ( w->same_condition.next)); } } emit_c (b, '\n'); } } /* Emit to *b the state of *mu, and return a pointer to *b's buffer. If blocking!=0, print_waiters!=0, and *mu's waiter list is non-empty, the call will block until it can acquire the spinlock. If print_waiters!=0, the waiter list is printed. The spinlock is released before return if it was acquired. blocking==0 && print_waiters!=0 is unsafe and is intended for use within interactive debuggers. */ static char *emit_mu_state (struct emit_buf *b, nsync_mu *mu, int blocking, int print_waiters) { uintptr_t word; uintptr_t readers; int acquired = 0; IGNORE_RACES_START (); word = ATM_LOAD (&mu->word); if ((word & MU_WAITING) != 0 && print_waiters && /* can benefit from lock */ (blocking || (word & MU_SPINLOCK) == 0)) { /* willing, or no need to wait */ word = nsync_spin_test_and_set_ (&mu->word, MU_SPINLOCK, MU_SPINLOCK, 0); acquired = 1; } readers = word / MU_RLOCK; emit_print (b, "mu 0x%i -> 0x%i = {", (uintptr_t) mu, word); emit_word (b, mu_bit, word); if (readers != 0) { emit_print (b, " readers=0x%i", readers); } emit_print (b, " }"); if (print_waiters) { emit_waiters (b, mu->waiters); } if (acquired) { ATM_STORE_REL (&mu->word, word); /* release store */ } emit_c (b, 0); IGNORE_RACES_END (); return (b->start); } /* Emit to *b the state of *cv, and return a pointer to *b's buffer. If blocking!=0, print_waiters!=0, and *cv's waiter list is non-empty, the call will block until it can acquire the spinlock. If print_waiters!=0, the waiter list is printed. The spinlock is released before return if it was acquired. blocking==0 && print_waiters!=0 is unsafe and is intended for use within interactive debuggers. */ static char *emit_cv_state (struct emit_buf *b, nsync_cv *cv, int blocking, int print_waiters) { uintptr_t word; int acquired = 0; IGNORE_RACES_START (); word = ATM_LOAD (&cv->word); if ((word & CV_NON_EMPTY) != 0 && print_waiters && /* can benefit from lock */ (blocking || (word & CV_SPINLOCK) == 0)) { /* willing, or no need to wait */ word = nsync_spin_test_and_set_ (&cv->word, CV_SPINLOCK, CV_SPINLOCK, 0); acquired = 1; } emit_print (b, "cv 0x%i -> 0x%i = {", (uintptr_t) cv, word); emit_word (b, cv_bit, word); emit_print (b, " }"); if (print_waiters) { emit_waiters (b, cv->waiters); } if (acquired) { ATM_STORE_REL (&cv->word, word); /* release store */ } emit_c (b, 0); IGNORE_RACES_END (); return (b->start); } char *nsync_mu_debug_state (nsync_mu *mu, char *buf, int n) { struct emit_buf b; return (emit_mu_state (emit_init (&b, buf, n), mu, 0, 0)); } char *nsync_cv_debug_state (nsync_cv *cv, char *buf, int n) { struct emit_buf b; return (emit_cv_state (emit_init (&b, buf, n), cv, 0, 0)); } char *nsync_mu_debug_state_and_waiters (nsync_mu *mu, char *buf, int n) { struct emit_buf b; return (emit_mu_state (emit_init (&b, buf, n), mu, 1, 1)); } char *nsync_cv_debug_state_and_waiters (nsync_cv *cv, char *buf, int n) { struct emit_buf b; return (emit_cv_state (emit_init (&b, buf, n), cv, 1, 1)); } static char nsync_debug_buf[1024]; char *nsync_mu_debugger (nsync_mu *mu) { struct emit_buf b; return (emit_mu_state (emit_init (&b, nsync_debug_buf, (int) sizeof (nsync_debug_buf)), mu, 0, 1)); } char *nsync_cv_debugger (nsync_cv *cv) { struct emit_buf b; return (emit_cv_state (emit_init (&b, nsync_debug_buf, (int) sizeof (nsync_debug_buf)), cv, 0, 1)); } NSYNC_CPP_END_ nsync-1.24.0/internal/dll.c000066400000000000000000000110761367521742200155010ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "dll.h" NSYNC_CPP_START_ /* Initialize *e. */ void nsync_dll_init_ (nsync_dll_element_ *e, void *container) { e->next = e; e->prev = e; e->container = container; } /* Return whether list is empty. */ int nsync_dll_is_empty_ (nsync_dll_list_ list) { return (list == NULL); } /* Remove *e from list, and returns the new list. */ nsync_dll_list_ nsync_dll_remove_ (nsync_dll_list_ list, nsync_dll_element_ *e) { if (list == e) { /* removing tail of list */ if (list->prev == list) { list = NULL; /* removing only element of list */ } else { list = list->prev; } } e->next->prev = e->prev; e->prev->next = e->next; e->next = e; e->prev = e; return (list); } /* Cause element *n and its successors to come after element *p. Requires n and p are non-NULL and do not point at elements of the same list. Unlike the other operations in this API, this operation acts on two circular lists of elements, rather than on a "head" location that points to such a circular list. If the two lists are p->p_2nd->p_mid->p_last->p and n->n_2nd->n_mid->n_last->n, then after nsync_dll_splice_after_ (p, n), the p list would be: p->n->n_2nd->n_mid->n_last->p_2nd->p_mid->p_last->p. */ void nsync_dll_splice_after_ (nsync_dll_element_ *p, nsync_dll_element_ *n) { nsync_dll_element_ *p_2nd = p->next; nsync_dll_element_ *n_last = n->prev; p->next = n; /* n follows p */ n->prev = p; n_last->next = p_2nd; /* remainder of p-list follows last of n-list */ p_2nd->prev = n_last; } /* Make element *e the first element of list, and return the list. The resulting list will have *e as its first element, followed by any elements in the same list as *e, followed by the elements that were previously in list. Requires that *e not be in list. If e==NULL, list is returned unchanged. Suppose the e list is e->e_2nd->e_mid->e_last->e. Recall that a head "list" points to the last element of its list. If list is initially null, then the outcome is: result = e_last->e->e_2nd->e_mid->e_last If list is initially list->list_last->list_1st->list_mid->list_last, then the outcome is: result = list_last->e->e_2nd->e_mid->e_last->list_1st->list_mid->list_last */ nsync_dll_list_ nsync_dll_make_first_in_list_ (nsync_dll_list_ list, nsync_dll_element_ *e) { if (e != NULL) { if (list == NULL) { list = e->prev; /*e->prev is e_last*/ } else { nsync_dll_splice_after_ (list, e); } } return (list); } /* Make element *e the last element of list, and return the list. The resulting list will have *e as its last element, preceded by any elements in the same list as *e, preceded by the elements that were previously in list. Requires that *e not be in list. If e==NULL, list is returned unchanged. */ nsync_dll_list_ nsync_dll_make_last_in_list_ (nsync_dll_list_ list, nsync_dll_element_ *e) { if (e != NULL) { nsync_dll_make_first_in_list_ (list, e->next); list = e; } return (list); } /* Return a pointer to the first element of list, or NULL if list is empty. */ nsync_dll_element_ *nsync_dll_first_ (nsync_dll_list_ list) { nsync_dll_element_ *first = NULL; if (list != NULL) { first = list->next; } return (first); } /* Return a pointer to the last element of list, or NULL if list is empty. */ nsync_dll_element_ *nsync_dll_last_ (nsync_dll_list_ list) { return (list); } /* Return a pointer to the next element of list following *e, or NULL if there is no such element. */ nsync_dll_element_ *nsync_dll_next_ (nsync_dll_list_ list, nsync_dll_element_ *e) { nsync_dll_element_ *next = NULL; if (e != list) { next = e->next; } return (next); } /* Return a pointer to the previous element of list following *e, or NULL if there is no such element. */ nsync_dll_element_ *nsync_dll_prev_ (nsync_dll_list_ list, nsync_dll_element_ *e) { nsync_dll_element_ *prev = NULL; if (e != list->next) { prev = e->prev; } return (prev); } NSYNC_CPP_END_ nsync-1.24.0/internal/dll.h000066400000000000000000000062531367521742200155070ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_INTERNAL_DLL_H_ #define NSYNC_INTERNAL_DLL_H_ /* Doubly linked lists. */ #include "nsync_cpp.h" NSYNC_CPP_START_ /* A nsync_dll_element_ represents an element of a doubly-linked list of waiters. */ typedef struct nsync_dll_element_s_ { struct nsync_dll_element_s_ *next; struct nsync_dll_element_s_ *prev; void *container; /* points to the struct this nsync_dll struct is embedded in. */ } nsync_dll_element_; /* A nsync_dll_list_ represents a list of nsync_dll_elements_. */ typedef nsync_dll_element_ *nsync_dll_list_; /* last elem of circular list; nil => empty; first is x.next. */ /* Initialize *e. */ void nsync_dll_init_ (nsync_dll_element_ *e, void *container); /* Return whether list is empty. */ int nsync_dll_is_empty_ (nsync_dll_list_ list); /* Remove *e from list, and returns the new list. */ nsync_dll_list_ nsync_dll_remove_ (nsync_dll_list_ list, nsync_dll_element_ *e); /* Cause element *n and its successors to come after element *p. Requires n and p are non-NULL and do not point at elements of the same list. */ void nsync_dll_splice_after_ (nsync_dll_element_ *p, nsync_dll_element_ *n); /* Make element *e the first element of list, and return the list. The resulting list will have *e as its first element, followed by any elements in the same list as *e, followed by the elements that were previously in list. Requires that *e not be in list. If e==NULL, list is returned unchanged. */ nsync_dll_list_ nsync_dll_make_first_in_list_ (nsync_dll_list_ list, nsync_dll_element_ *e); /* Make element *e the last element of list, and return the list. The resulting list will have *e as its last element, preceded by any elements in the same list as *e, preceded by the elements that were previously in list. Requires that *e not be in list. If e==NULL, list is returned unchanged. */ nsync_dll_list_ nsync_dll_make_last_in_list_ (nsync_dll_list_ list, nsync_dll_element_ *e); /* Return a pointer to the first element of list, or NULL if list is empty. */ nsync_dll_element_ *nsync_dll_first_ (nsync_dll_list_ list); /* Return a pointer to the last element of list, or NULL if list is empty. */ nsync_dll_element_ *nsync_dll_last_ (nsync_dll_list_ list); /* Return a pointer to the next element of list following *e, or NULL if there is no such element. */ nsync_dll_element_ *nsync_dll_next_ (nsync_dll_list_ list, nsync_dll_element_ *e); /* Return a pointer to the previous element of list following *e, or NULL if there is no such element. */ nsync_dll_element_ *nsync_dll_prev_ (nsync_dll_list_ list, nsync_dll_element_ *e); NSYNC_CPP_END_ #endif /*NSYNC_INTERNAL_DLL_H_*/ nsync-1.24.0/internal/headers.h000066400000000000000000000014721367521742200163450ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_INTERNAL_HEADERS_H_ #define NSYNC_INTERNAL_HEADERS_H_ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "atomic.h" #include "sem.h" #endif /*NSYNC_INTERNAL_HEADERS_H_*/ nsync-1.24.0/internal/mu.c000066400000000000000000000503621367521742200153500ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "dll.h" #include "sem.h" #include "wait_internal.h" #include "common.h" #include "atomic.h" NSYNC_CPP_START_ /* Initialize *mu. */ void nsync_mu_init (nsync_mu *mu) { memset ((void *) mu, 0, sizeof (*mu)); } /* Release the mutex spinlock. */ static void mu_release_spinlock (nsync_mu *mu) { uint32_t old_word = ATM_LOAD (&mu->word); while (!ATM_CAS_REL (&mu->word, old_word, old_word & ~MU_SPINLOCK)) { old_word = ATM_LOAD (&mu->word); } } /* Lock *mu using the specified lock_type, waiting on *w if necessary. "clear" should be zero if the thread has not previously slept on *mu, and MU_DESIG_WAKER if it has; this represents bits that nsync_mu_lock_slow_() must clear when it either acquires or sleeps on *mu. The caller owns *w on return; it is in a valid state to be returned to the free pool. */ void nsync_mu_lock_slow_ (nsync_mu *mu, waiter *w, uint32_t clear, lock_type *l_type) { uint32_t zero_to_acquire; uint32_t wait_count; uint32_t long_wait; unsigned attempts = 0; /* attempt count; used for spinloop backoff */ w->cv_mu = NULL; /* not a cv wait */ w->cond.f = NULL; /* Not using a conditional critical section. */ w->cond.v = NULL; w->cond.eq = NULL; w->l_type = l_type; zero_to_acquire = l_type->zero_to_acquire; if (clear != 0) { /* Only the constraints of mutual exclusion should stop a designated waker. */ zero_to_acquire &= ~(MU_WRITER_WAITING | MU_LONG_WAIT); } wait_count = 0; /* number of times we waited, and were woken. */ long_wait = 0; /* set to MU_LONG_WAIT when wait_count gets large */ for (;;) { uint32_t old_word = ATM_LOAD (&mu->word); if ((old_word & zero_to_acquire) == 0) { /* lock can be acquired; try to acquire, possibly clearing MU_DESIG_WAKER and MU_LONG_WAIT. */ if (ATM_CAS_ACQ (&mu->word, old_word, (old_word+l_type->add_to_acquire) & ~(clear|long_wait|l_type->clear_on_acquire))) { return; } } else if ((old_word&MU_SPINLOCK) == 0 && ATM_CAS_ACQ (&mu->word, old_word, (old_word|MU_SPINLOCK|long_wait| l_type->set_when_waiting) & ~(clear | MU_ALL_FALSE))) { /* Spinlock is now held, and lock is held by someone else; MU_WAITING has also been set; queue ourselves. There's no need to adjust same_condition here, because w.condition==NULL. */ ATM_STORE (&w->nw.waiting, 1); if (wait_count == 0) { /* first wait goes to end of queue */ mu->waiters = nsync_dll_make_last_in_list_ (mu->waiters, &w->nw.q); } else { /* subsequent waits go to front of queue */ mu->waiters = nsync_dll_make_first_in_list_ (mu->waiters, &w->nw.q); } /* Release spinlock. Cannot use a store here, because the current thread does not hold the mutex. If another thread were a designated waker, the mutex holder could be concurrently unlocking, even though we hold the spinlock. */ mu_release_spinlock (mu); /* wait until awoken. */ while (ATM_LOAD_ACQ (&w->nw.waiting) != 0) { /* acquire load */ nsync_mu_semaphore_p (&w->sem); } wait_count++; /* If the thread has been woken more than this many times, and still not acquired, it sets the MU_LONG_WAIT bit to prevent thread that have not waited from acquiring. This is the starvation avoidance mechanism. The number is fairly high so that we continue to benefit from the throughput of not having running threads wait unless absolutely necessary. */ if (wait_count == LONG_WAIT_THRESHOLD) { /* repeatedly woken */ long_wait = MU_LONG_WAIT; /* force others to wait at least once */ } attempts = 0; clear = MU_DESIG_WAKER; /* Threads that have been woken at least once don't care about waiting writers or long waiters. */ zero_to_acquire &= ~(MU_WRITER_WAITING | MU_LONG_WAIT); } attempts = nsync_spin_delay_ (attempts); } } /* Attempt to acquire *mu in writer mode without blocking, and return non-zero iff successful. Return non-zero with high probability if *mu was free on entry. */ int nsync_mu_trylock (nsync_mu *mu) { int result; IGNORE_RACES_START (); if (ATM_CAS_ACQ (&mu->word, 0, MU_WADD_TO_ACQUIRE)) { /* acquire CAS */ result = 1; } else { uint32_t old_word = ATM_LOAD (&mu->word); result = ((old_word & MU_WZERO_TO_ACQUIRE) == 0 && ATM_CAS_ACQ (&mu->word, old_word, (old_word + MU_WADD_TO_ACQUIRE) & ~MU_WCLEAR_ON_ACQUIRE)); } IGNORE_RACES_END (); return (result); } /* Block until *mu is free and then acquire it in writer mode. */ void nsync_mu_lock (nsync_mu *mu) { IGNORE_RACES_START (); if (!ATM_CAS_ACQ (&mu->word, 0, MU_WADD_TO_ACQUIRE)) { /* acquire CAS */ uint32_t old_word = ATM_LOAD (&mu->word); if ((old_word&MU_WZERO_TO_ACQUIRE) != 0 || !ATM_CAS_ACQ (&mu->word, old_word, (old_word+MU_WADD_TO_ACQUIRE) & ~MU_WCLEAR_ON_ACQUIRE)) { waiter *w = nsync_waiter_new_ (); nsync_mu_lock_slow_ (mu, w, 0, nsync_writer_type_); nsync_waiter_free_ (w); } } IGNORE_RACES_END (); } /* Attempt to acquire *mu in reader mode without blocking, and return non-zero iff successful. Returns non-zero with high probability if *mu was free on entry. It may fail to acquire if a writer is waiting, to avoid starvation. */ int nsync_mu_rtrylock (nsync_mu *mu) { int result; IGNORE_RACES_START (); if (ATM_CAS_ACQ (&mu->word, 0, MU_RADD_TO_ACQUIRE)) { /* acquire CAS */ result = 1; } else { uint32_t old_word = ATM_LOAD (&mu->word); result = ((old_word&MU_RZERO_TO_ACQUIRE) == 0 && ATM_CAS_ACQ (&mu->word, old_word, (old_word+MU_RADD_TO_ACQUIRE) & ~MU_RCLEAR_ON_ACQUIRE)); } IGNORE_RACES_END (); return (result); } /* Block until *mu can be acquired in reader mode and then acquire it. */ void nsync_mu_rlock (nsync_mu *mu) { IGNORE_RACES_START (); if (!ATM_CAS_ACQ (&mu->word, 0, MU_RADD_TO_ACQUIRE)) { /* acquire CAS */ uint32_t old_word = ATM_LOAD (&mu->word); if ((old_word&MU_RZERO_TO_ACQUIRE) != 0 || !ATM_CAS_ACQ (&mu->word, old_word, (old_word+MU_RADD_TO_ACQUIRE) & ~MU_RCLEAR_ON_ACQUIRE)) { waiter *w = nsync_waiter_new_ (); nsync_mu_lock_slow_ (mu, w, 0, nsync_reader_type_); nsync_waiter_free_ (w); } } IGNORE_RACES_END (); } /* Invoke the condition associated with *p, which is an element of a "waiter" list. */ static int condition_true (nsync_dll_element_ *p) { return ((*DLL_WAITER (p)->cond.f) (DLL_WAITER (p)->cond.v)); } /* If *p is an element of waiter_list (a list of "waiter" structs(, return a pointer to the next element of the list that has a different condition. */ static nsync_dll_element_ *skip_past_same_condition ( nsync_dll_list_ waiter_list, nsync_dll_element_ *p) { nsync_dll_element_ *next; nsync_dll_element_ *last_with_same_condition = &DLL_WAITER_SAMECOND (DLL_WAITER (p)->same_condition.prev)->nw.q; if (last_with_same_condition != p && last_with_same_condition != p->prev) { /* First in set with same condition, so skip to end. */ next = nsync_dll_next_ (waiter_list, last_with_same_condition); } else { next = nsync_dll_next_ (waiter_list, p); } return (next); } /* Merge the same_condition lists of *p and *n if they have the same non-NULL condition. */ void nsync_maybe_merge_conditions_ (nsync_dll_element_ *p, nsync_dll_element_ *n) { if (p != NULL && n != NULL && WAIT_CONDITION_EQ (&DLL_WAITER (p)->cond, &DLL_WAITER (n)->cond)) { nsync_dll_splice_after_ (&DLL_WAITER (p)->same_condition, &DLL_WAITER (n)->same_condition); } } /* Remove element *e from nsync_mu waiter queue mu_queue, fixing up the same_condition list by merging the lists on either side if possible. Also increment the waiter's remove_count. */ nsync_dll_list_ nsync_remove_from_mu_queue_ (nsync_dll_list_ mu_queue, nsync_dll_element_ *e) { /* Record previous and next elements in the original queue. */ nsync_dll_element_ *prev = e->prev; nsync_dll_element_ *next = e->next; uint32_t old_value; /* Remove. */ mu_queue = nsync_dll_remove_ (mu_queue, e); do { old_value = ATM_LOAD (&DLL_WAITER (e)->remove_count); } while (!ATM_CAS (&DLL_WAITER (e)->remove_count, old_value, old_value+1)); if (!nsync_dll_is_empty_ (mu_queue)) { /* Fix up same_condition. */ nsync_dll_element_ *e_same_condition = &DLL_WAITER (e)->same_condition; if (e_same_condition->next != e_same_condition) { /* *e is linked to a same_condition neighbour---just remove it. */ e_same_condition->next->prev = e_same_condition->prev; e_same_condition->prev->next = e_same_condition->next; e_same_condition->next = e_same_condition; e_same_condition->prev = e_same_condition; } else if (prev != nsync_dll_last_ (mu_queue)) { /* Merge the new neighbours together if we can. */ nsync_maybe_merge_conditions_ (prev, next); } } return (mu_queue); } /* Unlock *mu and wake one or more waiters as appropriate after an unlock. It is called with *mu held in mode l_type. */ void nsync_mu_unlock_slow_ (nsync_mu *mu, lock_type *l_type) { unsigned attempts = 0; /* attempt count; used for backoff */ for (;;) { uint32_t old_word = ATM_LOAD (&mu->word); int testing_conditions = ((old_word & MU_CONDITION) != 0); uint32_t early_release_mu = l_type->add_to_acquire; uint32_t late_release_mu = 0; if (testing_conditions) { /* Convert to a writer lock, and release later. - A writer lock is currently needed to test conditions because exclusive access is needed to the list to allow modification. The spinlock cannot be used to achieve that, because an internal lock should not be held when calling the external predicates. - We must test conditions even though a reader region cannot have made any new ones true because some might have been true before the reader region started. The MU_ALL_FALSE test below shortcuts the case where the conditions are known all to be false. */ early_release_mu = l_type->add_to_acquire - MU_WLOCK; late_release_mu = MU_WLOCK; } if ((old_word&MU_WAITING) == 0 || (old_word&MU_DESIG_WAKER) != 0 || (old_word & MU_RLOCK_FIELD) > MU_RLOCK || (old_word & (MU_RLOCK|MU_ALL_FALSE)) == (MU_RLOCK|MU_ALL_FALSE)) { /* no one to wake, there's a designated waker waking up, there are still readers, or it's a reader and all waiters have false conditions */ if (ATM_CAS_REL (&mu->word, old_word, (old_word - l_type->add_to_acquire) & ~l_type->clear_on_uncontended_release)) { return; } } else if ((old_word&MU_SPINLOCK) == 0 && ATM_CAS_ACQ (&mu->word, old_word, (old_word-early_release_mu)|MU_SPINLOCK|MU_DESIG_WAKER)) { nsync_dll_list_ wake; lock_type *wake_type; uint32_t clear_on_release; uint32_t set_on_release; /* The spinlock is now held, and we've set the designated wake flag, since we're likely to wake a thread that will become that designated waker. If there are conditions to check, the mutex itself is still held. */ nsync_dll_element_ *p = NULL; nsync_dll_element_ *next = NULL; /* Swap the entire mu->waiters list into the local "new_waiters" list. This gives us exclusive access to the list, even if we unlock the spinlock, which we may do if checking conditions. The loop below will grab more new waiters that arrived while we were checking conditions, and terminates only if no new waiters arrive in one loop iteration. */ nsync_dll_list_ waiters = NULL; nsync_dll_list_ new_waiters = mu->waiters; mu->waiters = NULL; /* Remove a waiter from the queue, if possible. */ wake = NULL; /* waiters to wake. */ wake_type = NULL; /* type of waiter(s) on wake, or NULL if wake is empty. */ clear_on_release = MU_SPINLOCK; set_on_release = MU_ALL_FALSE; while (!nsync_dll_is_empty_ (new_waiters)) { /* some new waiters to consider */ p = nsync_dll_first_ (new_waiters); if (testing_conditions) { /* Should we continue to test conditions? */ if (wake_type == nsync_writer_type_) { /* No, because we're already waking a writer, and need wake no others.*/ testing_conditions = 0; } else if (wake_type == NULL && DLL_WAITER (p)->l_type != nsync_reader_type_ && DLL_WAITER (p)->cond.f == NULL) { /* No, because we've woken no one, but the first waiter is a writer with no condition, so we will certainly wake it, and need wake no others. */ testing_conditions = 0; } } /* If testing waiters' conditions, release the spinlock while still holding the write lock. This is so that the spinlock is not held while the conditions are evaluated. */ if (testing_conditions) { mu_release_spinlock (mu); } /* Process the new waiters picked up in this iteration of the "while (!nsync_dll_is_empty_ (new_waiters))" loop, and stop looking when we run out of waiters, or we find a writer to wake up. */ while (p != NULL && wake_type != nsync_writer_type_) { int p_has_condition; next = nsync_dll_next_ (new_waiters, p); p_has_condition = (DLL_WAITER (p)->cond.f != NULL); if (p_has_condition && !testing_conditions) { nsync_panic_ ("checking a waiter condition " "while unlocked\n"); } if (p_has_condition && !condition_true (p)) { /* condition is false */ /* skip to the end of the same_condition group. */ next = skip_past_same_condition (new_waiters, p); } else if (wake_type == NULL || DLL_WAITER (p)->l_type == nsync_reader_type_) { /* Wake this thread. */ new_waiters = nsync_remove_from_mu_queue_ ( new_waiters, p); wake = nsync_dll_make_last_in_list_ (wake, p); wake_type = DLL_WAITER (p)->l_type; } else { /* Failing to wake a writer that could acquire if it were first. */ set_on_release |= MU_WRITER_WAITING; set_on_release &= ~MU_ALL_FALSE; } p = next; } if (p != NULL) { /* Didn't search to end of list, so can't be sure all conditions are false. */ set_on_release &= ~MU_ALL_FALSE; } /* If testing waiters' conditions, reacquire the spinlock released above. */ if (testing_conditions) { nsync_spin_test_and_set_ (&mu->word, MU_SPINLOCK, MU_SPINLOCK, 0); } /* add the new_waiters to the last of the waiters. */ nsync_maybe_merge_conditions_ (nsync_dll_last_ (waiters), nsync_dll_first_ (new_waiters)); waiters = nsync_dll_make_last_in_list_ (waiters, nsync_dll_last_ (new_waiters)); /* Pick up the next set of new waiters. */ new_waiters = mu->waiters; mu->waiters = NULL; } /* Return the local waiter list to *mu. */ mu->waiters = waiters; if (nsync_dll_is_empty_ (wake)) { /* not waking a waiter => no designated waker */ clear_on_release |= MU_DESIG_WAKER; } if ((set_on_release & MU_ALL_FALSE) == 0) { /* If not explicitly setting MU_ALL_FALSE, clear it. */ clear_on_release |= MU_ALL_FALSE; } if (nsync_dll_is_empty_ (mu->waiters)) { /* no waiters left */ clear_on_release |= MU_WAITING | MU_WRITER_WAITING | MU_CONDITION | MU_ALL_FALSE; } /* Release the spinlock, and possibly the lock if late_release_mu is non-zero. Other bits are set or cleared according to whether we woke any threads, whether any waiters remain, and whether any of them are writers. */ old_word = ATM_LOAD (&mu->word); while (!ATM_CAS_REL (&mu->word, old_word, ((old_word-late_release_mu)|set_on_release) & ~clear_on_release)) { /* release CAS */ old_word = ATM_LOAD (&mu->word); } /* Wake the waiters. */ for (p = nsync_dll_first_ (wake); p != NULL; p = next) { next = nsync_dll_next_ (wake, p); wake = nsync_dll_remove_ (wake, p); ATM_STORE_REL (&DLL_NSYNC_WAITER (p)->waiting, 0); nsync_mu_semaphore_v (&DLL_WAITER (p)->sem); } return; } attempts = nsync_spin_delay_ (attempts); } } /* Unlock *mu, which must be held in write mode, and wake waiters, if appropriate. */ void nsync_mu_unlock (nsync_mu *mu) { IGNORE_RACES_START (); /* C is not a garbage-collected language, so we cannot release until we can be sure that we will not have to touch the mutex again to wake a waiter. Another thread could acquire, decrement a reference count and deallocate the mutex before the current thread touched the mutex word again. */ if (!ATM_CAS_REL (&mu->word, MU_WLOCK, 0)) { uint32_t old_word = ATM_LOAD (&mu->word); /* Clear MU_ALL_FALSE because the critical section we're just leaving may have made some conditions true. */ uint32_t new_word = (old_word - MU_WLOCK) & ~MU_ALL_FALSE; /* Sanity check: mutex must be held in write mode, and there must be no readers. */ if ((new_word & (MU_RLOCK_FIELD | MU_WLOCK)) != 0) { if ((old_word & MU_RLOCK_FIELD) != 0) { nsync_panic_ ("attempt to nsync_mu_unlock() an nsync_mu " "held in read mode\n"); } else { nsync_panic_ ("attempt to nsync_mu_unlock() an nsync_mu " "not held in write mode\n"); } } else if ((old_word & (MU_WAITING|MU_DESIG_WAKER)) == MU_WAITING || !ATM_CAS_REL (&mu->word, old_word, new_word)) { /* There are waiters and no designated waker, or our initial CAS attempt failed, to use slow path. */ nsync_mu_unlock_slow_ (mu, nsync_writer_type_); } } IGNORE_RACES_END (); } /* Unlock *mu, which must be held in read mode, and wake waiters, if appropriate. */ void nsync_mu_runlock (nsync_mu *mu) { IGNORE_RACES_START (); /* See comment in nsync_mu_unlock(). */ if (!ATM_CAS_REL (&mu->word, MU_RLOCK, 0)) { uint32_t old_word = ATM_LOAD (&mu->word); /* Sanity check: mutex must not be held in write mode and reader count must not be 0. */ if (((old_word ^ MU_WLOCK) & (MU_WLOCK | MU_RLOCK_FIELD)) == 0) { if ((old_word & MU_WLOCK) != 0) { nsync_panic_ ("attempt to nsync_mu_runlock() an nsync_mu " "held in write mode\n"); } else { nsync_panic_ ("attempt to nsync_mu_runlock() an nsync_mu " "not held in read mode\n"); } } else if ((old_word & (MU_WAITING | MU_DESIG_WAKER)) == MU_WAITING && (old_word & (MU_RLOCK_FIELD|MU_ALL_FALSE)) == MU_RLOCK) { /* There are waiters and no designated waker, the last reader is unlocking, and not all waiters have a false condition. So we must take the slow path to attempt to wake a waiter. */ nsync_mu_unlock_slow_ (mu, nsync_reader_type_); } else if (!ATM_CAS_REL (&mu->word, old_word, old_word - MU_RLOCK)) { /* CAS attempt failed, so take slow path. */ nsync_mu_unlock_slow_ (mu, nsync_reader_type_); } } IGNORE_RACES_END (); } /* Abort if *mu is not held in write mode. */ void nsync_mu_assert_held (const nsync_mu *mu) { IGNORE_RACES_START (); if ((ATM_LOAD (&mu->word) & MU_WHELD_IF_NON_ZERO) == 0) { nsync_panic_ ("nsync_mu not held in write mode\n"); } IGNORE_RACES_END (); } /* Abort if *mu is not held in read or write mode. */ void nsync_mu_rassert_held (const nsync_mu *mu) { IGNORE_RACES_START (); if ((ATM_LOAD (&mu->word) & MU_ANY_LOCK) == 0) { nsync_panic_ ("nsync_mu not held in some mode\n"); } IGNORE_RACES_END (); } /* Return whether *mu is held in read mode. Requires that *mu is held in some mode. */ int nsync_mu_is_reader (const nsync_mu *mu) { uint32_t word; IGNORE_RACES_START (); word = ATM_LOAD (&mu->word); if ((word & MU_ANY_LOCK) == 0) { nsync_panic_ ("nsync_mu not held in some mode\n"); } IGNORE_RACES_END (); return ((word & MU_WLOCK) == 0); } NSYNC_CPP_END_ nsync-1.24.0/internal/mu_wait.c000066400000000000000000000322051367521742200163700ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "dll.h" #include "sem.h" #include "wait_internal.h" #include "common.h" #include "atomic.h" NSYNC_CPP_START_ /* Attempt to remove waiter *w from *mu's waiter queue. If successful, leave the lock held in mode *l_type, and return non-zero; otherwise return zero. Requires that the current thread hold neither *mu nor its spinlock, that remove_count be the value of w.remove_count when *w was inserted into the queue (which it will still be if it has not been removed). This is a tricky part of the design. Here is the rationale. When a condition times out or is cancelled, we must "turn off" the condition, making it always true, so the lock will be acquired in the normal way. The naive approach would be to set a field atomically to tell future waiters to ignore the condition. Unfortunately, that would violate the same_condition list invariants, and the same_condition optimization is probably worth keeping. To fixup the same_condition list, we must have mutual exclusion with the loop in nsync_mu_unlock_slow_() that is examining waiters, evaluating their conditions, and removing them from the queue. That loop uses both the spinlock (to allow queue changes), and the mutex itself (to allow condition evaluation). Therefore, to "turn off" the condition requires acquiring both the spinlock and the mutex. This has two consequences: - If we must acquire *mu to "turn off" the condition, we might as well give the lock to this waiter and return from nsync_cv_wait_with_deadline() after we've done so. It would be wasted work to put it back on the waiter queue, and have it wake up and acquire yet again. (There are possibilities for starvation here that we ignore, under the assumption that the client avoids timeouts that are extremely short relative to the durations of his section durations.) - We can't use *w to wait for the lock to be free, because *w is already on the waiter queue with the wrong condition; we now want to wait with no condition. So either we must spin to acquire the lock, or we must allocate _another_ waiter object. The latter option is feasible, but delicate: the thread would have two waiter objects, and would have to handle being woken by either one or both, and possibly removing one that was not awoken. For the moment, we spin, because it's easier, and seems not to cause problems in practice, since the spinloop backs off aggressively. */ static int mu_try_acquire_after_timeout_or_cancel (nsync_mu *mu, lock_type *l_type, waiter *w, uint32_t remove_count) { int success = 0; unsigned spin_attempts = 0; uint32_t old_word = ATM_LOAD (&mu->word); /* Spin until we can acquire the spinlock and a writer lock on *mu. */ while ((old_word&(MU_WZERO_TO_ACQUIRE|MU_SPINLOCK)) != 0 || !ATM_CAS_ACQ (&mu->word, old_word, (old_word+MU_WADD_TO_ACQUIRE+MU_SPINLOCK) & ~MU_WCLEAR_ON_ACQUIRE)) { /* Failed to acquire. If we can, set the MU_WRITER_WAITING bit to avoid being starved by readers. */ if ((old_word & (MU_WRITER_WAITING | MU_SPINLOCK)) == 0) { /* If the following CAS succeeds, it effectively acquires and releases the spinlock atomically, so must be both an acquire and release barrier. MU_WRITER_WAITING will be cleared via MU_WCLEAR_ON_ACQUIRE when this loop succeeds. An optimization; failures are ignored. */ ATM_CAS_RELACQ (&mu->word, old_word, old_word|MU_WRITER_WAITING); } spin_attempts = nsync_spin_delay_ (spin_attempts); old_word = ATM_LOAD (&mu->word); } /* Check that w wasn't removed from the queue after our caller checked, but before we acquired the spinlock. The check of remove_count confirms that the waiter *w is still governed by *mu's spinlock. Otherwise, some other thread may be about to set w.waiting==0. */ if (ATM_LOAD (&w->nw.waiting) != 0 && remove_count == ATM_LOAD (&w->remove_count)) { /* This thread's condition is now irrelevant, and it holds a writer lock. Remove it from the queue, and possibly convert back to a reader lock. */ mu->waiters = nsync_remove_from_mu_queue_ (mu->waiters, &w->nw.q); ATM_STORE (&w->nw.waiting, 0); /* Release spinlock but keep desired lock type. */ ATM_STORE_REL (&mu->word, old_word+l_type->add_to_acquire); /* release store */ success = 1; } else { /* Release spinlock and *mu. */ ATM_STORE_REL (&mu->word, old_word); /* release store */ } return (success); } /* Return when at least one of: the condition is true, the deadline expires, or cancel_note is notified. It may unlock and relock *mu while blocked waiting for one of these events, but always returns with *mu held. It returns 0 iff the condition is true on return, and otherwise either ETIMEDOUT or ECANCELED, depending on why the call returned early. Use abs_deadline==nsync_time_no_deadline for no deadline, and cancel_note==NULL for no cancellation. Requires that *mu be held on entry. Requires that condition.eval() neither modify state protected by *mu, nor return a value dependent on state not protected by *mu. To depend on time, use the abs_deadline parameter. (Conventional use of condition variables have the same restrictions on the conditions tested by the while-loop.) The implementation calls condition.eval() only with *mu held, though not always from the calling thread, and may elect to hold only a read lock during the call, even if the client is attempting to acquire only write locks. The nsync_mu_wait() and nsync_mu_wait_with_deadline() calls can be used instead of condition variables. In many straightforward situations they are of equivalent performance and are somewhat easier to use, because unlike condition variables, they do not require that the waits be placed in a loop, and they do not require explicit wakeup calls. In the current implementation, use of nsync_mu_wait() and nsync_mu_wait_with_deadline() can take longer if many distinct wait conditions are used. In such cases, use an explicit condition variable per wakeup condition for best performance. */ int nsync_mu_wait_with_deadline (nsync_mu *mu, int (*condition) (const void *condition_arg), const void *condition_arg, int (*condition_arg_eq) (const void *a, const void *b), nsync_time abs_deadline, nsync_note cancel_note) { lock_type *l_type; int first_wait; int condition_is_true; waiter *w; int outcome; /* Work out in which mode the lock is held. */ uint32_t old_word; IGNORE_RACES_START (); old_word = ATM_LOAD (&mu->word); if ((old_word & MU_ANY_LOCK) == 0) { nsync_panic_ ("nsync_mu not held in some mode when calling " "nsync_mu_wait_with_deadline()\n"); } l_type = nsync_writer_type_; if ((old_word & MU_RHELD_IF_NON_ZERO) != 0) { l_type = nsync_reader_type_; } first_wait = 1; /* first time through the loop below. */ condition_is_true = (condition == NULL || (*condition) (condition_arg)); /* Loop until either the condition becomes true, or "outcome" indicates cancellation or timeout. */ w = NULL; outcome = 0; while (outcome == 0 && !condition_is_true) { uint32_t has_condition; uint32_t remove_count; uint32_t add_to_acquire; int had_waiters; int sem_outcome; unsigned attempts; int have_lock; if (w == NULL) { w = nsync_waiter_new_ (); /* get a waiter struct if we need one. */ } /* Prepare to wait. */ w->cv_mu = NULL; /* not a condition variable wait */ w->l_type = l_type; w->cond.f = condition; w->cond.v = condition_arg; w->cond.eq = condition_arg_eq; has_condition = 0; /* set to MU_CONDITION if condition is non-NULL */ if (condition != NULL) { has_condition = MU_CONDITION; } ATM_STORE (&w->nw.waiting, 1); remove_count = ATM_LOAD (&w->remove_count); /* Acquire spinlock. */ old_word = nsync_spin_test_and_set_ (&mu->word, MU_SPINLOCK, MU_SPINLOCK|MU_WAITING|has_condition, MU_ALL_FALSE); had_waiters = ((old_word & (MU_DESIG_WAKER | MU_WAITING)) == MU_WAITING); /* Queue the waiter. */ if (first_wait) { nsync_maybe_merge_conditions_ (nsync_dll_last_ (mu->waiters), &w->nw.q); /* first wait goes to end of queue */ mu->waiters = nsync_dll_make_last_in_list_ (mu->waiters, &w->nw.q); first_wait = 0; } else { nsync_maybe_merge_conditions_ (&w->nw.q, nsync_dll_first_ (mu->waiters)); /* subsequent waits go to front of queue */ mu->waiters = nsync_dll_make_first_in_list_ (mu->waiters, &w->nw.q); } /* Release spinlock and *mu. */ do { old_word = ATM_LOAD (&mu->word); add_to_acquire = l_type->add_to_acquire; if (((old_word-l_type->add_to_acquire)&MU_ANY_LOCK) == 0 && had_waiters) { add_to_acquire = 0; /* release happens in nsync_mu_unlock_slow_ */ } } while (!ATM_CAS_REL (&mu->word, old_word, (old_word - add_to_acquire) & ~MU_SPINLOCK)); if (add_to_acquire == 0) { /* The lock will be fully released, there are waiters, and no designated waker, so wake waiters. */ nsync_mu_unlock_slow_ (mu, l_type); } /* wait until awoken or a timeout. */ sem_outcome = 0; attempts = 0; have_lock = 0; while (ATM_LOAD_ACQ (&w->nw.waiting) != 0) { /* acquire load */ if (sem_outcome == 0) { sem_outcome = nsync_sem_wait_with_cancel_ (w, abs_deadline, cancel_note); if (sem_outcome != 0 && ATM_LOAD (&w->nw.waiting) != 0) { /* A timeout or cancellation occurred, and no wakeup. Acquire the spinlock and mu, and confirm. */ have_lock = mu_try_acquire_after_timeout_or_cancel ( mu, l_type, w, remove_count); if (have_lock) { /* Successful acquire. */ outcome = sem_outcome; } } } if (ATM_LOAD (&w->nw.waiting) != 0) { attempts = nsync_spin_delay_ (attempts); /* will ultimately yield */ } } if (!have_lock) { /* If we didn't reacquire due to a cancellation/timeout, acquire now. */ nsync_mu_lock_slow_ (mu, w, MU_DESIG_WAKER, l_type); } condition_is_true = (condition == NULL || (*condition) (condition_arg)); } if (w != NULL) { nsync_waiter_free_ (w); /* free waiter if we allocated one. */ } if (condition_is_true) { outcome = 0; /* condition is true trumps other outcomes. */ } IGNORE_RACES_END (); return (outcome); } /* Return when the condition is true. Perhaps unlock and relock *mu while blocked waiting for the condition to become true. It is equivalent to a call to nsync_mu_wait_with_deadline() with abs_deadline==nsync_time_no_deadline, and cancel_note==NULL. Requires that *mu be held on entry. Calls condition.eval() only with *mu held, though not always from the calling thread. See wait_with_deadline() for the restrictions on condition and performance considerations. */ void nsync_mu_wait (nsync_mu *mu, int (*condition) (const void *condition_arg), const void *condition_arg, int (*condition_arg_eq) (const void *a, const void *b)) { if (nsync_mu_wait_with_deadline (mu, condition, condition_arg, condition_arg_eq, nsync_time_no_deadline, NULL) != 0) { nsync_panic_ ("nsync_mu_wait woke but condition not true\n"); } } /* Unlock *mu, which must be held in write mode, and wake waiters, if appropriate. Unlike nsync_mu_unlock(), this call is not required to wake nsync_mu_wait/nsync_mu_wait_with_deadline calls on conditions that were false before this thread acquired the lock. This call should be used only at the end of critical sections for which: - nsync_mu_wait/nsync_mu_wait_with_deadline are in use on the same mutex, - this critical section cannot make the condition true for any of those nsync_mu_wait/nsync_mu_wait_with_deadline waits, and - when performance is significantly improved by doing so. */ void nsync_mu_unlock_without_wakeup (nsync_mu *mu) { IGNORE_RACES_START (); /* See comment in nsync_mu_unlock(). */ if (!ATM_CAS_REL (&mu->word, MU_WLOCK, 0)) { uint32_t old_word = ATM_LOAD (&mu->word); uint32_t new_word = old_word - MU_WLOCK; if ((new_word & (MU_RLOCK_FIELD | MU_WLOCK)) != 0) { if ((old_word & MU_RLOCK_FIELD) != 0) { nsync_panic_ ("attempt to nsync_mu_unlock() an nsync_mu " "held in read mode\n"); } else { nsync_panic_ ("attempt to nsync_mu_unlock() an nsync_mu " "not held in write mode\n"); } } else if ((old_word & (MU_WAITING | MU_DESIG_WAKER | MU_ALL_FALSE)) == MU_WAITING || !ATM_CAS_REL (&mu->word, old_word, new_word)) { nsync_mu_unlock_slow_ (mu, nsync_writer_type_); } } IGNORE_RACES_END (); } NSYNC_CPP_END_ nsync-1.24.0/internal/note.c000066400000000000000000000230041367521742200156650ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "dll.h" #include "sem.h" #include "wait_internal.h" #include "common.h" #include "atomic.h" NSYNC_CPP_START_ /* Locking discipline for the nsync_note implementation: Each nsync_note has a lock "note_mu" which protects the "parent" pointer, "waiters" list, and "disconnecting" count. It also protects the "children" list; thus each node's "parent_child_link", which links together the children of a single parent, is protected by the parent's "note_mu". To connect a parent to a child, or to disconnect one, the parent's lock must be held to manipulate its child list, and the child's lock must be held to change the parent pointer, so both must be held simultaneously. The locking order is "parent before child". Operations like notify and free are given a node pointer n and must disconnect *n from its parent n->parent. The call must hold n->note_mu to read n->parent, but need to release n->note_mu to acquire n->parent->note_mu. The parent could be disconnected and freed while n->note_mu is not held. The n->disconnecting count handles this; the operation acquires n->note_mu, increments n->disconnecting, and can then release n->note_mu, and acquire n->parent->note_mu and n->note_mu is the correct order. n->disconnecting!=0 indicates that a thread is already in the processes of disconnecting n from n->parent. A thread freeing or notifying the parent should not perform the disconnection of that child, but should instead wait for the "children" list to become empty via WAIT_FOR_NO_CHILDREN(). WAKEUP_NO_CHILDREN() should be used whenever this condition could become true. */ /* Set the expiry time in *n to t */ static void set_expiry_time (nsync_note n, nsync_time t) { n->expiry_time = t; n->expiry_time_valid = 1; } /* Return a pointer to the note containing nsync_dll_element_ *e. */ #define DLL_NOTE(e) ((nsync_note)((e)->container)) /* Return whether n->children is empty. Assumes n->note_mu held. */ static int no_children (const void *v) { return (nsync_dll_is_empty_ (((nsync_note)v)->children)); } #define WAIT_FOR_NO_CHILDREN(pred_, n_) nsync_mu_wait (&(n_)->note_mu, &pred_, (n_), NULL) #define WAKEUP_NO_CHILDREN(n_) do { } while (0) /* // These lines can be used in place of those above if conditional critical // sections have been removed from the source. #define WAIT_FOR_NO_CHILDREN(pred_, n_) do { \ while (!pred_ (n_)) { nsync_cv_wait (&(n_)->no_children_cv, &(n_)->note_mu); } \ } while (0) #define WAKEUP_NO_CHILDREN(n_) nsync_cv_broadcast (&(n_)->no_children_cv) */ /* Notify *n and all its descendants that are not already disconnnecting. n->note_mu is held. May release and reacquire n->note_mu. parent->note_mu is held if parent != NULL. */ static void note_notify_child (nsync_note n, nsync_note parent) { nsync_time t; t = NOTIFIED_TIME (n); if (nsync_time_cmp (t, nsync_time_zero) > 0) { nsync_dll_element_ *p; nsync_dll_element_ *next; ATM_STORE_REL (&n->notified, 1); while ((p = nsync_dll_first_ (n->waiters)) != NULL) { struct nsync_waiter_s *nw = DLL_NSYNC_WAITER (p); n->waiters = nsync_dll_remove_ (n->waiters, p); ATM_STORE_REL (&nw->waiting, 0); nsync_mu_semaphore_v (nw->sem); } for (p = nsync_dll_first_ (n->children); p != NULL; p = next) { nsync_note child = DLL_NOTE (p); next = nsync_dll_next_ (n->children, p); nsync_mu_lock (&child->note_mu); if (child->disconnecting == 0) { note_notify_child (child, n); } nsync_mu_unlock (&child->note_mu); } WAIT_FOR_NO_CHILDREN (no_children, n); if (parent != NULL) { parent->children = nsync_dll_remove_ (parent->children, &n->parent_child_link); WAKEUP_NO_CHILDREN (parent); n->parent = NULL; } } } /* Notify *n and all its descendants that are not already disconnnecting. No locks are held. */ static void notify (nsync_note n) { nsync_time t; nsync_mu_lock (&n->note_mu); t = NOTIFIED_TIME (n); if (nsync_time_cmp (t, nsync_time_zero) > 0) { nsync_note parent; n->disconnecting++; parent = n->parent; if (parent != NULL && !nsync_mu_trylock (&parent->note_mu)) { nsync_mu_unlock (&n->note_mu); nsync_mu_lock (&parent->note_mu); nsync_mu_lock (&n->note_mu); } note_notify_child (n, parent); if (parent != NULL) { nsync_mu_unlock (&parent->note_mu); } n->disconnecting--; } nsync_mu_unlock (&n->note_mu); } /* Return the deadline by which *n is certain to be notified, setting it to zero if it already has passed that time. Requires n->note_mu not held on entry. Not static; used in sem_wait.c */ nsync_time nsync_note_notified_deadline_ (nsync_note n) { nsync_time ntime; if (ATM_LOAD_ACQ (&n->notified) != 0) { ntime = nsync_time_zero; } else { nsync_mu_lock (&n->note_mu); ntime = NOTIFIED_TIME (n); nsync_mu_unlock (&n->note_mu); if (nsync_time_cmp (ntime, nsync_time_zero) > 0) { if (nsync_time_cmp (ntime, nsync_time_now ()) <= 0) { notify (n); ntime = nsync_time_zero; } } } return (ntime); } int nsync_note_is_notified (nsync_note n) { int result; IGNORE_RACES_START (); result = (nsync_time_cmp (nsync_note_notified_deadline_ (n), nsync_time_zero) <= 0); IGNORE_RACES_END (); return (result); } nsync_note nsync_note_new (nsync_note parent, nsync_time abs_deadline) { nsync_note n = (nsync_note) malloc (sizeof (*n)); if (n != NULL) { memset ((void *) n, 0, sizeof (*n)); nsync_dll_init_ (&n->parent_child_link, n); set_expiry_time (n, abs_deadline); if (!nsync_note_is_notified (n) && parent != NULL) { nsync_time parent_time; nsync_mu_lock (&parent->note_mu); parent_time = NOTIFIED_TIME (parent); if (nsync_time_cmp (parent_time, abs_deadline) < 0) { set_expiry_time (n, parent_time); } if (nsync_time_cmp (parent_time, nsync_time_zero) > 0) { n->parent = parent; parent->children = nsync_dll_make_last_in_list_ (parent->children, &n->parent_child_link); } nsync_mu_unlock (&parent->note_mu); } } return (n); } void nsync_note_free (nsync_note n) { nsync_note parent; nsync_dll_element_ *p; nsync_dll_element_ *next; nsync_mu_lock (&n->note_mu); n->disconnecting++; ASSERT (nsync_dll_is_empty_ (n->waiters)); parent = n->parent; if (parent != NULL && !nsync_mu_trylock (&parent->note_mu)) { nsync_mu_unlock (&n->note_mu); nsync_mu_lock (&parent->note_mu); nsync_mu_lock (&n->note_mu); } for (p = nsync_dll_first_ (n->children); p != NULL; p = next) { nsync_note child = DLL_NOTE (p); next = nsync_dll_next_ (n->children, p); nsync_mu_lock (&child->note_mu); if (child->disconnecting == 0) { n->children = nsync_dll_remove_ (n->children, &child->parent_child_link); if (parent != NULL) { child->parent = parent; parent->children = nsync_dll_make_last_in_list_ ( parent->children, &child->parent_child_link); } else { child->parent = NULL; } } nsync_mu_unlock (&child->note_mu); } WAIT_FOR_NO_CHILDREN (no_children, n); if (parent != NULL) { parent->children = nsync_dll_remove_ (parent->children, &n->parent_child_link); WAKEUP_NO_CHILDREN (parent); n->parent = NULL; nsync_mu_unlock (&parent->note_mu); } n->disconnecting--; nsync_mu_unlock (&n->note_mu); free (n); } void nsync_note_notify (nsync_note n) { IGNORE_RACES_START (); if (nsync_time_cmp (nsync_note_notified_deadline_ (n), nsync_time_zero) > 0) { notify (n); } IGNORE_RACES_END (); } int nsync_note_wait (nsync_note n, nsync_time abs_deadline) { struct nsync_waitable_s waitable; struct nsync_waitable_s *pwaitable = &waitable; waitable.v = n; waitable.funcs = &nsync_note_waitable_funcs; return (nsync_wait_n (NULL, NULL, NULL, abs_deadline, 1, &pwaitable) == 0); } nsync_time nsync_note_expiry (nsync_note n) { return (n->expiry_time); } static nsync_time note_ready_time (void *v, struct nsync_waiter_s *nw UNUSED) { return (nsync_note_notified_deadline_ ((nsync_note)v)); } static int note_enqueue (void *v, struct nsync_waiter_s *nw) { int waiting = 0; nsync_note n = (nsync_note) v; nsync_time ntime; nsync_mu_lock (&n->note_mu); ntime = NOTIFIED_TIME (n); if (nsync_time_cmp (ntime, nsync_time_zero) > 0) { n->waiters = nsync_dll_make_last_in_list_ (n->waiters, &nw->q); ATM_STORE (&nw->waiting, 1); waiting = 1; } else { ATM_STORE (&nw->waiting, 0); waiting = 0; } nsync_mu_unlock (&n->note_mu); return (waiting); } static int note_dequeue (void *v, struct nsync_waiter_s *nw) { int was_queued = 0; nsync_note n = (nsync_note) v; nsync_time ntime; nsync_note_notified_deadline_ (n); nsync_mu_lock (&n->note_mu); ntime = NOTIFIED_TIME (n); if (nsync_time_cmp (ntime, nsync_time_zero) > 0) { n->waiters = nsync_dll_remove_ (n->waiters, &nw->q); ATM_STORE (&nw->waiting, 0); was_queued = 1; } nsync_mu_unlock (&n->note_mu); return (was_queued); } const struct nsync_waitable_funcs_s nsync_note_waitable_funcs = { ¬e_ready_time, ¬e_enqueue, ¬e_dequeue }; NSYNC_CPP_END_ nsync-1.24.0/internal/once.c000066400000000000000000000105371367521742200156530ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "dll.h" #include "sem.h" #include "wait_internal.h" #include "common.h" #include "atomic.h" NSYNC_CPP_START_ /* An once_sync_s struct contains a lock, and a condition variable on which threads may wait for an nsync_once to be initialized by another thread. A separate struct is used only to keep nsync_once small. A given nsync_once can be associated with any once_sync_s struct, but cannot be associated with more than one. nsync_once instances are mapped to once_sync_s instances by a trivial hashing scheme implemented by NSYNC_ONCE_SYNC_(). The number of once_sync_s structs in the following array is greater than one only to reduce the probability of contention if a great many distinct nsync_once variables are initialized concurrently. */ static struct once_sync_s { nsync_mu once_mu; nsync_cv once_cv; } once_sync[64]; /* Return a pointer to the once_sync_s struct associated with the nsync_once *p. */ #define NSYNC_ONCE_SYNC_(p) &once_sync[(((uintptr_t) (p)) / sizeof (*(p))) % \ (sizeof (once_sync) / sizeof (once_sync[0]))] /* Implement nsync_run_once, nsync_run_once_arg, nsync_run_once_spin, or nsync_run_once_arg_spin, chosen as described below. If s!=NULL, s is required to point to the once_sync_s associated with *once, and the semantics of nsync_run_once or nsync_run_once_arg are provided. If s==NULL, the semantics of nsync_run_once_spin, or nsync_run_once_arg_spin are provided. If f!=NULL, the semantics of nsync_run_once or nsync_run_once_spin are provided. Otherwise, farg is required to be non-NULL, and the semantics of nsync_run_once_arg or nsync_run_once_arg_spin are provided. */ static void nsync_run_once_impl (nsync_once *once, struct once_sync_s *s, void (*f) (void), void (*farg) (void *arg), void *arg) { uint32_t o = ATM_LOAD_ACQ (once); if (o != 2) { unsigned attempts = 0; if (s != NULL) { nsync_mu_lock (&s->once_mu); } while (o == 0 && !ATM_CAS_ACQ (once, 0, 1)) { o = ATM_LOAD (once); } if (o == 0) { if (s != NULL) { nsync_mu_unlock (&s->once_mu); } if (f != NULL) { (*f) (); } else { (*farg) (arg); } if (s != NULL) { nsync_mu_lock (&s->once_mu); nsync_cv_broadcast (&s->once_cv); } ATM_STORE_REL (once, 2); } while (ATM_LOAD_ACQ (once) != 2) { if (s != NULL) { nsync_time deadline; if (attempts < 50) { attempts += 10; } deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (attempts)); nsync_cv_wait_with_deadline (&s->once_cv, &s->once_mu, deadline, NULL); } else { attempts = nsync_spin_delay_ (attempts); } } if (s != NULL) { nsync_mu_unlock (&s->once_mu); } } } void nsync_run_once (nsync_once *once, void (*f) (void)) { uint32_t o; IGNORE_RACES_START (); o = ATM_LOAD_ACQ (once); if (o != 2) { struct once_sync_s *s = NSYNC_ONCE_SYNC_ (once); nsync_run_once_impl (once, s, f, NULL, NULL); } IGNORE_RACES_END (); } void nsync_run_once_arg (nsync_once *once, void (*farg) (void *arg), void *arg) { uint32_t o; IGNORE_RACES_START (); o = ATM_LOAD_ACQ (once); if (o != 2) { struct once_sync_s *s = NSYNC_ONCE_SYNC_ (once); nsync_run_once_impl (once, s, NULL, farg, arg); } IGNORE_RACES_END (); } void nsync_run_once_spin (nsync_once *once, void (*f) (void)) { uint32_t o; IGNORE_RACES_START (); o = ATM_LOAD_ACQ (once); if (o != 2) { nsync_run_once_impl (once, NULL, f, NULL, NULL); } IGNORE_RACES_END (); } void nsync_run_once_arg_spin (nsync_once *once, void (*farg) (void *arg), void *arg) { uint32_t o; IGNORE_RACES_START (); o = ATM_LOAD_ACQ (once); if (o != 2) { nsync_run_once_impl (once, NULL, NULL, farg, arg); } IGNORE_RACES_END (); } NSYNC_CPP_END_ nsync-1.24.0/internal/sem.h000066400000000000000000000027051367521742200155160ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_INTERNAL_SEM_H_ #define NSYNC_INTERNAL_SEM_H_ /* A semaphore. It may be counting or binary, and it need have no destructor. */ #include "nsync_cpp.h" NSYNC_CPP_START_ typedef struct nsync_semaphore_s_ { void *sem_space[32]; /* space used by implementation */ } nsync_semaphore; /* Initialize *s; the initial value is 0. */ void nsync_mu_semaphore_init (nsync_semaphore *s); /* Wait until the count of *s exceeds 0, and decrement it. */ void nsync_mu_semaphore_p (nsync_semaphore *s); /* Wait until one of: the count of *s is non-zero, in which case decrement *s and return 0; or abs_deadline expires, in which case return ETIMEDOUT. */ int nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadline); /* Ensure that the count of *s is at least 1. */ void nsync_mu_semaphore_v (nsync_semaphore *s); NSYNC_CPP_END_ #endif /*NSYNC_INTERNAL_SEM_H_*/ nsync-1.24.0/internal/sem_wait.c000066400000000000000000000051651367521742200165400ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "dll.h" #include "sem.h" #include "wait_internal.h" #include "common.h" #include "atomic.h" NSYNC_CPP_START_ /* Wait until one of: w->sem is non-zero----decrement it and return 0. abs_deadline expires---return ETIMEDOUT. cancel_note is non-NULL and *cancel_note becomes notified---return ECANCELED. */ int nsync_sem_wait_with_cancel_ (waiter *w, nsync_time abs_deadline, nsync_note cancel_note) { int sem_outcome; if (cancel_note == NULL) { sem_outcome = nsync_mu_semaphore_p_with_deadline (&w->sem, abs_deadline); } else { nsync_time cancel_time; cancel_time = nsync_note_notified_deadline_ (cancel_note); sem_outcome = ECANCELED; if (nsync_time_cmp (cancel_time, nsync_time_zero) > 0) { struct nsync_waiter_s nw; nw.tag = NSYNC_WAITER_TAG; nw.sem = &w->sem; nsync_dll_init_ (&nw.q, &nw); ATM_STORE (&nw.waiting, 1); nw.flags = 0; nsync_mu_lock (&cancel_note->note_mu); cancel_time = NOTIFIED_TIME (cancel_note); if (nsync_time_cmp (cancel_time, nsync_time_zero) > 0) { nsync_time local_abs_deadline; int deadline_is_nearer = 0; cancel_note->waiters = nsync_dll_make_last_in_list_ ( cancel_note->waiters, &nw.q); local_abs_deadline = cancel_time; if (nsync_time_cmp (abs_deadline, cancel_time) < 0) { local_abs_deadline = abs_deadline; deadline_is_nearer = 1; } nsync_mu_unlock (&cancel_note->note_mu); sem_outcome = nsync_mu_semaphore_p_with_deadline (&w->sem, local_abs_deadline); if (sem_outcome == ETIMEDOUT && !deadline_is_nearer) { sem_outcome = ECANCELED; nsync_note_notify (cancel_note); } nsync_mu_lock (&cancel_note->note_mu); cancel_time = NOTIFIED_TIME (cancel_note); if (nsync_time_cmp (cancel_time, nsync_time_zero) > 0) { cancel_note->waiters = nsync_dll_remove_ ( cancel_note->waiters, &nw.q); } } nsync_mu_unlock (&cancel_note->note_mu); } } return (sem_outcome); } NSYNC_CPP_END_ nsync-1.24.0/internal/sem_wait_no_note.c000066400000000000000000000021671367521742200202600ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "dll.h" #include "sem.h" #include "wait_internal.h" #include "common.h" #include "atomic.h" NSYNC_CPP_START_ /* Wait until one of: w->sem is non-zero----decrement it and return 0. abs_deadline expires---return ETIMEDOUT. Ignores cancel_note. */ int nsync_sem_wait_with_cancel_ (waiter *w, nsync_time abs_deadline, nsync_note cancel_note UNUSED) { return (nsync_mu_semaphore_p_with_deadline (&w->sem, abs_deadline)); } NSYNC_CPP_END_ nsync-1.24.0/internal/time_internal.c000066400000000000000000000017501367521742200175560ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync_time.h" NSYNC_CPP_START_ nsync_time nsync_time_ms (unsigned ms) { unsigned s = ms / 1000; return (nsync_time_s_ns (s, 1000 * 1000 * (ms % 1000))); } nsync_time nsync_time_us (unsigned us) { unsigned s = us / (1000 * 1000); return (nsync_time_s_ns (s, 1000 * (us % (1000 * 1000)))); } NSYNC_CPP_END_ nsync-1.24.0/internal/wait.c000066400000000000000000000055411367521742200156720ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync.h" #include "sem.h" #include "dll.h" #include "wait_internal.h" #include "common.h" #include "atomic.h" NSYNC_CPP_START_ int nsync_wait_n (void *mu, void (*lock) (void *), void (*unlock) (void *), nsync_time abs_deadline, int count, struct nsync_waitable_s *waitable[]) { int ready; IGNORE_RACES_START (); for (ready = 0; ready != count && nsync_time_cmp ((*waitable[ready]->funcs->ready_time) ( waitable[ready]->v, NULL), nsync_time_zero) > 0; ready++) { } if (ready == count && nsync_time_cmp (abs_deadline, nsync_time_zero) > 0) { int i; int unlocked = 0; int j; int enqueued = 1; waiter *w = nsync_waiter_new_ (); struct nsync_waiter_s nw_set[4]; struct nsync_waiter_s *nw = nw_set; if (count > (int) (sizeof (nw_set) / sizeof (nw_set[0]))) { nw = (struct nsync_waiter_s *) malloc (count * sizeof (nw[0])); } for (i = 0; i != count && enqueued; i++) { nw[i].tag = NSYNC_WAITER_TAG; nw[i].sem = &w->sem; nsync_dll_init_ (&nw[i].q, &nw[i]); ATM_STORE (&nw[i].waiting, 0); nw[i].flags = 0; enqueued = (*waitable[i]->funcs->enqueue) (waitable[i]->v, &nw[i]); } if (i == count) { nsync_time min_ntime; if (mu != NULL) { (*unlock) (mu); unlocked = 1; } do { min_ntime = abs_deadline; for (j = 0; j != count; j++) { nsync_time ntime; ntime = (*waitable[j]->funcs->ready_time) ( waitable[j]->v, &nw[j]); if (nsync_time_cmp (ntime, min_ntime) < 0) { min_ntime = ntime; } } } while (nsync_time_cmp (min_ntime, nsync_time_zero) > 0 && nsync_mu_semaphore_p_with_deadline (&w->sem, min_ntime) == 0); } /* An attempt was made above to enqueue waitable[0..i-1]. Dequeue any that are still enqueued, and remember the index of the first ready (i.e., not still enqueued) object, if any. */ for (j = 0; j != i; j++) { int was_still_enqueued = (*waitable[j]->funcs->dequeue) (waitable[j]->v, &nw[j]); if (!was_still_enqueued && ready == count) { ready = j; } } if (nw != nw_set) { free (nw); } nsync_waiter_free_ (w); if (unlocked) { (*lock) (mu); } } IGNORE_RACES_END (); return (ready); } NSYNC_CPP_END_ nsync-1.24.0/internal/wait_internal.h000066400000000000000000000026451367521742200175750ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_INTERNAL_WAIT_INTERNAL_H_ #define NSYNC_INTERNAL_WAIT_INTERNAL_H_ NSYNC_CPP_START_ /* Implementations of "struct nsync_waitable_s" must provide functions in struct nsync_waitable_funcs_s (see public/nsync_wait.h). When nsync_wait_n() waits on a client's object, those functions are called with v pointing to the client's object and nw pointing to a struct nsync_waiter_s. */ struct nsync_waiter_s { uint32_t tag; /* used for debugging */ nsync_dll_element_ q; /* used to link children of parent */ nsync_atomic_uint32_ waiting; /* non-zero <=> the waiter is waiting */ struct nsync_semaphore_s_ *sem; /* *sem will be Ved when waiter is woken */ uint32_t flags; /* see below */ }; #define NSYNC_WAITER_FLAG_MUCV 0x1 /* set if waiter is embedded in Mu/CV's internal structures */ NSYNC_CPP_END_ #endif /*NSYNC_INTERNAL_WAIT_INTERNAL_H_*/ nsync-1.24.0/platform/000077500000000000000000000000001367521742200145655ustar00rootroot00000000000000nsync-1.24.0/platform/aarch64/000077500000000000000000000000001367521742200160155ustar00rootroot00000000000000nsync-1.24.0/platform/aarch64/cputype.h000066400000000000000000000013451367521742200176620ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_AARCH64_CPUTYPE_H_ #define NSYNC_PLATFORM_AARCH64_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_AARCH64_CPUTYPE_H_*/ nsync-1.24.0/platform/aarch64/src/000077500000000000000000000000001367521742200166045ustar00rootroot00000000000000nsync-1.24.0/platform/aarch64/src/nsync_atm_aarch64.s000066400000000000000000000050451367521742200222770ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for aarch64 implementation of atomic operations. */ /* Atomically: int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some-non-zero-value); } else { return (0); } } */ .text .align 3 .global nsync_atm_cas_ .type nsync_atm_cas_, %function nsync_atm_cas_: 1: ldxr w3, [x0] cmp w3, w1 bne 2f stxr w4, w2, [x0] cbnz w4, 1b 2: cset w0, eq ret /* Like nsync_atm_cas_, but with acquire barrier semantics. */ .align 3 .global nsync_atm_cas_acq_ .type nsync_atm_cas_acq_, %function nsync_atm_cas_acq_: 1: ldaxr w3, [x0] cmp w3, w1 bne 2f stxr w4, w2, [x0] cbnz w4, 1b 2: cset w0, eq ret /* Like nsync_atm_cas_, but with release barrier semantics. */ .align 3 .global nsync_atm_cas_rel_ .type nsync_atm_cas_rel_, %function nsync_atm_cas_rel_: 1: ldxr w3, [x0] cmp w3, w1 bne 2f stlxr w4, w2, [x0] cbnz w4, 1b 2: cset w0, eq ret /* Like nsync_atm_cas_, but with both acquire and release barrier semantics. */ .align 3 .global nsync_atm_cas_relacq_ .type nsync_atm_cas_relacq_, %function nsync_atm_cas_relacq_: 1: ldaxr w3, [x0] cmp w3, w1 bne 2f stlxr w4, w2, [x0] cbnz w4, 1b 2: cset w0, eq ret /* Atomically: uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 3 .global nsync_atm_load_ .type nsync_atm_load_, %function nsync_atm_load_: ldr w0, [x0] ret /* Like nsync_atm_load_, but with acquire barrier semantics. */ .align 3 .global nsync_atm_load_acq_ .type nsync_atm_load_acq_, %function nsync_atm_load_acq_: ldar w0, [x0] ret /* Atomically: void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 3 .global nsync_atm_store_ .type nsync_atm_store_, %function nsync_atm_store_: str w1, [x0] ret /* Like nsync_atm_store_, but with release barrier semantics. */ .align 3 .global nsync_atm_store_rel_ .type nsync_atm_store_rel_, %function nsync_atm_store_rel_: stlr w1, [x0] ret nsync-1.24.0/platform/alpha/000077500000000000000000000000001367521742200156525ustar00rootroot00000000000000nsync-1.24.0/platform/alpha/cputype.h000066400000000000000000000013371367521742200175200ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_ALPHA_CPUTYPE_H_ #define NSYNC_PLATFORM_ALPHA_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_ALPHA_CPUTYPE_H_*/ nsync-1.24.0/platform/alpha/src/000077500000000000000000000000001367521742200164415ustar00rootroot00000000000000nsync-1.24.0/platform/alpha/src/nsync_atm_alpha.s000066400000000000000000000062041367521742200217670ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for alpha implementation of atomic operations. */ #define v0 $0 #define a0 $16 #define a1 $17 #define a2 $18 #define ra $26 .set noreorder .text /* Atomically: int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some - non - zero - value); } else { return (0); } } */ .align 4 .globl nsync_atm_cas_ .ent nsync_atm_cas_ nsync_atm_cas_: .frame $sp, 0, ra .prologue 0 1: ldl_l v0, (a0) cmpeq v0, a1, v0 blbc v0, 2f bis a2, a2, v0 stl_c v0, (a0) blbc v0, 1b 2: ret (ra) .end nsync_atm_cas_ /* Like nsync_atm_cas_, but with acquire barrier semantics. */ .align 4 .globl nsync_atm_cas_acq_ .ent nsync_atm_cas_acq_ nsync_atm_cas_acq_: .frame $sp, 0, ra .prologue 0 1: ldl_l v0, (a0) cmpeq v0, a1, v0 blbc v0, 2f bis a2, a2, v0 stl_c v0, (a0) blbc v0, 1b mb 2: ret (ra) .end nsync_atm_cas_acq_ /* Like nsync_atm_cas_, but with release barrier semantics. */ .align 4 .globl nsync_atm_cas_rel_ .ent nsync_atm_cas_rel_ nsync_atm_cas_rel_: .frame $sp, 0, ra .prologue 0 mb 1: ldl_l v0, (a0) cmpeq v0, a1, v0 blbc v0, 2f bis a2, a2, v0 stl_c v0, (a0) blbc v0, 1b 2: ret (ra) .end nsync_atm_cas_rel_ /* Like nsync_atm_cas_, but with both acquire and release barrier semantics. */ .align 4 .globl nsync_atm_cas_relacq_ .ent nsync_atm_cas_relacq_ nsync_atm_cas_relacq_: .frame $sp, 0, ra .prologue 0 mb 1: ldl_l v0, (a0) cmpeq v0, a1, v0 blbc v0, 2f bis a2, a2, v0 stl_c v0, (a0) blbc v0, 1b mb 2: ret (ra) .end nsync_atm_cas_relacq_ /* Atomically: uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 4 .globl nsync_atm_load_ .ent nsync_atm_load_ nsync_atm_load_: .frame $sp, 0, ra .prologue 0 ldl v0, (a0) ret (ra) .end nsync_atm_load_ /* Like nsync_atm_load_, but with acquire barrier semantics. */ .align 4 .globl nsync_atm_load_acq_ .ent nsync_atm_load_acq_ nsync_atm_load_acq_: .frame $sp, 0, ra .prologue 0 ldl v0, (a0) mb ret (ra) .end nsync_atm_load_acq_ /* Atomically: void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 4 .globl nsync_atm_store_ .ent nsync_atm_store_ nsync_atm_store_: .frame $sp, 0, ra .prologue 0 stl a1, (a0) ret (ra) .end nsync_atm_store_ /* Like nsync_atm_store_, but with release barrier semantics. */ .align 4 .globl nsync_atm_store_rel_ .ent nsync_atm_store_rel_ nsync_atm_store_rel_: .frame $sp, 0, ra .prologue 0 mb stl a1, (a0) ret (ra) .end nsync_atm_store_rel_ nsync-1.24.0/platform/arm/000077500000000000000000000000001367521742200153445ustar00rootroot00000000000000nsync-1.24.0/platform/arm/cputype.h000066400000000000000000000013311367521742200172040ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_ARM_CPUTYPE_H_ #define NSYNC_PLATFORM_ARM_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_ARM_CPUTYPE_H_*/ nsync-1.24.0/platform/arm/src/000077500000000000000000000000001367521742200161335ustar00rootroot00000000000000nsync-1.24.0/platform/arm/src/nsync_atm_arm.s000066400000000000000000000053071367521742200211560ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for arm implementation of atomic operations. */ .text /* Atomically: int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some-non-zero-value); } else { return (0); } } */ .align 3 .global nsync_atm_cas_ .type nsync_atm_cas_, %function nsync_atm_cas_: 1: ldrex r3, [r0] cmp r3, r1 bne 2f strex r3, r2, [r0] teq r3, #0 bne 1b mov r0, #1 bx lr 2: mov r0, #0 bx lr /* Like nsync_atm_cas_, but with acquire barrier semantics. */ .align 3 .global nsync_atm_cas_acq_ .type nsync_atm_cas_acq_, %function nsync_atm_cas_acq_: 1: ldrex r3, [r0] cmp r3, r1 bne 2f strex r3, r2, [r0] teq r3, #0 bne 1b dmb sy mov r0, #1 bx lr 2: mov r0, #0 bx lr /* Like nsync_atm_cas_, but with release barrier semantics. */ .align 3 .global nsync_atm_cas_rel_ .type nsync_atm_cas_rel_, %function nsync_atm_cas_rel_: dmb sy 1: ldrex r3, [r0] cmp r3, r1 bne 2f strex r3, r2, [r0] teq r3, #0 bne 1b mov r0, #1 bx lr 2: mov r0, #0 bx lr /* Like nsync_atm_cas_, but with both acquire and release barrier semantics. */ .align 3 .global nsync_atm_cas_relacq_ .type nsync_atm_cas_relacq_, %function nsync_atm_cas_relacq_: dmb sy 1: ldrex r3, [r0] cmp r3, r1 bne 2f strex r3, r2, [r0] teq r3, #0 bne 1b dmb sy mov r0, #1 bx lr 2: mov r0, #0 bx lr /* Atomically: uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 3 .global nsync_atm_load_ .type nsync_atm_load_, %function nsync_atm_load_: ldr r0, [r0] bx lr /* Like nsync_atm_load_, but with acquire barrier semantics. */ .align 3 .global nsync_atm_load_acq_ .type nsync_atm_load_acq_, %function nsync_atm_load_acq_: ldr r0, [r0] dmb sy bx lr /* Atomically: void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 3 .global nsync_atm_store_ .type nsync_atm_store_, %function nsync_atm_store_: str r1, [r0] bx lr /* Like nsync_atm_store_, but with release barrier semantics. */ .align 3 .global nsync_atm_store_rel_ .type nsync_atm_store_rel_, %function nsync_atm_store_rel_: dmb sy str r1, [r0] bx lr nsync-1.24.0/platform/atomic_ind/000077500000000000000000000000001367521742200166735ustar00rootroot00000000000000nsync-1.24.0/platform/atomic_ind/atomic.h000066400000000000000000000070131367521742200203210ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_ATOMIC_IND_ATOMIC_H_ #define NSYNC_PLATFORM_ATOMIC_IND_ATOMIC_H_ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #include "compiler.h" #include "nsync_atomic.h" NSYNC_CPP_START_ int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); int nsync_atm_cas_acq_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); int nsync_atm_cas_rel_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); int nsync_atm_cas_relacq_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); uint32_t nsync_atm_load_ (const nsync_atomic_uint32_ *p); uint32_t nsync_atm_load_acq_ (const nsync_atomic_uint32_ *p); void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value); void nsync_atm_store_rel_ (nsync_atomic_uint32_ *p, uint32_t value); #define ATM_CAS nsync_atm_cas_ #define ATM_CAS_ACQ nsync_atm_cas_acq_ #define ATM_CAS_REL nsync_atm_cas_rel_ #define ATM_CAS_RELACQ nsync_atm_cas_relacq_ #define ATM_LOAD nsync_atm_load_ #define ATM_LOAD_ACQ nsync_atm_load_acq_ #define ATM_STORE nsync_atm_store_ #define ATM_STORE_REL nsync_atm_store_rel_ NSYNC_CPP_END_ #endif /*NSYNC_PLATFORM_ATOMIC_IND_ATOMIC_H_*/ nsync-1.24.0/platform/c++11.futex/000077500000000000000000000000001367521742200164315ustar00rootroot00000000000000nsync-1.24.0/platform/c++11.futex/platform.h000066400000000000000000000017411367521742200204310ustar00rootroot00000000000000/* Copyright 2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_CPP11_FUTEX_PLATFORM_H_ #define NSYNC_PLATFORM_CPP11_FUTEX_PLATFORM_H_ /* This header is for use of when a mostly-C++11 build is desired, but on a Linux system where fuxtex is available, and outperforms the C++11 library functions. */ #include "../c++11/platform.h" #include #include #include #endif /*NSYNC_PLATFORM_CPP11_FUTEX_PLATFORM_H_*/ nsync-1.24.0/platform/c++11/000077500000000000000000000000001367521742200152775ustar00rootroot00000000000000nsync-1.24.0/platform/c++11/atomic.h000066400000000000000000000106531367521742200167310ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_CPP11_ATOMIC_H_ #define NSYNC_PLATFORM_CPP11_ATOMIC_H_ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #include "nsync_cpp.h" #include "nsync_atomic.h" NSYNC_CPP_START_ static INLINE int atm_cas_nomb_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (std::atomic_compare_exchange_strong_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, std::memory_order_relaxed, std::memory_order_relaxed)); } static INLINE int atm_cas_acq_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (std::atomic_compare_exchange_strong_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, std::memory_order_acquire, std::memory_order_relaxed)); } static INLINE int atm_cas_rel_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (std::atomic_compare_exchange_strong_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, std::memory_order_release, std::memory_order_relaxed)); } static INLINE int atm_cas_relacq_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (std::atomic_compare_exchange_strong_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, std::memory_order_acq_rel, std::memory_order_relaxed)); } #define ATM_CAS_HELPER_(barrier, p, o, n) (atm_cas_##barrier##_u32_ ((p), (o), (n))) #define ATM_CAS(p,o,n) ATM_CAS_HELPER_ (nomb, (p), (o), (n)) #define ATM_CAS_ACQ(p,o,n) ATM_CAS_HELPER_ (acq, (p), (o), (n)) #define ATM_CAS_REL(p,o,n) ATM_CAS_HELPER_ (rel, (p), (o), (n)) #define ATM_CAS_RELACQ(p,o,n) ATM_CAS_HELPER_ (relacq, (p), (o), (n)) #define ATM_LOAD(p) (std::atomic_load_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), std::memory_order_relaxed)) #define ATM_LOAD_ACQ(p) (std::atomic_load_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), std::memory_order_acquire)) #define ATM_STORE(p,v) (std::atomic_store_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), (uint32_t) (v), std::memory_order_relaxed)) #define ATM_STORE_REL(p,v) (std::atomic_store_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), (uint32_t) (v), std::memory_order_release)) NSYNC_CPP_END_ #endif /*NSYNC_PLATFORM_CPP11_ATOMIC_H_*/ nsync-1.24.0/platform/c++11/platform.h000066400000000000000000000133221367521742200172750ustar00rootroot00000000000000/* Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_CPP11_PLATFORM_H_ #define NSYNC_PLATFORM_CPP11_PLATFORM_H_ /* These C header files are in "C compatibility headers" in C++11. */ #include #include #include #include #include #include #include #include #include #include #include "nsync_cpp.h" /* We could include pthread.h, if we knew it existed. Instead we implement the things the tests need using C++11 equivalents. */ typedef std::mutex *nsync_pthread_mutex_; static inline int nsync_pthread_mutex_lock_ (nsync_pthread_mutex_ *mu) { (*mu)->lock (); return (0); } static inline int nsync_pthread_mutex_unlock_ (nsync_pthread_mutex_ *mu) { (*mu)->unlock (); return (0); } #undef pthread_mutex_t #undef pthread_mutex_lock #undef pthread_mutex_unlock #undef pthread_mutex_init #undef pthread_mutex_destroy #define pthread_mutex_t nsync_pthread_mutex_ #define pthread_mutex_lock nsync_pthread_mutex_lock_ #define pthread_mutex_unlock nsync_pthread_mutex_unlock_ #define pthread_mutex_init(mu,attr) (*(mu) = new std::mutex) #define pthread_mutex_destroy(mu) delete *(mu) typedef std::condition_variable *nsync_pthread_cond_; static inline int nsync_pthread_cond_broadcast_ (nsync_pthread_cond_ *cv) { (*cv)->notify_all (); return (0); } static inline int nsync_pthread_cond_signal_ (nsync_pthread_cond_ *cv) { (*cv)->notify_one (); return (0); } static inline int nsync_pthread_cond_wait_ (nsync_pthread_cond_ *cv, nsync_pthread_mutex_ *mu) { std::unique_lock mu_mu (**mu, std::adopt_lock); (*cv)->wait (mu_mu); mu_mu.release (); return (0); } static inline int nsync_pthread_cond_timedwait_ (nsync_pthread_cond_ *cv, nsync_pthread_mutex_ *mu, const struct timespec *abstimeout) { std::cv_status result = std::cv_status::no_timeout; std::unique_lock mu_mu (**mu, std::adopt_lock); if (abstimeout == NULL || abstimeout->tv_sec >= 0x7fffffff) { (*cv)->wait (mu_mu); } else { std::chrono::system_clock::time_point epoch; result = (*cv)->wait_until (mu_mu, epoch + std::chrono::nanoseconds ( abstimeout->tv_nsec + 1000 * 1000 * 1000 * (int64_t) abstimeout->tv_sec)); } mu_mu.release (); return (result == std::cv_status::timeout? ETIMEDOUT : 0); } #undef pthread_cond_t #undef pthread_cond_broadcast #undef pthread_cond_signal #undef pthread_cond_wait #undef pthread_cond_timedwait #undef pthread_cond_init #undef pthread_cond_destroy #define pthread_cond_t nsync_pthread_cond_ #define pthread_cond_broadcast nsync_pthread_cond_broadcast_ #define pthread_cond_signal nsync_pthread_cond_signal_ #define pthread_cond_wait nsync_pthread_cond_wait_ #define pthread_cond_timedwait nsync_pthread_cond_timedwait_ #define pthread_cond_init(cv, attr) (*(cv) = new std::condition_variable) #define pthread_cond_destroy(cv) delete *(cv) typedef struct nsync_pthread_rwlock_s { nsync_pthread_rwlock_s () : lock (0) {} int lock; /* -1 == exclusive; 0==unlocked; +ve == reader count */ std::mutex mu; std::condition_variable cv; } *nsync_pthread_rwlock_; static inline int nsync_pthread_rwlock_wrlock_ (nsync_pthread_rwlock_ *rw) { std::unique_lock rw_mu ((*rw)->mu, std::defer_lock); rw_mu.lock (); while ((*rw)->lock != 0) { (*rw)->cv.wait (rw_mu); } (*rw)->lock = -1; rw_mu.unlock (); return (0); } static inline int nsync_pthread_rwlock_rdlock_ (nsync_pthread_rwlock_ *rw) { std::unique_lock rw_mu ((*rw)->mu, std::defer_lock); rw_mu.lock (); while ((*rw)->lock == -1) { (*rw)->cv.wait (rw_mu); } (*rw)->lock++; rw_mu.unlock (); return (0); } static inline int nsync_pthread_rwlock_unlock_ (nsync_pthread_rwlock_ *rw) { std::unique_lock rw_mu ((*rw)->mu, std::defer_lock); rw_mu.lock (); if ((*rw)->lock == -1) { (*rw)->lock = 0; } else if ((*rw)->lock > 0) { (*rw)->lock--; } if ((*rw)->lock == 0) { (*rw)->cv.notify_all (); } rw_mu.unlock (); return (0); } #undef pthread_rwlock_t #undef pthread_rwlock_wrlock #undef pthread_rwlock_rdlock #undef pthread_rwlock_unlock #undef pthread_rwlock_init #undef pthread_rwlock_destroy #define pthread_rwlock_t nsync_pthread_rwlock_ #define pthread_rwlock_wrlock nsync_pthread_rwlock_wrlock_ #define pthread_rwlock_rdlock nsync_pthread_rwlock_rdlock_ #define pthread_rwlock_unlock nsync_pthread_rwlock_unlock_ #define pthread_rwlock_init(rw,attr) (*(rw) = new nsync_pthread_rwlock_s) #define pthread_rwlock_destroy(rw) delete *(rw) typedef int nsync_pthread_once_type_; #undef PTHREAD_ONCE_INIT #define PTHREAD_ONCE_INIT 0 static inline void nsync_pthread_once_ (nsync_pthread_once_type_ *o, void (*f) ()) { static std::mutex mu; static std::condition_variable cv; std::unique_lock o_mu (mu, std::defer_lock); o_mu.lock (); if (*o == 0) { *o = 1; o_mu.unlock (); (*f) (); o_mu.lock (); *o = 2; cv.notify_all (); } else { while (*o != 2) { cv.wait (o_mu); } } o_mu.unlock (); } #undef pthread_once_t #undef pthread_once #define pthread_once_t nsync_pthread_once_type_ #define pthread_once nsync_pthread_once_ /* Some platforms need more OS-specific help. */ #include "platform_c++11_os.h" #endif /*NSYNC_PLATFORM_CPP11_PLATFORM_H_*/ nsync-1.24.0/platform/c++11/src/000077500000000000000000000000001367521742200160665ustar00rootroot00000000000000nsync-1.24.0/platform/c++11/src/nsync_panic.cc000066400000000000000000000014721367521742200207050ustar00rootroot00000000000000/* Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" #include #include NSYNC_CPP_START_ /* Abort after printing the nul-terminated string s[]. */ void nsync_panic_ (const char *s) { std::cerr << "panic: " << s; std::abort (); } NSYNC_CPP_END_ nsync-1.24.0/platform/c++11/src/nsync_semaphore_mutex.cc000066400000000000000000000103131367521742200230120ustar00rootroot00000000000000/* Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" /* This module implements a binary semaphore using C++11 constructs. The interface of std::condition_variable requires the use of std::unique_lock, but the justification of correctness here is more subtle than I'd like. Presumably, the idea behind std::unique_lock was to provide exception safety: it guarantees to release the lock no matter how a block is exited. However, if the lock had a non-trivial monitor invariant, std::unique_lock wouldn't restore it, so the programmer would be forced to maintain/restore the monitor invariant at every point in the region where an exception could be thown. This is why other languages with locks and exceptions provide try-finally, even if they also provide scoped locked regions. In this code we can get away with std::unique_lock only because the monitor invariant happens to be trivial, and holds at all procedure call sites within the region. The lock and unlock calls are explicit so readers can see the region bounaries. */ NSYNC_CPP_START_ #define ASSERT(x) do { if (!(x)) { *(volatile int *)0 = 0; } } while (0) struct mutex_cond { std::mutex mu; std::condition_variable cv; uint32_t i; }; static_assert (sizeof (struct mutex_cond) <= sizeof (nsync_semaphore), "mutex_cond must fit in an nsync_semaphore"); /* Initialize *s; the initial value is 0. */ void nsync_mu_semaphore_init (nsync_semaphore *s) { struct mutex_cond *mc = (struct mutex_cond *) s; new (&mc->mu) std::mutex (); new (&mc->cv) std::condition_variable (); mc->i = 0; } /* Wait until the count of *s exceeds 0, and decrement it. */ void nsync_mu_semaphore_p (nsync_semaphore *s) { struct mutex_cond *mc = (struct mutex_cond *) s; /* std::unique_lock works here because the monitor invariant holds throughout the region. */ std::unique_lock mc_mu(mc->mu, std::defer_lock); mc_mu.lock (); while (mc->i == 0) { mc->cv.wait (mc_mu); } mc->i = 0; mc_mu.unlock (); } /* Wait until one of: the count of *s is non-zero, in which case decrement *s and return 0; or abs_deadline expires, in which case return ETIMEDOUT. */ int nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadline) { struct mutex_cond *mc = (struct mutex_cond *)s; std::cv_status res = std::cv_status::no_timeout; /* std::unique_lock works here because the monitor invariant holds throughout the regions. */ std::unique_lock mc_mu(mc->mu, std::defer_lock); if (nsync_time_cmp (abs_deadline, nsync_time_no_deadline) == 0) { mc_mu.lock (); while (mc->i == 0) { mc->cv.wait (mc_mu); } mc->i = 0; mc_mu.unlock (); } else { nsync_cpp_time_point_ tp_deadline = nsync_to_time_point_ (abs_deadline); mc_mu.lock (); while (mc->i == 0 && ((res = mc->cv.wait_until (mc_mu, tp_deadline)) == std::cv_status::no_timeout || (res == std::cv_status::timeout && /* Various systems wake up too early. */ nsync_time_cmp (abs_deadline, nsync_time_now ()) > 0))) { } ASSERT (res == std::cv_status::no_timeout || res == std::cv_status::timeout); if (mc->i != 0) { res = std::cv_status::no_timeout; mc->i = 0; } mc_mu.unlock (); } return (res == std::cv_status::timeout? ETIMEDOUT : 0); } /* Ensure that the count of *s is at least 1. */ void nsync_mu_semaphore_v (nsync_semaphore *s) { struct mutex_cond *mc = (struct mutex_cond *) s; /* std::unique_lock works here because the monitor invariant holds throughout the region. */ std::unique_lock mc_mu(mc->mu, std::defer_lock); mc_mu.lock (); mc->i = 1; mc->cv.notify_all (); mc_mu.unlock (); } NSYNC_CPP_END_ nsync-1.24.0/platform/c++11/src/per_thread_waiter.cc000066400000000000000000000032721367521742200220710ustar00rootroot00000000000000/* Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ namespace { class per_thread { public: per_thread(); ~per_thread(); /* Return the per-thread value, and set the destructor to dest. */ void *get(void (*dest) (void *)); /* Set the per-thread value to p, and setting the destructor to dest. */ void set(void *p, void (*dest) (void *)); private: void *value; void (*dest) (void *); }; per_thread::per_thread() { this->value = nullptr; this->dest = nullptr; } per_thread::~per_thread() { void *value = this->value; void (*dest) (void *) = this->dest; this->value = nullptr; this->dest = nullptr; if (dest != nullptr && value != nullptr) { (*dest) (value); } } void *per_thread::get(void (*dest) (void *)) { this->dest = dest; return (this->value); } void per_thread::set(void *p, void (*dest) (void *)) { this->value = p; this->dest = dest; } thread_local per_thread thread_specific; } void *nsync_per_thread_waiter_ (void (*dest) (void *)) { return (thread_specific.get (dest)); } void nsync_set_per_thread_waiter_ (void *v, void (*dest) (void *)) { thread_specific.set (v, dest); } NSYNC_CPP_END_ nsync-1.24.0/platform/c++11/src/start_thread.cc000066400000000000000000000013551367521742200210650ustar00rootroot00000000000000/* Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" #include NSYNC_CPP_START_ void nsync_start_thread_ (void (*f) (void *), void *arg) { std::thread t (f, arg); t.detach (); } NSYNC_CPP_END_ nsync-1.24.0/platform/c++11/src/time_rep_timespec.cc000066400000000000000000000102041367521742200220670ustar00rootroot00000000000000/* Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync_time_init.h" #include "nsync_time.h" #include #include NSYNC_CPP_START_ #define NSYNC_NS_IN_S_ (1000 * 1000 * 1000) /* Return the maximum t, assuming it's an integral type, and the representation is not too strange. */ #define MAX_INT_TYPE(t) (((t)~(t)0) > 1? /*is t unsigned?*/ \ (t)~(t)0 : /*unsigned*/ \ (t) ((((uintmax_t)1) << (sizeof (t) * CHAR_BIT - 1)) - 1)) /*signed*/ const nsync_time nsync_time_no_deadline = NSYNC_TIME_STATIC_INIT (MAX_INT_TYPE (time_t), NSYNC_NS_IN_S_ - 1); const nsync_time nsync_time_zero = NSYNC_TIME_STATIC_INIT (0, 0); nsync_time nsync_time_s_ns (time_t s, unsigned ns) { nsync_time t; memset (&t, 0, sizeof (t)); t.tv_sec = s; t.tv_nsec = ns; return (t); } /* Return the nsync_time corresponding to tp. */ nsync_time nsync_from_time_point_ (nsync_cpp_time_point_ tp) { /* std::chrono::system_clock::to_time_t() says that "[i]t is implementation defined whether values are rounded or truncated to the required precision", which is a little tricky to use. Assume instead that the epoch for std::chrono::system_clock::time_point is the same as that for a struct timespec. This seems to be true on at least Linux, NetBSD, MacOS, and Win32; and with 64 bits gives us an implementation that will work for over 200 years. By then, we'll be able to call C++17's timespec_get. */ int64_t ns = std::chrono::duration_cast( tp.time_since_epoch ()).count(); struct timespec ts; memset (&ts, 0, sizeof (ts)); ts.tv_sec = ns / NSYNC_NS_IN_S_; ts.tv_nsec = (long) (ns - ts.tv_sec * NSYNC_NS_IN_S_); return (ts); } /* Return the nsync_cpp_time_point_ corresponding to absolute time t. */ nsync_cpp_time_point_ nsync_to_time_point_ (nsync_time t) { nsync_cpp_time_point_ tp; std::chrono::nanoseconds t_ns(NSYNC_TIME_NSEC (t) + NSYNC_NS_IN_S_ * (int64_t) NSYNC_TIME_SEC (t)); nsync_cpp_time_point_::duration tp_dur = std::chrono::duration_cast(t_ns); return (tp + tp_dur); } nsync_time nsync_time_now (void) { return (nsync_from_time_point_ (std::chrono::system_clock::now ())); } nsync_time nsync_time_sleep (nsync_time delay) { nsync_time start = nsync_time_now (); nsync_time expected_end = nsync_time_add (start, delay); nsync_time remain; std::chrono::nanoseconds delay_ns(NSYNC_TIME_NSEC (delay) + NSYNC_NS_IN_S_ * (int64_t) NSYNC_TIME_SEC (delay)); std::this_thread::sleep_for (delay_ns); nsync_time actual_end = nsync_time_now (); if (nsync_time_cmp (actual_end, expected_end) < 0) { remain = nsync_time_sub (expected_end, actual_end); } else { remain = nsync_time_zero; } return (remain); } nsync_time nsync_time_add (nsync_time a, nsync_time b) { a.tv_sec += b.tv_sec; a.tv_nsec += b.tv_nsec; if (a.tv_nsec >= NSYNC_NS_IN_S_) { a.tv_nsec -= NSYNC_NS_IN_S_; a.tv_sec++; } return (a); } nsync_time nsync_time_sub (nsync_time a, nsync_time b) { a.tv_sec -= b.tv_sec; if (a.tv_nsec < b.tv_nsec) { a.tv_nsec += NSYNC_NS_IN_S_; a.tv_sec--; } a.tv_nsec -= b.tv_nsec; return (a); } int nsync_time_cmp (nsync_time a, nsync_time b) { int cmp = (NSYNC_TIME_SEC (a) > NSYNC_TIME_SEC (b)) - (NSYNC_TIME_SEC (a) < NSYNC_TIME_SEC (b)); if (cmp == 0) { cmp = (NSYNC_TIME_NSEC (a) > NSYNC_TIME_NSEC (b)) - (NSYNC_TIME_NSEC (a) < NSYNC_TIME_NSEC (b)); } return (cmp); } NSYNC_CPP_END_ nsync-1.24.0/platform/c++11/src/time_rep_timespec_test.cc000066400000000000000000000223571367521742200231420ustar00rootroot00000000000000/* Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "compiler.h" #include "nsync.h" #include "time_extra.h" #include "smprintf.h" /* #include "closure.h" */ #include "testing.h" /* Test that the functions that accept and return C++11 time_point values work as advertised. */ NSYNC_CPP_USING_ /* Test the form of nsync_counter_wait() that takes a time_point. */ static void test_nsync_counter_wait_cpp (testing t) { nsync_time start; nsync_time waited; nsync_counter c = nsync_counter_new (1); start = nsync_time_now (); if (nsync_counter_wait (c, std::chrono::system_clock::now () + std::chrono::milliseconds (1000)) != 1) { TEST_ERROR (t, ("counter is not 1 (1s wait)")); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("timed wait on non-zero counter returned too quickly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed wait on non-zero counter returned too slowly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_counter_add (c, -1) != 0) { TEST_ERROR (t, ("zero counter is not 0 (add)")); } if (nsync_counter_wait (c, std::chrono::system_clock::now () + std::chrono::milliseconds (1000)) != 0) { TEST_ERROR (t, ("counter is not 0 (1s wait)")); } nsync_counter_free (c); } /* Call nsync_mu_lock() on v. */ static void mu_lock (void *v) { nsync_mu_lock ((nsync_mu *) v); } /* Call nsync_mu_unlock() on v. */ static void mu_unlock (void *v) { nsync_mu_unlock ((nsync_mu *) v); } /* Test the forms of nsync_cv_wait_with_deadline() and nsync_cv_wait_with_deadline_generic() that take a time_point. */ static void test_nsync_cv_wait_cpp (testing t UNUSED) { nsync_time start; nsync_time waited; nsync_mu mu; nsync_cv cv; nsync_mu_init (&mu); nsync_cv_init (&cv); nsync_mu_lock (&mu); start = nsync_time_now (); nsync_cv_wait_with_deadline (&cv, &mu, std::chrono::system_clock::now () + std::chrono::milliseconds (1000), nullptr); waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("timed wait on condition variable returned too quickly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed wait on condition variable returned too slowly (1s wait took %s)", nsync_time_str (waited, 2))); } start = nsync_time_now (); nsync_cv_wait_with_deadline_generic (&cv, &mu, &mu_lock, &mu_unlock, std::chrono::system_clock::now () + std::chrono::milliseconds (1000), nullptr); waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("timed wait generic on condition variable returned too quickly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed wait generic on condition variable returned too slowly (1s wait took %s)", nsync_time_str (waited, 2))); } nsync_mu_unlock (&mu); } /* A false condition. */ static int false_cond (const void *v UNUSED) { return (0); } /* Test the form of nsync_mu_wait_with_deadline() that takes a time_point. */ static void test_nsync_mu_wait_cpp (testing t UNUSED) { nsync_time start; nsync_time waited; nsync_mu mu; nsync_mu_init (&mu); nsync_mu_lock (&mu); start = nsync_time_now (); nsync_mu_wait_with_deadline (&mu, &false_cond, nullptr, nullptr, std::chrono::system_clock::now () + std::chrono::milliseconds (1000), nullptr); waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("timed wait on mutex returned too quickly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed wait on mutex returned too slowly (1s wait took %s)", nsync_time_str (waited, 2))); } nsync_mu_unlock (&mu); } /* Test the forms of nsync_note_new() and nsync_note_wait() that take a time_point, plus nsync_note_expiry_timepoint(). */ static void test_nsync_note_wait_cpp (testing t) { nsync_time start; nsync_time waited; std::chrono::system_clock::time_point now = std::chrono::system_clock::now (); std::chrono::system_clock::time_point expected_expiry = now + std::chrono::milliseconds (2000); nsync_note n = nsync_note_new (nullptr, expected_expiry); std::chrono::system_clock::time_point expiry = nsync_note_expiry_timepoint (n); /* Assume that "system_clock" is no coarser than 100ms */ if (expiry < expected_expiry - std::chrono::milliseconds(101)) { TEST_ERROR (t, ("expiry earlier than expected")); } if (expected_expiry + std::chrono::milliseconds(101) < expiry) { TEST_ERROR (t, ("expiry later than expected")); } start = nsync_time_now (); if (nsync_note_wait (n, std::chrono::system_clock::now () + std::chrono::milliseconds (1000))) { TEST_ERROR (t, ("note is ready (1s wait)")); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("timed wait on non-ready note returned too quickly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (1900)) > 0) { TEST_ERROR (t, ("timed wait on non-ready note returned too slowly (1s wait took %s)", nsync_time_str (waited, 2))); } start = nsync_time_now (); if (!nsync_note_wait (n, std::chrono::system_clock::now () + std::chrono::milliseconds (2000))) { TEST_ERROR (t, ("note did not expire (2s wait)")); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("timed wait on expired note returned too quickly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (1900)) > 0) { TEST_ERROR (t, ("timed wait on expired note returned too slowly (1s wait took %s)", nsync_time_str (waited, 2))); } nsync_note_free (n); } /* Test the form of nsync_wait_n() that takes a time_point. */ static void test_nsync_wait_n_cpp (testing t UNUSED) { nsync_time start; nsync_time waited; struct nsync_waitable_s w[1]; struct nsync_waitable_s *wp[1]; nsync_note n = nsync_note_new (nullptr, std::chrono::system_clock::now () + std::chrono::milliseconds (2000)); w[0].v = n; w[0].funcs = &nsync_note_waitable_funcs; wp[0] = &w[0]; start = nsync_time_now (); nsync_wait_n (nullptr, nullptr, nullptr, std::chrono::system_clock::now () + std::chrono::milliseconds (1000), 1, wp); waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("timed wait_n on non-ready note returned too quickly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed wait_n on non-ready note returned too slowly (1s wait took %s)", nsync_time_str (waited, 2))); } nsync_note_free (n); } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_nsync_counter_wait_cpp); TEST_RUN (tb, test_nsync_cv_wait_cpp); TEST_RUN (tb, test_nsync_mu_wait_cpp); TEST_RUN (tb, test_nsync_note_wait_cpp); TEST_RUN (tb, test_nsync_wait_n_cpp); return (testing_base_exit (tb)); } #if 0 #define NSYNC_WAITER_CPP_OVERLOAD_ \ static inline int nsync_wait_n (void *mu, void (*lock) (void *), \ void (*unlock) (void *), \ nsync_cpp_time_point_ abs_deadline, \ int count, struct nsync_waitable_s *waitable[]) { \ return (nsync_wait_n (mu, lock, unlock, \ nsync_from_time_point_ (abs_deadline), count, waitable)); \ } #endif nsync-1.24.0/platform/c++11/src/yield.cc000066400000000000000000000013031367521742200175000ustar00rootroot00000000000000/* Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" #include NSYNC_CPP_START_ void nsync_yield_ (void) { std::this_thread::yield (); } NSYNC_CPP_END_ nsync-1.24.0/platform/c11/000077500000000000000000000000001367521742200151515ustar00rootroot00000000000000nsync-1.24.0/platform/c11/atomic.h000066400000000000000000000106411367521742200166000ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_C11_ATOMIC_H_ #define NSYNC_PLATFORM_C11_ATOMIC_H_ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #include "compiler.h" #include "nsync_atomic.h" NSYNC_CPP_START_ static __inline__ int atm_cas_nomb_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (atomic_compare_exchange_strong_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, memory_order_relaxed, memory_order_relaxed)); } static __inline__ int atm_cas_acq_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (atomic_compare_exchange_strong_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, memory_order_acquire, memory_order_relaxed)); } static __inline__ int atm_cas_rel_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (atomic_compare_exchange_strong_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, memory_order_release, memory_order_relaxed)); } static __inline__ int atm_cas_relacq_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (atomic_compare_exchange_strong_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, memory_order_acq_rel, memory_order_relaxed)); } #define ATM_CAS_HELPER_(barrier, p, o, n) (atm_cas_##barrier##_u32_ ((p), (o), (n))) #define ATM_CAS(p,o,n) ATM_CAS_HELPER_ (nomb, (p), (o), (n)) #define ATM_CAS_ACQ(p,o,n) ATM_CAS_HELPER_ (acq, (p), (o), (n)) #define ATM_CAS_REL(p,o,n) ATM_CAS_HELPER_ (rel, (p), (o), (n)) #define ATM_CAS_RELACQ(p,o,n) ATM_CAS_HELPER_ (relacq, (p), (o), (n)) /* Need a cast to remove "const" from some uses. */ #define ATM_LOAD(p) (atomic_load_explicit ((nsync_atomic_uint32_ *) NSYNC_ATOMIC_UINT32_PTR_ (p), memory_order_relaxed)) #define ATM_LOAD_ACQ(p) (atomic_load_explicit ((nsync_atomic_uint32_ *) NSYNC_ATOMIC_UINT32_PTR_ (p), memory_order_acquire)) #define ATM_STORE(p,v) (atomic_store_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), (v), memory_order_relaxed)) #define ATM_STORE_REL(p,v) (atomic_store_explicit (NSYNC_ATOMIC_UINT32_PTR_ (p), (v), memory_order_release)) NSYNC_CPP_END_ #endif /*NSYNC_PLATFORM_C11_ATOMIC_H_*/ nsync-1.24.0/platform/c_from_c++11/000077500000000000000000000000001367521742200166245ustar00rootroot00000000000000nsync-1.24.0/platform/c_from_c++11/src/000077500000000000000000000000001367521742200174135ustar00rootroot00000000000000nsync-1.24.0/platform/c_from_c++11/src/nsync_atm_c++.cc000066400000000000000000000107101367521742200223440ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ and ATM_CAS_RELACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL and ATM_CAS_RELACQ, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, and *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #include #include "platform.h" #include "nsync_atomic.h" #include "nsync_cpp.h" NSYNC_CPP_USING_ NSYNC_C_START_ int assert_atomic32_size_ = 1 / (sizeof (uint32_t) == sizeof (nsync_atomic_uint32_)); typedef std::atomic nsync_atomic_uint32_cpp_; // Helper routines for C++ implementation of atomic operations. int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { return (std::atomic_compare_exchange_strong_explicit ((nsync_atomic_uint32_cpp_ *) p, &old_value, new_value, std::memory_order_relaxed, std::memory_order_relaxed)); } int nsync_atm_cas_acq_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { return (std::atomic_compare_exchange_strong_explicit ((nsync_atomic_uint32_cpp_ *) p, &old_value, new_value, std::memory_order_acquire, std::memory_order_relaxed)); } int nsync_atm_cas_rel_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { return (std::atomic_compare_exchange_strong_explicit ((nsync_atomic_uint32_cpp_ *) p, &old_value, new_value, std::memory_order_release, std::memory_order_relaxed)); } int nsync_atm_cas_relacq_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { return (std::atomic_compare_exchange_strong_explicit ((nsync_atomic_uint32_cpp_ *) p, &old_value, new_value, std::memory_order_acq_rel, std::memory_order_relaxed)); } uint32_t nsync_atm_load_ (const nsync_atomic_uint32_ *p) { return (std::atomic_load_explicit ((nsync_atomic_uint32_cpp_ *) p, std::memory_order_relaxed)); } uint32_t nsync_atm_load_acq_ (const nsync_atomic_uint32_ *p) { return (std::atomic_load_explicit ((nsync_atomic_uint32_cpp_ *) p, std::memory_order_acquire)); } void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { std::atomic_store_explicit ((nsync_atomic_uint32_cpp_ *) p, value, std::memory_order_relaxed); } void nsync_atm_store_rel_ (nsync_atomic_uint32_ *p, uint32_t value) { std::atomic_store_explicit ((nsync_atomic_uint32_cpp_ *) p, value, std::memory_order_release); } NSYNC_C_END_ nsync-1.24.0/platform/clang/000077500000000000000000000000001367521742200156515ustar00rootroot00000000000000nsync-1.24.0/platform/clang/atomic.h000066400000000000000000000013221367521742200172740ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_CLANG_ATOMIC_H_ #define NSYNC_PLATFORM_CLANG_ATOMIC_H_ #include "../gcc/atomic.h" #endif /*NSYNC_PLATFORM_CLANG_ATOMIC_H_*/ nsync-1.24.0/platform/clang/compiler.h000066400000000000000000000014701367521742200176360ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_CLANG_COMPILER_H_ #define NSYNC_PLATFORM_CLANG_COMPILER_H_ #define INLINE __inline #define UNUSED __attribute__((unused)) #define THREAD_LOCAL __thread #define HAVE_THREAD_LOCAL 1 #endif /*NSYNC_PLATFORM_CLANG_COMPILER_H_*/ nsync-1.24.0/platform/cygwin/000077500000000000000000000000001367521742200160655ustar00rootroot00000000000000nsync-1.24.0/platform/cygwin/platform.h000066400000000000000000000017011367521742200200610ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_CYGWIN_PLATFORM_H_ #define NSYNC_PLATFORM_CYGWIN_PLATFORM_H_ #if !defined(_GNU_SOURCE) #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #endif /*NSYNC_PLATFORM_CYGWIN_PLATFORM_H_*/ nsync-1.24.0/platform/decc/000077500000000000000000000000001367521742200154635ustar00rootroot00000000000000nsync-1.24.0/platform/decc/compiler.h000066400000000000000000000014471367521742200174540ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_DECC_COMPILER_H_ #define NSYNC_PLATFORM_DECC_COMPILER_H_ #define INLINE __inline #define UNUSED #define THREAD_LOCAL __declspec(thread) #define HAVE_THREAD_LOCAL 1 #endif /*NSYNC_PLATFORM_DECC_COMPILER_H_*/ nsync-1.24.0/platform/freebsd/000077500000000000000000000000001367521742200161775ustar00rootroot00000000000000nsync-1.24.0/platform/freebsd/platform.h000066400000000000000000000016701367521742200202000ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_FREEBSD_PLATFORM_H_ #define NSYNC_PLATFORM_FREEBSD_PLATFORM_H_ #include #include #include #include #include #include #include #include #include #include #include #include #endif /*NSYNC_PLATFORM_FREEBSD_PLATFORM_H_*/ nsync-1.24.0/platform/gcc/000077500000000000000000000000001367521742200153215ustar00rootroot00000000000000nsync-1.24.0/platform/gcc/atomic.h000066400000000000000000000054201367521742200167470ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_GCC_ATOMIC_H_ #define NSYNC_PLATFORM_GCC_ATOMIC_H_ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ and ATM_CAS_RELACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL and ATM_CAS_RELACQ, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, and *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #if !defined(__GNUC__) || \ ((__GNUC__ - 0) * 100 + (__GNUC_MINOR__ - 0)) < 407 || \ defined(__INTEL_COMPILER) || defined(__clang__) #include "../gcc_old/atomic.h" #else #include "../gcc_new/atomic.h" #endif #endif /*NSYNC_PLATFORM_GCC_ATOMIC_H_*/ nsync-1.24.0/platform/gcc/compiler.h000066400000000000000000000014621367521742200173070ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_GCC_COMPILER_H_ #define NSYNC_PLATFORM_GCC_COMPILER_H_ #define INLINE __inline #define UNUSED __attribute__((unused)) #define THREAD_LOCAL __thread #define HAVE_THREAD_LOCAL 1 #endif /*NSYNC_PLATFORM_GCC_COMPILER_H_*/ nsync-1.24.0/platform/gcc_new/000077500000000000000000000000001367521742200161725ustar00rootroot00000000000000nsync-1.24.0/platform/gcc_new/atomic.h000066400000000000000000000104251367521742200176210ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_GCC_NEW_ATOMIC_H_ #define NSYNC_PLATFORM_GCC_NEW_ATOMIC_H_ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #include "compiler.h" #include "nsync_atomic.h" NSYNC_CPP_START_ /* GCC 4.7 or later --- has new-style atomic ops */ static __inline__ int atm_cas_nomb_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (__atomic_compare_exchange_n (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED)); } static __inline__ int atm_cas_acq_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (__atomic_compare_exchange_n (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)); } static __inline__ int atm_cas_rel_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (__atomic_compare_exchange_n (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED)); } static __inline__ int atm_cas_relacq_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (__atomic_compare_exchange_n (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)); } #define ATM_CAS_HELPER_(barrier, p, o, n) (atm_cas_##barrier##_u32_ ((p), (o), (n))) #define ATM_CAS(p,o,n) ATM_CAS_HELPER_ (nomb, (p), (o), (n)) #define ATM_CAS_ACQ(p,o,n) ATM_CAS_HELPER_ (acq, (p), (o), (n)) #define ATM_CAS_REL(p,o,n) ATM_CAS_HELPER_ (rel, (p), (o), (n)) #define ATM_CAS_RELACQ(p,o,n) ATM_CAS_HELPER_ (relacq, (p), (o), (n)) #define ATM_LOAD(p) (__atomic_load_n (NSYNC_ATOMIC_UINT32_PTR_ (p), __ATOMIC_RELAXED)) #define ATM_LOAD_ACQ(p) (__atomic_load_n (NSYNC_ATOMIC_UINT32_PTR_ (p), __ATOMIC_ACQUIRE)) #define ATM_STORE(p,v) (__atomic_store_n (NSYNC_ATOMIC_UINT32_PTR_ (p), (v), __ATOMIC_RELAXED)) #define ATM_STORE_REL(p,v) (__atomic_store_n (NSYNC_ATOMIC_UINT32_PTR_ (p), (v), __ATOMIC_RELEASE)) NSYNC_CPP_END_ #endif /*NSYNC_PLATFORM_GCC_NEW_ATOMIC_H_*/ nsync-1.24.0/platform/gcc_new_debug/000077500000000000000000000000001367521742200173405ustar00rootroot00000000000000nsync-1.24.0/platform/gcc_new_debug/atomic.h000066400000000000000000000117641367521742200207760ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_GCC_NEW_DEBUG_ATOMIC_H_ #define NSYNC_PLATFORM_GCC_NEW_DEBUG_ATOMIC_H_ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #include "compiler.h" #include "nsync_atomic.h" NSYNC_CPP_START_ /* GCC 4.7 or later --- has new-style atomic ops */ static __inline__ int atm_cas_nomb_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (__atomic_compare_exchange_n (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED)); } static __inline__ int atm_cas_acq_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (__atomic_compare_exchange_n (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)); } static __inline__ int atm_cas_rel_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (__atomic_compare_exchange_n (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED)); } static __inline__ int atm_cas_relacq_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (__atomic_compare_exchange_n (NSYNC_ATOMIC_UINT32_PTR_ (p), &o, n, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)); } #if NSYNC_ATM_LOG #include "atm_log.h" #define ATM_LOG_VAL_(c,p,o,n) (nsync_atm_log_ ((c), (p), (o), (n), __FILE__, __LINE__), (o)) #define ATM_LOG_NO_VAL_(c,p,o,n) (nsync_atm_log_ ((c), (p), (o), (n), __FILE__, __LINE__)) #else #define ATM_LOG_VAL_(c,p,o,n) (o) #define ATM_LOG_NO_VAL_(c,p,o,n) ((void)0) #endif #define ATM_CAS_HELPER_(barrier, p, o, n) \ ( \ ATM_LOG_NO_VAL_ ('P', (p), (o), (n)), \ atm_cas_##barrier##_u32_ ((p), (o), (n)) ? \ (ATM_LOG_NO_VAL_ ('C', (p), (o), (n)), 1) : 0 \ ) #define ATM_CAS(p,o,n) ATM_CAS_HELPER_ (nomb, (p), (o), (n)) #define ATM_CAS_ACQ(p,o,n) ATM_CAS_HELPER_ (acq, (p), (o), (n)) #define ATM_CAS_REL(p,o,n) ATM_CAS_HELPER_ (rel, (p), (o), (n)) #define ATM_CAS_RELACQ(p,o,n) ATM_CAS_HELPER_ (relacq, (p), (o), (n)) #define ATM_LOAD(p) ( ATM_LOG_VAL_ ('L', (p), \ __atomic_load_n (NSYNC_ATOMIC_UINT32_PTR_ (p), \ __ATOMIC_RELAXED), 0)) #define ATM_LOAD_ACQ(p) ( ATM_LOG_VAL_ ('L', (p), \ __atomic_load_n (NSYNC_ATOMIC_UINT32_PTR_ (p), \ __ATOMIC_ACQUIRE), 0)) #define ATM_STORE(p,v) (ATM_LOG_NO_VAL_ ('S', (p), NSYNC_ATOMIC_UINT32_LOAD_ (p), (v)), \ __atomic_store_n (NSYNC_ATOMIC_UINT32_PTR_ (p), (v), \ __ATOMIC_RELAXED)) #define ATM_STORE_REL(p,v) (ATM_LOG_NO_VAL_ ('S', (p), NSYNC_ATOMIC_UINT32_LOAD_ (p), (v)), \ __atomic_store_n (NSYNC_ATOMIC_UINT32_PTR_ (p), (v), \ __ATOMIC_RELEASE)) NSYNC_CPP_END_ #endif /*NSYNC_PLATFORM_GCC_NEW_DEBUG_ATOMIC_H_*/ nsync-1.24.0/platform/gcc_no_tls/000077500000000000000000000000001367521742200166775ustar00rootroot00000000000000nsync-1.24.0/platform/gcc_no_tls/compiler.h000066400000000000000000000014761367521742200206720ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_GCC_NO_TLS_COMPILER_H_ #define NSYNC_PLATFORM_GCC_NO_TLS_COMPILER_H_ #define INLINE __inline #define UNUSED __attribute__((unused)) #define THREAD_LOCAL #define HAVE_THREAD_LOCAL 0 #endif /*NSYNC_PLATFORM_GCC_NO_TLS_COMPILER_H_*/ nsync-1.24.0/platform/gcc_old/000077500000000000000000000000001367521742200161575ustar00rootroot00000000000000nsync-1.24.0/platform/gcc_old/atomic.h000066400000000000000000000074501367521742200176120ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_GCC_OLD_ATOMIC_H_ #define NSYNC_PLATFORM_GCC_OLD_ATOMIC_H_ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #include "compiler.h" #include "nsync_atomic.h" NSYNC_CPP_START_ /* GCC before 4.7 or old gcc compatible --- use __sync ops. */ #if ATM_LD_IS_ACQ_ST_IS_REL_ #define ATM_LD_ACQ_ ATM_CB_ #define ATM_ST_REL_ ATM_CB_ #else #define ATM_LD_ACQ_ ATM_MB_ #define ATM_ST_REL_ ATM_MB_ #endif #define ATM_CB_() __asm__ __volatile__ ("" : : : "memory") /* compiler barrier */ #define ATM_MB_() __sync_synchronize () /*----*/ #define ATM_CAS(p,o,n) (__sync_bool_compare_and_swap (NSYNC_ATOMIC_UINT32_PTR_ (p), (o), (n))) #define ATM_CAS_ACQ ATM_CAS #define ATM_CAS_REL ATM_CAS #define ATM_CAS_RELACQ ATM_CAS /*----*/ static __inline__ uint32_t atm_load_acq_u32_ (nsync_atomic_uint32_ *p) { uint32_t result = NSYNC_ATOMIC_UINT32_LOAD_ ((volatile nsync_atomic_uint32_ *)p); ATM_LD_ACQ_ (); return (result); } #define ATM_LOAD(p) NSYNC_ATOMIC_UINT32_LOAD_ ((volatile nsync_atomic_uint32_ *)(p)) #define ATM_LOAD_ACQ(p) (atm_load_acq_u32_ (p)) /*----*/ #define ATM_STORE_X_(p,v,b,a) do { \ b; \ NSYNC_ATOMIC_UINT32_STORE_ ((volatile nsync_atomic_uint32_ *)(p), (uint32_t) (v)); \ a; \ } while (0) #define ATM_STORE(p,v) ATM_STORE_X_ ((p), (v), ; , ; ) #define ATM_STORE_REL(p,v) ATM_STORE_X_ ((p), (v), ATM_ST_REL_ (), ; ) NSYNC_CPP_END_ #endif /*NSYNC_PLATFORM_GCC_OLD_ATOMIC_H_*/ nsync-1.24.0/platform/ia64/000077500000000000000000000000001367521742200153305ustar00rootroot00000000000000nsync-1.24.0/platform/ia64/cputype.h000066400000000000000000000013341367521742200171730ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_IA64_CPUTYPE_H_ #define NSYNC_PLATFORM_IA64_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_IA64_CPUTYPE_H_*/ nsync-1.24.0/platform/ia64/src/000077500000000000000000000000001367521742200161175ustar00rootroot00000000000000nsync-1.24.0/platform/ia64/src/nsync_atm_ia64.s000066400000000000000000000073601367521742200211270ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for ia64 implementation of atomic operations. */ .pred.safe_across_calls p1-p5,p16-p63 .text /* Atomically, with release barrier semantics: int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some - non - zero - value); } else { return (0); } } */ .align 16 .global nsync_atm_cas_# .global nsync_atm_cas_rel_# .type nsync_atm_cas_rel_#, @function .proc nsync_atm_cas_rel_# nsync_atm_cas_: nsync_atm_cas_rel_: .prologue .body addp4 r33 = r33, r0 /* incoming uint32_t need not have high half zero */ mov ar.ccv = r33 /* put in ar.ccv for use by cmpxchg */ cmpxchg4.rel r34 = [r32], r34, ar.ccv addl r8 = 1, r0 /* assume success => return 1 */ cmp4.eq p6, p7 = r34, r33 (p7) mov r8 = r0 /* values not equal => return 0 */ br.ret.sptk.many b0 .endp nsync_atm_cas_rel_# /* Like nsync_atm_cas_, but with acquire barrier semantics. */ .align 16 .global nsync_atm_cas_acq_# .type nsync_atm_cas_acq_#, @function .proc nsync_atm_cas_acq_# nsync_atm_cas_acq_: .prologue .body addp4 r33 = r33, r0 /* incoming uint32_t need not have high half zero */ mov ar.ccv = r33 /* put in ar.ccv for use by cmpxchg */ cmpxchg4.acq r34 = [r32], r34, ar.ccv addl r8 = 1, r0 /* assume success => return 1 */ cmp4.eq p6, p7 = r34, r33 (p7) mov r8 = r0 /* values not equal => return 0 */ br.ret.sptk.many b0 .endp nsync_atm_cas_acq_# /* Like nsync_atm_cas_, but with both acquire and release barrier semantics. */ .align 16 .global nsync_atm_cas_relacq_# .type nsync_atm_cas_relacq_#, @function .proc nsync_atm_cas_relacq_# nsync_atm_cas_relacq_: .prologue .body addp4 r33 = r33, r0 /* incoming uint32_t need not have high half zero */ mov ar.ccv = r33 /* put in ar.ccv for use by cmpxchg */ cmpxchg4.rel r34 = [r32], r34, ar.ccv addl r8 = 1, r0 /* assume success => return 1 */ mf /* acquire barrier */ cmp4.eq p6, p7 = r34, r33 (p7) mov r8 = r0 /* values not equal => return 0 */ br.ret.sptk.many b0 .endp nsync_atm_cas_relacq_# /* Atomically: uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 16 .global nsync_atm_load_# .type nsync_atm_load_#, @function .proc nsync_atm_load_# nsync_atm_load_: .prologue .body ld4 r8 = [r32] br.ret.sptk.many b0 .endp nsync_atm_load_# /* Like nsync_atm_load_, but with acquire barrier semantics. */ .align 16 .global nsync_atm_load_acq_# .type nsync_atm_load_acq_#, @function .proc nsync_atm_load_acq_# nsync_atm_load_acq_: .prologue .body ld4.acq r8 = [r32] br.ret.sptk.many b0 .endp nsync_atm_load_acq_# /* Atomically: void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 16 .global nsync_atm_store_# .type nsync_atm_store_#, @function .proc nsync_atm_store_# nsync_atm_store_: .prologue .body st4 [r32] = r33 br.ret.sptk.many b0 .endp nsync_atm_store_# /* Like nsync_atm_store_, but with release barrier semantics. */ .align 16 .global nsync_atm_store_rel_# .type nsync_atm_store_rel_#, @function .proc nsync_atm_store_rel_# nsync_atm_store_rel_: .prologue .body st4.rel [r32] = r33 br.ret.sptk.many b0 .endp nsync_atm_store_rel_# nsync-1.24.0/platform/irix64/000077500000000000000000000000001367521742200157125ustar00rootroot00000000000000nsync-1.24.0/platform/irix64/platform.h000066400000000000000000000022411367521742200177060ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_IRIX64_PLATFORM_H_ #define NSYNC_PLATFORM_IRIX64_PLATFORM_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include /* Strangely, some Irix versions have snprintf() and vsnprintf(), yet stdio.h lacks valid signatures. */ int snprintf (char *, size_t, const char *, ...); int vsnprintf (char *, size_t, const char *, va_list); #endif /*NSYNC_PLATFORM_IRIX64_PLATFORM_H_*/ nsync-1.24.0/platform/lcc/000077500000000000000000000000001367521742200153265ustar00rootroot00000000000000nsync-1.24.0/platform/lcc/compiler.h000066400000000000000000000014101367521742200173050ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_LCC_COMPILER_H_ #define NSYNC_PLATFORM_LCC_COMPILER_H_ #define INLINE #define UNUSED #define THREAD_LOCAL #define HAVE_THREAD_LOCAL 0 #endif /*NSYNC_PLATFORM_LCC_COMPILER_H_*/ nsync-1.24.0/platform/lcc/nsync_time_init.h000066400000000000000000000016041367521742200206730ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_LCC_NSYNC_TIME_INIT_H_ #define NSYNC_PLATFORM_LCC_NSYNC_TIME_INIT_H_ #if defined(__i386__) #define NSYNC_TIME_STATIC_INIT(t,ns) { (t), 0, (ns) } /* fake 64-bit time_t with 32-bit ints */ #else #define NSYNC_TIME_STATIC_INIT(t,ns) { (t), (ns) } #endif #endif /*NSYNC_PLATFORM_LCC_NSYNC_TIME_INIT_H_*/ nsync-1.24.0/platform/linux/000077500000000000000000000000001367521742200157245ustar00rootroot00000000000000nsync-1.24.0/platform/linux/platform.h000066400000000000000000000020541367521742200177220ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_LINUX_PLATFORM_H_ #define NSYNC_PLATFORM_LINUX_PLATFORM_H_ #if !defined(_GNU_SOURCE) #define _GNU_SOURCE /* for futexes */ #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif /*NSYNC_PLATFORM_LINUX_PLATFORM_H_*/ nsync-1.24.0/platform/linux/src/000077500000000000000000000000001367521742200165135ustar00rootroot00000000000000nsync-1.24.0/platform/linux/src/nsync_semaphore_futex.c000066400000000000000000000107221367521742200232710ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ static int futex (int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3) { return (syscall (__NR_futex, uaddr, op, val, timeout, uaddr2, val3)); } /* Check that atomic operations on nsync_atomic_uint32_ can be applied to int. */ static const int assert_int_size = 1 / (sizeof (assert_int_size) == sizeof (uint32_t) && sizeof (nsync_atomic_uint32_) == sizeof (uint32_t)); #if defined(FUTEX_PRIVATE_FLAG) #define FUTEX_PRIVATE_FLAG_ FUTEX_PRIVATE_FLAG #else #define FUTEX_PRIVATE_FLAG_ 0 #endif #if defined(FUTEX_WAIT_BITSET) #define FUTEX_WAIT_ (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG_ | FUTEX_CLOCK_REALTIME) #define FUTEX_WAIT_BITS_ FUTEX_BITSET_MATCH_ANY #else #define FUTEX_WAIT_ (FUTEX_WAIT | FUTEX_PRIVATE_FLAG_) #define FUTEX_WAIT_BITS_ 0 #endif #define FUTEX_WAKE_ (FUTEX_WAKE | FUTEX_PRIVATE_FLAG_) #define FUTEX_TIMEOUT_IS_ABSOLUTE (FUTEX_WAIT_BITS_ != 0) #define ASSERT(x) do { if (!(x)) { *(volatile int *)0 = 0; } } while (0) struct futex { int i; /* lo half=count; hi half=waiter count */ }; static nsync_semaphore *sem_big_enough_for_futex = (nsync_semaphore *) (uintptr_t)(1 / (sizeof (struct futex) <= sizeof (*sem_big_enough_for_futex))); /* Initialize *s; the initial value is 0. */ void nsync_mu_semaphore_init (nsync_semaphore *s) { struct futex *f = (struct futex *) s; f->i = 0; } /* Wait until the count of *s exceeds 0, and decrement it. */ void nsync_mu_semaphore_p (nsync_semaphore *s) { struct futex *f = (struct futex *) s; int i; do { i = ATM_LOAD ((nsync_atomic_uint32_ *) &f->i); if (i == 0) { int futex_result = futex (&f->i, FUTEX_WAIT_, i, NULL, NULL, FUTEX_WAIT_BITS_); ASSERT (futex_result == 0 || errno == EINTR || errno == EWOULDBLOCK); } } while (i == 0 || !ATM_CAS_ACQ ((nsync_atomic_uint32_ *) &f->i, i, i-1)); } /* Wait until one of: the count of *s is non-zero, in which case decrement *s and return 0; or abs_deadline expires, in which case return ETIMEDOUT. */ int nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadline) { struct futex *f = (struct futex *)s; int i; int result = 0; do { i = ATM_LOAD ((nsync_atomic_uint32_ *) &f->i); if (i == 0) { int futex_result; struct timespec ts_buf; const struct timespec *ts = NULL; if (nsync_time_cmp (abs_deadline, nsync_time_no_deadline) != 0) { memset (&ts_buf, 0, sizeof (ts_buf)); if (FUTEX_TIMEOUT_IS_ABSOLUTE) { ts_buf.tv_sec = NSYNC_TIME_SEC (abs_deadline); ts_buf.tv_nsec = NSYNC_TIME_NSEC (abs_deadline); } else { nsync_time now; now = nsync_time_now (); if (nsync_time_cmp (now, abs_deadline) > 0) { ts_buf.tv_sec = 0; ts_buf.tv_nsec = 0; } else { nsync_time rel_deadline; rel_deadline = nsync_time_sub (abs_deadline, now); ts_buf.tv_sec = NSYNC_TIME_SEC (rel_deadline); ts_buf.tv_nsec = NSYNC_TIME_NSEC (rel_deadline); } } ts = &ts_buf; } futex_result = futex (&f->i, FUTEX_WAIT_, i, ts, NULL, FUTEX_WAIT_BITS_); ASSERT (futex_result == 0 || errno == EINTR || errno == EWOULDBLOCK || errno == ETIMEDOUT); /* Some systems don't wait as long as they are told. */ if (futex_result == -1 && errno == ETIMEDOUT && nsync_time_cmp (abs_deadline, nsync_time_now ()) <= 0) { result = ETIMEDOUT; } } } while (result == 0 && (i == 0 || !ATM_CAS_ACQ ((nsync_atomic_uint32_ *) &f->i, i, i - 1))); return (result); } /* Ensure that the count of *s is at least 1. */ void nsync_mu_semaphore_v (nsync_semaphore *s) { struct futex *f = (struct futex *) s; uint32_t old_value; do { old_value = ATM_LOAD ((nsync_atomic_uint32_ *) &f->i); } while (!ATM_CAS_REL ((nsync_atomic_uint32_ *) &f->i, old_value, old_value+1)); ASSERT (futex (&f->i, FUTEX_WAKE_, 1, NULL, NULL, 0) >= 0); } NSYNC_CPP_END_ nsync-1.24.0/platform/m68k/000077500000000000000000000000001367521742200153525ustar00rootroot00000000000000nsync-1.24.0/platform/m68k/cputype.h000066400000000000000000000013341367521742200172150ustar00rootroot00000000000000/* Copyright 2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_M68K_CPUTYPE_H_ #define NSYNC_PLATFORM_M68K_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 1 #endif /*NSYNC_PLATFORM_M68K_CPUTYPE_H_*/ nsync-1.24.0/platform/m68k/src/000077500000000000000000000000001367521742200161415ustar00rootroot00000000000000nsync-1.24.0/platform/m68k/src/nsync_atm_m68k.s000066400000000000000000000035061367521742200211710ustar00rootroot00000000000000/* Copyright 2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for m68k implementation of atomic operations. */ .text /* Atomically, with acquire and release barrier semantics, int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some-non-zero-value); } else { return (0); } } */ .text .align 2 .globl nsync_atm_cas_ .globl nsync_atm_cas_acq_ .globl nsync_atm_cas_rel_ .globl nsync_atm_cas_relacq_ nsync_atm_cas_: nsync_atm_cas_acq_: nsync_atm_cas_rel_: nsync_atm_cas_relacq_: link.w %fp,#0 move.l 8(%fp),%a0 move.l 12(%fp),%d0 move.l 16(%fp),%d1 cas.l %d0,%d1,(%a0) seq %d0 extb.l %d0 neg.l %d0 unlk %fp rts /* Atomically, with acquire barrier semantics, uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 2 .globl nsync_atm_load_ .globl nsync_atm_load_acq_ nsync_atm_load_: nsync_atm_load_acq_: link.w %fp,#0 move.l 8(%fp),%a0 move.l (%a0),%d0 unlk %fp rts /* Atomically, with release barrier semantics, void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 1 .align 2 .globl nsync_atm_store_ .globl nsync_atm_store_rel_ nsync_atm_store_: nsync_atm_store_rel_: link.w %fp,#0 move.l 8(%fp),%a0 move.l 12(%fp),(%a0) unlk %fp rts nsync-1.24.0/platform/macos/000077500000000000000000000000001367521742200156675ustar00rootroot00000000000000nsync-1.24.0/platform/macos/atomic.h000066400000000000000000000077551367521742200173320ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_MACOS_ATOMIC_H_ #define NSYNC_PLATFORM_MACOS_ATOMIC_H_ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #include "compiler.h" #include "nsync_atomic.h" #include NSYNC_CPP_START_ #define ATM_MB_() OSMemoryBarrier () #if ATM_LD_IS_ACQ_ST_IS_REL_ #define ATM_CB_() __asm__ __volatile__ ("" : : : "memory") /* compiler barrier */ #define ATM_LD_ACQ_ ATM_CB_ #define ATM_ST_REL_ ATM_CB_ #else #define ATM_LD_ACQ_ ATM_MB_ #define ATM_ST_REL_ ATM_MB_ #endif #define ATM_CAS(p,o,n) OSAtomicCompareAndSwap32 ((o), (n), (int32_t *) NSYNC_ATOMIC_UINT32_PTR_ (p)) #define ATM_CAS_ACQ(p,o,n) OSAtomicCompareAndSwap32Barrier ((o), (n), (int32_t *) NSYNC_ATOMIC_UINT32_PTR_ (p)) #define ATM_CAS_REL(p,o,n) OSAtomicCompareAndSwap32Barrier ((o), (n), (int32_t *) NSYNC_ATOMIC_UINT32_PTR_ (p)) #define ATM_CAS_RELACQ(p,o,n) OSAtomicCompareAndSwap32Barrier ((o), (n), (int32_t *) NSYNC_ATOMIC_UINT32_PTR_ (p)) /*----*/ static INLINE uint32_t atm_load_acq_u32_ (nsync_atomic_uint32_ *p) { uint32_t result = NSYNC_ATOMIC_UINT32_LOAD_ ((volatile nsync_atomic_uint32_ *)p); ATM_LD_ACQ_ (); return (result); } #define ATM_LOAD(p) (NSYNC_ATOMIC_UINT32_LOAD_ ((volatile nsync_atomic_uint32_ *)(p))) #define ATM_LOAD_ACQ(p) (atm_load_acq_u32_ (p)) /*----*/ #define ATM_STORE_X_(p,v,b,a) do { \ b; \ NSYNC_ATOMIC_UINT32_STORE_ ((volatile nsync_atomic_uint32_ *)(p), (uint32_t) (v)); \ a; \ } while (0) #define ATM_STORE(p,v) ATM_STORE_X_ ((p), (v), ; , ; ) #define ATM_STORE_REL(p,v) ATM_STORE_X_ ((p), (v), ATM_ST_REL_ (), ; ) NSYNC_CPP_END_ #endif /*NSYNC_PLATFORM_MACOS_ATOMIC_H_*/ nsync-1.24.0/platform/macos/platform.h000066400000000000000000000023071367521742200176660ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_MACOS_PLATFORM_H_ #define NSYNC_PLATFORM_MACOS_PLATFORM_H_ #define _DARWIN_C_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include /* Some versions(!) of MacOS don't implement clock_gettime(). */ #if !defined(CLOCK_REALTIME) #define CLOCK_REALTIME 0 typedef int clockid_t; int clock_gettime (clockid_t clk_id, struct timespec *tp); #define TIMER_ABSTIME 1 #endif /*CLOCK_REALTIME*/ #endif /*NSYNC_PLATFORM_MACOS_PLATFORM_H_*/ nsync-1.24.0/platform/macos/platform_c++11_os.h000066400000000000000000000020101367521742200211500ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_MACOS_PLATFORM_CPP_OS_H_ #define NSYNC_PLATFORM_MACOS_PLATFORM_CPP_OS_H_ /* Some versions(!) of MacOS don't implement clock_gettime(). */ #include #if !defined(CLOCK_REALTIME) #define CLOCK_REALTIME 0 #define TIMER_ABSTIME 1 NSYNC_CPP_START_ typedef int clockid_t; int clock_gettime (clockid_t clk_id, struct timespec *tp); NSYNC_CPP_END_ #endif /*CLOCK_REALTIME*/ #endif /*NSYNC_PLATFORM_MACOS_PLATFORM_CPP_OS_H_*/ nsync-1.24.0/platform/macos/src/000077500000000000000000000000001367521742200164565ustar00rootroot00000000000000nsync-1.24.0/platform/macos/src/nsync_semaphore_gcd.c000066400000000000000000000041711367521742200226370ustar00rootroot00000000000000/* Copyright 2019 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" #pragma GCC diagnostic ignored "-Wlong-long" /* to avoid error on DISPATCH_TIME_FOREVER */ #include NSYNC_CPP_START_ static nsync_semaphore *sem_big_enough_for_dispatch_semaphore_t = (void *) (1 / (sizeof (dispatch_semaphore_t) <= sizeof (*sem_big_enough_for_dispatch_semaphore_t))); /* Initialize *s; the initial value is 0. */ void nsync_mu_semaphore_init (nsync_semaphore *s) { *(dispatch_semaphore_t *)s = dispatch_semaphore_create (0); } /* Wait until the count of *s exceeds 0, and decrement it. */ void nsync_mu_semaphore_p (nsync_semaphore *s) { dispatch_semaphore_wait (*(dispatch_semaphore_t *)s, DISPATCH_TIME_FOREVER); } /* Wait until one of: the count of *s is non-zero, in which case decrement *s and return 0; or abs_deadline expires, in which case return ETIMEDOUT. */ int nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadline) { int result = 0; if (nsync_time_cmp (abs_deadline, nsync_time_no_deadline) == 0) { dispatch_semaphore_wait (*(dispatch_semaphore_t *)s, DISPATCH_TIME_FOREVER); } else { struct timespec ts; memset (&ts, 0, sizeof (ts)); ts.tv_sec = NSYNC_TIME_SEC (abs_deadline); ts.tv_nsec = NSYNC_TIME_NSEC (abs_deadline); if (dispatch_semaphore_wait (*(dispatch_semaphore_t *)s, dispatch_walltime (&abs_deadline, 0)) != 0) { result = ETIMEDOUT; } } return (result); } /* Ensure that the count of *s is at least 1. */ void nsync_mu_semaphore_v (nsync_semaphore *s) { dispatch_semaphore_signal (*(dispatch_semaphore_t *)s); } NSYNC_CPP_END_ nsync-1.24.0/platform/mips/000077500000000000000000000000001367521742200155355ustar00rootroot00000000000000nsync-1.24.0/platform/mips/cputype.h000066400000000000000000000013341367521742200174000ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_MIPS_CPUTYPE_H_ #define NSYNC_PLATFORM_MIPS_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_MIPS_CPUTYPE_H_*/ nsync-1.24.0/platform/mips/src/000077500000000000000000000000001367521742200163245ustar00rootroot00000000000000nsync-1.24.0/platform/mips/src/nsync_atm_mips.S000066400000000000000000000055461367521742200215050ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for mips implementation of atomic operations. */ #define zero $0 #define v0 $2 #define a0 $4 #define a1 $5 #define a2 $6 #define t0 $8 #define ra $31 /* Atomically: int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some-non-zero-value); } else { return (0); } } */ .text .align 2 .globl nsync_atm_cas_ .ent nsync_atm_cas_ nsync_atm_cas_: 1: ll t0, 0(a0) move v0, zero bne t0, a1, 2f move v0, a2 sc v0, 0(a0) beq v0, zero, 1b 2: j ra .end nsync_atm_cas_ /* Like nsync_atm_cas_, but with acquire barrier semantics. */ .align 2 .globl nsync_atm_cas_acq_ .ent nsync_atm_cas_acq_ nsync_atm_cas_acq_: 1: ll t0, 0(a0) move v0, zero bne t0, a1, 2f move v0, a2 sc v0, 0(a0) beq v0, zero, 1b sync 2: j ra .end nsync_atm_cas_acq_ /* Like nsync_atm_cas_, but with release barrier semantics. */ .align 2 .globl nsync_atm_cas_rel_ .ent nsync_atm_cas_rel_ nsync_atm_cas_rel_: sync 1: ll t0, 0(a0) move v0, zero bne t0, a1, 2f move v0, a2 sc v0, 0(a0) beq v0, zero, 1b 2: j ra .end nsync_atm_cas_rel_ /* Like nsync_atm_cas_, but with both acquire and release barrier semantics. */ .align 2 .globl nsync_atm_cas_relacq_ .ent nsync_atm_cas_relacq_ nsync_atm_cas_relacq_: sync 1: ll t0, 0(a0) move v0, zero bne t0, a1, 2f move v0, a2 sc v0, 0(a0) beq v0, zero, 1b sync 2: j ra .end nsync_atm_cas_relacq_ /* Atomically: uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 2 .globl nsync_atm_load_ .ent nsync_atm_load_ nsync_atm_load_: lw v0, 0(a0) j ra .end nsync_atm_load_ /* Like nsync_atm_load_, but with acquire barrier semantics. */ .align 2 .globl nsync_atm_load_acq_ .ent nsync_atm_load_acq_ nsync_atm_load_acq_: lw v0, 0(a0) sync j ra .end nsync_atm_load_acq_ /* Atomically: void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 2 .globl nsync_atm_store_ .ent nsync_atm_store_ nsync_atm_store_: sw a1, 0(a0) j ra .end nsync_atm_store_ /* Like nsync_atm_store_, but with release barrier semantics. */ .align 2 .globl nsync_atm_store_rel_ .ent nsync_atm_store_rel_ nsync_atm_store_rel_: sync sw a1, 0(a0) j ra .end nsync_atm_store_rel_ nsync-1.24.0/platform/msvc/000077500000000000000000000000001367521742200155355ustar00rootroot00000000000000nsync-1.24.0/platform/msvc/compiler.h000066400000000000000000000014471367521742200175260ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_MSVC_COMPILER_H_ #define NSYNC_PLATFORM_MSVC_COMPILER_H_ #define INLINE __inline #define UNUSED #define THREAD_LOCAL __declspec(thread) #define HAVE_THREAD_LOCAL 1 #endif /*NSYNC_PLATFORM_MSVC_COMPILER_H_*/ nsync-1.24.0/platform/netbsd/000077500000000000000000000000001367521742200160445ustar00rootroot00000000000000nsync-1.24.0/platform/netbsd/atomic.h000066400000000000000000000103151367521742200174710ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_NETBSD_ATOMIC_H_ #define NSYNC_PLATFORM_NETBSD_ATOMIC_H_ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #include "compiler.h" #include "nsync_atomic.h" #include NSYNC_CPP_START_ #if ATM_LD_IS_ACQ_ST_IS_REL_ && defined(__GNUC__) #define ATM_CB_() __asm__ __volatile__ ("" : : : "memory") /* compiler barrier */ #define ATM_LD_ACQ_ ATM_CB_ #define ATM_ST_REL_ ATM_CB_ #else #define ATM_LD_ACQ_ membar_sync /* not membar_enter(); it doesn't affect preceding loads */ #define ATM_ST_REL_ membar_exit #endif static INLINE int atm_cas_nomb_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { return (atomic_cas_32 (NSYNC_ATOMIC_UINT32_PTR_ (p), o, n) == o); } static INLINE int atm_cas_acq_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { int res = (atomic_cas_32 (NSYNC_ATOMIC_UINT32_PTR_ (p), o, n) == o); membar_enter (); return (res); } #define ATM_CAS(p,o,n) (atm_cas_nomb_u32_ ((p),(o),(n))) #define ATM_CAS_ACQ(p,o,n) (atm_cas_acq_u32_ ((p),(o),(n))) #define ATM_CAS_REL(p,o,n) (membar_exit (), ATM_CAS ((p), (o), (n))) #define ATM_CAS_RELACQ(p,o,n) (membar_exit (), atm_cas_acq_u32_ ((p),(o),(n))) /*----*/ static INLINE uint32_t atm_load_acq_u32_ (nsync_atomic_uint32_ *p) { uint32_t result = NSYNC_ATOMIC_UINT32_LOAD_ ((volatile nsync_atomic_uint32_ *)p); ATM_LD_ACQ_ (); return (result); } #define ATM_LOAD(p) (NSYNC_ATOMIC_UINT32_LOAD_ ((volatile nsync_atomic_uint32_ *)(p))) #define ATM_LOAD_ACQ(p) (atm_load_acq_u32_ (p)) /*----*/ #define ATM_STORE_X_(p,v,b,a) do { \ b; \ NSYNC_ATOMIC_UINT32_STORE_ ((volatile nsync_atomic_uint32_ *)(p), (uint32_t) (v)); \ a; \ } while (0) #define ATM_STORE(p,v) ATM_STORE_X_ ((p), (v), ; , ; ) #define ATM_STORE_REL(p,v) ATM_STORE_X_ ((p), (v), ATM_ST_REL_ (), ; ) NSYNC_CPP_END_ #endif /*NSYNC_PLATFORM_NETBSD_ATOMIC_H_*/ nsync-1.24.0/platform/netbsd/platform.h000066400000000000000000000020071367521742200200400ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_NETBSD_PLATFORM_H_ #define NSYNC_PLATFORM_NETBSD_PLATFORM_H_ #if !defined(_NETBSD_SOURCE) #define _NETBSD_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #endif /*NSYNC_PLATFORM_NETBSD_PLATFORM_H_*/ nsync-1.24.0/platform/num_time/000077500000000000000000000000001367521742200164025ustar00rootroot00000000000000nsync-1.24.0/platform/num_time/nsync_time_init.h000066400000000000000000000016431367521742200217520ustar00rootroot00000000000000/* Copyright 2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_NUM_TIME_NSYNC_TIME_INIT_H_ #define NSYNC_PLATFORM_NUM_TIME_NSYNC_TIME_INIT_H_ #define NSYNC_TIME_STATIC_INIT(t,ns) \ (sizeof (nsync_time) >= 8? \ (((nsync_time) (t))*1000*1000*1000) + (nsync_time) (ns) : \ ((((nsync_time) (t))*1000) + (nsync_time) (ns / (1000 * 1000)))) #endif /*NSYNC_PLATFORM_NUM_TIME_NSYNC_TIME_INIT_H_*/ nsync-1.24.0/platform/num_time/src/000077500000000000000000000000001367521742200171715ustar00rootroot00000000000000nsync-1.24.0/platform/num_time/src/time_rep.c000066400000000000000000000053261367521742200211470ustar00rootroot00000000000000/* Copyright 2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync_time_init.h" #include "nsync_time.h" #include "nsync_once.h" NSYNC_CPP_START_ #define NSYNC_NS_IN_S_ ((nsync_time)(1000 * 1000 * 1000)) /* Return the maximum t, assuming it's an integral type, and the representation is not too strange. This macro may be used by NSYNC_TIME_MAX_ internally. */ #define MAX_INT_TYPE(t) (((t)~(t)0) > 1? /*is t unsigned?*/ \ (t)~(t)0 : /*unsigned*/ \ (t) ((((uintmax_t)1) << (sizeof (t) * CHAR_BIT - 1)) - 1)) /*signed*/ const nsync_time nsync_time_no_deadline = NSYNC_TIME_MAX_; /* May use MAX_INT_TYPE() */ const nsync_time nsync_time_zero = 0; static nsync_once initial_time_once = NSYNC_ONCE_INIT; struct timespec nsync_time_initial_; static void get_initial_time (void) { clock_gettime (CLOCK_REALTIME, &nsync_time_initial_); } nsync_time nsync_time_s_ns (time_t s, unsigned ns) { nsync_time result; if (sizeof (nsync_time) >= 8) { result = ((nsync_time) s) * NSYNC_NS_IN_S_ + (nsync_time) ns; } else { result = ((nsync_time) s) * (nsync_time) 1000 + ((nsync_time) ns) / (nsync_time) (1000 * 1000); } return (result); } nsync_time nsync_time_now (void) { struct timespec ts; if (sizeof (nsync_time) < 8) { nsync_run_once (&initial_time_once, &get_initial_time); } clock_gettime (CLOCK_REALTIME, &ts); return (nsync_time_s_ns ( ts.tv_sec - (sizeof (nsync_time) < 8? nsync_time_initial_.tv_sec: 0), ts.tv_nsec)); } nsync_time nsync_time_sleep (nsync_time delay) { struct timespec ts; struct timespec remain; memset (&ts, 0, sizeof (ts)); ts.tv_sec = NSYNC_TIME_SEC (delay); ts.tv_nsec = NSYNC_TIME_NSEC (delay); if (nanosleep (&ts, &remain) == 0) { /* nanosleep() is not required to fill in "remain" if it returns 0. */ memset (&remain, 0, sizeof (remain)); } return (nsync_time_s_ns (remain.tv_sec, remain.tv_nsec)); } nsync_time nsync_time_add (nsync_time a, nsync_time b) { return (a+b); } nsync_time nsync_time_sub (nsync_time a, nsync_time b) { return (a-b); } int nsync_time_cmp (nsync_time a, nsync_time b) { return ((a > b) - (a < b)); } NSYNC_CPP_END_ nsync-1.24.0/platform/openbsd/000077500000000000000000000000001367521742200162175ustar00rootroot00000000000000nsync-1.24.0/platform/openbsd/platform.h000066400000000000000000000020101367521742200202050ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_OPENBSD_PLATFORM_H_ #define NSYNC_PLATFORM_OPENBSD_PLATFORM_H_ #if !defined(_BSD_SOURCE) #define _BSD_SOURCE /* provided ECANCELED */ #endif #include #include #include #include #include #include #include #include #include #include #include #include #endif /*NSYNC_PLATFORM_OPENBSD_PLATFORM_H_*/ nsync-1.24.0/platform/osf1/000077500000000000000000000000001367521742200154355ustar00rootroot00000000000000nsync-1.24.0/platform/osf1/platform.h000066400000000000000000000016041367521742200174330ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_OSF1_PLATFORM_H_ #define NSYNC_PLATFORM_OSF1_PLATFORM_H_ #include #include #include #include #include #include #include #include #include #include #endif /*NSYNC_PLATFORM_OSF1_PLATFORM_H_*/ nsync-1.24.0/platform/parisc64/000077500000000000000000000000001367521742200162205ustar00rootroot00000000000000nsync-1.24.0/platform/parisc64/cputype.h000066400000000000000000000013501367521742200200610ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_PARISC64_CPUTYPE_H_ #define NSYNC_PLATFORM_PARISC64_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_PARISC64_CPUTYPE_H_*/ nsync-1.24.0/platform/parisc64/src/000077500000000000000000000000001367521742200170075ustar00rootroot00000000000000nsync-1.24.0/platform/parisc64/src/nsync_atm_parisc64.s000066400000000000000000000101271367521742200227020ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for parisc64 implementation of atomic operations. PA RISC uses ldcw (load and clear), so its CAS and store operations are interlocked with respect to one another, rather than being fully atomic. This is sufficient for nsync. */ .LEVEL 2.0 .text /* Atomically with respect to other routines in this file, with acquire and release semantics: int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some - non - zero - value); } else { return (0); } } */ .align 4 .globl nsync_atm_cas_ .globl nsync_atm_cas_acq_ .globl nsync_atm_cas_rel_ .globl nsync_atm_cas_relacq_ nsync_atm_cas_: nsync_atm_cas_acq_: nsync_atm_cas_rel_: nsync_atm_cas_relacq_: .PROC .CALLINFO FRAME=64,CALLS,SAVE_RP .ENTRY stw %r2,-20(%r30) ldo 64(%r30),%r30 1: /* map input pointer to a 16-byte aligned semaphore */ ldi 0x70,%r19 and %r26,%r19,%r19 addil LR'locks-$global$,%r27 ldo RR'locks-$global$(%r1),%r1 addl %r19,%r1,%r23 /* %r23 now points to semaphore */ ldcw 0(%r23),%r28 combt,= %r0,%r28,2f ldi 1,%r19 /* delay slot */ ldw,o 0(%r26),%r28 comclr,<> %r25,%r28,%r28 ldi 1,%r28 /* nullified if %r25!=previous %r28 */ comiclr,= 0,%r28,%r0 stw %r24,0(%r26) /* nullified if %r28==0 */ stw,o %r19,0(%r23) bv %r0(%r2) ldo -64(%r30),%r30 /* delay slot */ 2: stw %r24,-44(%r30) stw %r25,-40(%r30) stw %r26,-36(%r30) bl nsync_yield_,%r2 nop /* delay slot */ ldw -44(%r30),%r24 ldw -40(%r30),%r25 ldw -36(%r30),%r26 ldw -84(%r30),%r2 b 1b nop /* delay slot */ .EXIT .PROCEND /* Atomically with respect to other routines in this file, with release sematics: void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 4 .globl nsync_atm_store_ .globl nsync_atm_store_rel_ nsync_atm_store_: nsync_atm_store_rel_: .PROC .CALLINFO FRAME=64,CALLS,SAVE_RP .ENTRY stw %r2,-20(%r30) ldo 64(%r30),%r30 1: /* map input pointer to a 16-byte aligned semaphore */ ldi 0x70,%r19 and %r26,%r19,%r19 addil LR'locks-$global$,%r27 ldo RR'locks-$global$(%r1),%r1 addl %r19,%r1,%r23 /* %r23 now points to semaphore */ ldcw 0(%r23),%r28 combt,= %r0,%r28,2f ldi 1,%r19 /* delay slot */ stw %r25,0(%r26) stw,o %r19,0(%r23) bv %r0(%r2) ldo -64(%r30),%r30 2: stw %r25,-40(%r30) stw %r26,-36(%r30) bl nsync_yield_,%r2 nop /* delay slot */ ldw -40(%r30),%r25 ldw -36(%r30),%r26 ldw -84(%r30),%r2 b 1b nop /* delay slot */ .EXIT .PROCEND /* Atomically: uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 4 .globl nsync_atm_load_ nsync_atm_load_: .PROC .CALLINFO FRAME=0,NO_CALLS .ENTRY bv %r0(%r2) ldw 0(%r26),%r28 /* delay slot */ .EXIT .PROCEND /* Like nsync_atm_load_, but with acquire barrier semantics. */ .align 4 .globl nsync_atm_load_acq_ nsync_atm_load_acq_: .PROC .CALLINFO FRAME=0,NO_CALLS .ENTRY bv %r0(%r2) ldw,o 0(%r26),%r28 /* delay slot */ .EXIT .PROCEND .data .align 4 locks: .word 1 .word 0 .word 0 .word 0 .word 1 .word 0 .word 0 .word 0 .word 1 .word 0 .word 0 .word 0 .word 1 .word 0 .word 0 .word 0 .word 1 .word 0 .word 0 .word 0 .word 1 .word 0 .word 0 .word 0 .word 1 .word 0 .word 0 .word 0 .word 1 .word 0 .word 0 .word 0 nsync-1.24.0/platform/pcc/000077500000000000000000000000001367521742200153325ustar00rootroot00000000000000nsync-1.24.0/platform/pcc/compiler.h000066400000000000000000000015131367521742200173150ustar00rootroot00000000000000/* Copyright 2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_PCC_COMPILER_H_ #define NSYNC_PLATFORM_PCC_COMPILER_H_ #define INLINE #define UNUSED /* pcc accepts the __thread keyword, but it seems to be broken */ #define THREAD_LOCAL #define HAVE_THREAD_LOCAL 0 #endif /*NSYNC_PLATFORM_PCC_COMPILER_H_*/ nsync-1.24.0/platform/pmax/000077500000000000000000000000001367521742200155325ustar00rootroot00000000000000nsync-1.24.0/platform/pmax/cputype.h000066400000000000000000000013341367521742200173750ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_PMAX_CPUTYPE_H_ #define NSYNC_PLATFORM_PMAX_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 1 #endif /*NSYNC_PLATFORM_PMAX_CPUTYPE_H_*/ nsync-1.24.0/platform/posix/000077500000000000000000000000001367521742200157275ustar00rootroot00000000000000nsync-1.24.0/platform/posix/compiler.h000066400000000000000000000014161367521742200177140ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_POSIX_COMPILER_H_ #define NSYNC_PLATFORM_POSIX_COMPILER_H_ #define INLINE #define UNUSED #define THREAD_LOCAL #define HAVE_THREAD_LOCAL 0 #endif /*NSYNC_PLATFORM_POSIX_COMPILER_H_*/ nsync-1.24.0/platform/posix/cputype.h000066400000000000000000000013371367521742200175750ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_POSIX_CPUTYPE_H_ #define NSYNC_PLATFORM_POSIX_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_POSIX_CPUTYPE_H_*/ nsync-1.24.0/platform/posix/make.common000066400000000000000000000150641367521742200200640ustar00rootroot00000000000000# A generic Makefile included by the most platform-specific Makefiles. # Uses no fancy features, so can be included by many make variants, # but is not used by nmake. PUBLIC=../../public INTERNAL=../../internal TESTING=../../testing TOOLS=../../tools OPT=-O CPPFLAGS=${PLATFORM_CPPFLAGS} -I${PUBLIC} -I${INTERNAL} CFLAGS=${CPPFLAGS} ${OPT} ${PLATFORM_CFLAGS} CXXFLAGS=${CPPFLAGS} ${OPT} ${PLATFORM_CXXFLAGS} LDFLAGS=${OPT} ${PLATFORM_LDFLAGS} PAR_SUB_COUNT=1 # subtests to run in parallel with partest PAR_COUNT=2 # tests to run in parallel with partest LD=${CC} TESTS=counter_test cv_mu_timeout_stress_test cv_test cv_wait_example_test dll_test mu_starvation_test mu_test mu_wait_example_test mu_wait_test note_test once_test pingpong_test wait_test TEST_OBJS=counter_test.o cv_mu_timeout_stress_test.o cv_test.o cv_wait_example_test.o dll_test.o mu_starvation_test.o mu_test.o mu_wait_example_test.o mu_wait_test.o note_test.o once_test.o pingpong_test.o wait_test.o TEST_LIB_OBJS=array.o atm_log.o closure.o time_extra.o smprintf.o testing.o ${TEST_PLATFORM_OBJS} LIB_OBJS=common.o counter.o cv.o debug.o dll.o mu.o mu_wait.o note.o once.o sem_wait.o time_internal.o wait.o ${PLATFORM_OBJS} LIB=libnsync.a LIBALTNAME=nsync.a TEST_LIB=nsync_test.a all: ${LIB} ${LIBALTNAME} ${LIB}: ${LIB_OBJS} ${AR} cr ${LIB} $? case "${RANLIB}" in "") ;; *) ${RANLIB} ${LIB};; esac # Older versions of this package exported a different library name. ${LIBALTNAME}: ${LIB} cp ${LIB} ${LIBALTNAME} case "${RANLIB}" in "") ;; *) ${RANLIB} ${LIBALTNAME};; esac ${TEST_LIB}: ${TEST_LIB_OBJS} ${AR} cr ${TEST_LIB} $? case "${RANLIB}" in "") ;; *) ${RANLIB} ${TEST_LIB};; esac clean: rm -f ${LIB} ${LIBALTNAME} ${TEST_LIB} ${TESTS} ${TEST_OBJS} ${TEST_LIB_OBJS} ${LIB_OBJS} mkdep run_tests tests: ${TESTS} test: tests run_tests PATH="$$PATH:." ./run_tests -b ${TESTS} partest: tests run_tests PATH="$$PATH:." ./run_tests -p ${PAR_COUNT} -n ${PAR_SUB_COUNT} -b ${TESTS} run_tests: ${TOOLS}/run_tests.c ${CC} ${TOOLS}/run_tests.c -o run_tests mkdep: ${TOOLS}/mkdep.c ${CC} ${TOOLS}/mkdep.c -o mkdep depend: ${MKDEP_DEPEND} ${MKDEP} ${CPPFLAGS} ${INTERNAL}/*.c ${TESTING}/*.c ${PLATFORM_C} \ ${PLATFORM_S} ${PLATFORM_CXX} ${TEST_PLATFORM_C} > dependfile ${PLATFORM_OBJS}: ${PLATFORM_C} ${PLATFORM_S} ${PLATFORM_CXX} set -x; \ for x in ${PLATFORM_C} $$empty; do ${CC} ${CFLAGS} -c $$x || exit 1; done; \ for x in ${PLATFORM_S} $$empty; do o=`basename $$x .s`; ${AS} ${ASFLAGS} $$x -o `basename $$o .S`.o || exit 1; done; \ for x in ${PLATFORM_CXX} $$empty; do ${CXX} ${CXXFLAGS} -c $$x || exit 1; done ${TEST_PLATFORM_OBJS}: ${TEST_PLATFORM_C}; set -x; for x in ${TEST_PLATFORM_C}; do ${CC} ${CFLAGS} -c $$x || exit 1; done common.o: ${INTERNAL}/common.c; ${CC} ${CFLAGS} -c ${INTERNAL}/common.c counter.o: ${INTERNAL}/counter.c; ${CC} ${CFLAGS} -c ${INTERNAL}/counter.c cv.o: ${INTERNAL}/cv.c; ${CC} ${CFLAGS} -c ${INTERNAL}/cv.c debug.o: ${INTERNAL}/debug.c; ${CC} ${CFLAGS} -c ${INTERNAL}/debug.c dll.o: ${INTERNAL}/dll.c; ${CC} ${CFLAGS} -c ${INTERNAL}/dll.c mu.o: ${INTERNAL}/mu.c; ${CC} ${CFLAGS} -c ${INTERNAL}/mu.c mu_wait.o: ${INTERNAL}/mu_wait.c; ${CC} ${CFLAGS} -c ${INTERNAL}/mu_wait.c note.o: ${INTERNAL}/note.c; ${CC} ${CFLAGS} -c ${INTERNAL}/note.c time_internal.o: ${INTERNAL}/time_internal.c; ${CC} ${CFLAGS} -c ${INTERNAL}/time_internal.c once.o: ${INTERNAL}/once.c; ${CC} ${CFLAGS} -c ${INTERNAL}/once.c sem_wait.o: ${INTERNAL}/sem_wait.c; ${CC} ${CFLAGS} -c ${INTERNAL}/sem_wait.c wait.o: ${INTERNAL}/wait.c; ${CC} ${CFLAGS} -c ${INTERNAL}/wait.c array.o: ${TESTING}/array.c; ${CC} ${CFLAGS} -c ${TESTING}/array.c atm_log.o: ${TESTING}/atm_log.c; ${CC} ${CFLAGS} -c ${TESTING}/atm_log.c closure.o: ${TESTING}/closure.c; ${CC} ${CFLAGS} -c ${TESTING}/closure.c counter_test.o: ${TESTING}/counter_test.c; ${CC} ${CFLAGS} -c ${TESTING}/counter_test.c cv_mu_timeout_stress_test.o: ${TESTING}/cv_mu_timeout_stress_test.c; ${CC} ${CFLAGS} -c ${TESTING}/cv_mu_timeout_stress_test.c cv_test.o: ${TESTING}/cv_test.c; ${CC} ${CFLAGS} -c ${TESTING}/cv_test.c cv_wait_example_test.o: ${TESTING}/cv_wait_example_test.c; ${CC} ${CFLAGS} -c ${TESTING}/cv_wait_example_test.c dll_test.o: ${TESTING}/dll_test.c; ${CC} ${CFLAGS} -c ${TESTING}/dll_test.c mu_starvation_test.o: ${TESTING}/mu_starvation_test.c; ${CC} ${CFLAGS} -c ${TESTING}/mu_starvation_test.c mu_test.o: ${TESTING}/mu_test.c; ${CC} ${CFLAGS} -c ${TESTING}/mu_test.c mu_wait_example_test.o: ${TESTING}/mu_wait_example_test.c; ${CC} ${CFLAGS} -c ${TESTING}/mu_wait_example_test.c mu_wait_test.o: ${TESTING}/mu_wait_test.c; ${CC} ${CFLAGS} -c ${TESTING}/mu_wait_test.c note_test.o: ${TESTING}/note_test.c; ${CC} ${CFLAGS} -c ${TESTING}/note_test.c once_test.o: ${TESTING}/once_test.c; ${CC} ${CFLAGS} -c ${TESTING}/once_test.c time_extra.o: ${TESTING}/time_extra.c; ${CC} ${CFLAGS} -c ${TESTING}/time_extra.c pingpong_test.o: ${TESTING}/pingpong_test.c; ${CC} ${CFLAGS} -c ${TESTING}/pingpong_test.c smprintf.o: ${TESTING}/smprintf.c; ${CC} ${CFLAGS} -c ${TESTING}/smprintf.c testing.o: ${TESTING}/testing.c; ${CC} ${CFLAGS} -c ${TESTING}/testing.c wait_test.o: ${TESTING}/wait_test.c; ${CC} ${CFLAGS} -c ${TESTING}/wait_test.c counter_test: counter_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} cv_mu_timeout_stress_test: cv_mu_timeout_stress_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} cv_test: cv_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} cv_wait_example_test: cv_wait_example_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} dll_test: dll_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} mu_starvation_test: mu_starvation_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} mu_test: mu_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} mu_wait_example_test: mu_wait_example_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} mu_wait_test: mu_wait_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} note_test: note_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} once_test: once_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} pingpong_test: pingpong_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} wait_test: wait_test.o ${TEST_LIB} ${LIB}; ${LD} ${LDFLAGS} -o $@ $@.o ${TEST_LIB} ${LIB} ${PLATFORM_LIBS} nsync-1.24.0/platform/posix/nsync_time_init.h000066400000000000000000000014071367521742200212750ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_POSIX_NSYNC_TIME_INIT_H_ #define NSYNC_PLATFORM_POSIX_NSYNC_TIME_INIT_H_ #define NSYNC_TIME_STATIC_INIT(t,ns) { (t), (ns) } #endif /*NSYNC_PLATFORM_POSIX_NSYNC_TIME_INIT_H_*/ nsync-1.24.0/platform/posix/platform.h000066400000000000000000000017101367521742200177230ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_POSIX_PLATFORM_H_ #define NSYNC_PLATFORM_POSIX_PLATFORM_H_ #include #include #include #include #include #include #include #include #include #include #include #include #include #endif /*NSYNC_PLATFORM_POSIX_PLATFORM_H_*/ nsync-1.24.0/platform/posix/platform_c++11_os.h000066400000000000000000000010761367521742200212230ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ nsync-1.24.0/platform/posix/src/000077500000000000000000000000001367521742200165165ustar00rootroot00000000000000nsync-1.24.0/platform/posix/src/clock_gettime.c000066400000000000000000000015201367521742200214710ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ int clock_gettime(clockid_t clk_id UNUSED, struct timespec *tp) { struct timeval tv; int rc = gettimeofday(&tv, NULL); if (rc == 0) { tp->tv_sec = tv.tv_sec; tp->tv_nsec = tv.tv_usec * 1000; } return (rc); } NSYNC_CPP_END_ nsync-1.24.0/platform/posix/src/nsync_panic.c000066400000000000000000000023471367521742200211740ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ /* Write the nul-terminated string s[] to file descriptor fd. */ static void writestr (int fd, const char *s) { int len = strlen (s); int n = 0; while (len != 0 && n >= 0) { n = write (fd, s, len); if (n >= 0) { len -= n; s += n; } else if (n == -1 && errno == EINTR) { n = 0; } } } /* Abort after printing the nul-terminated string s[]. */ void nsync_panic_ (const char *s) { writestr (2, "panic: "); writestr (2, s); abort (); } NSYNC_CPP_END_ nsync-1.24.0/platform/posix/src/nsync_semaphore_mutex.c000066400000000000000000000056321367521742200233070ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ #define ASSERT(x) do { if (!(x)) { *(volatile int *)0 = 0; } } while (0) struct mutex_cond { pthread_mutex_t mu; pthread_cond_t cv; uint32_t i; }; static nsync_semaphore *sem_big_enough_for_mutex_cond = (nsync_semaphore *) (1 / (sizeof (struct mutex_cond) <= sizeof (*sem_big_enough_for_mutex_cond))); /* Initialize *s; the initial value is 0. */ void nsync_mu_semaphore_init (nsync_semaphore *s) { struct mutex_cond *mc = (struct mutex_cond *) s; ASSERT (pthread_mutex_init (&mc->mu, NULL) == 0); ASSERT (pthread_cond_init (&mc->cv, NULL) == 0); mc->i = 0; } /* Wait until the count of *s exceeds 0, and decrement it. */ void nsync_mu_semaphore_p (nsync_semaphore *s) { struct mutex_cond *mc = (struct mutex_cond *) s; ASSERT (pthread_mutex_lock (&mc->mu) == 0); while (mc->i == 0) { ASSERT (pthread_cond_wait (&mc->cv, &mc->mu) == 0); } mc->i = 0; ASSERT (pthread_mutex_unlock (&mc->mu) == 0); } /* Wait until one of: the count of *s is non-zero, in which case decrement *s and return 0; or abs_deadline expires, in which case return ETIMEDOUT. */ int nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadline) { struct mutex_cond *mc = (struct mutex_cond *)s; int res = 0; ASSERT (pthread_mutex_lock (&mc->mu) == 0); if (nsync_time_cmp (abs_deadline, nsync_time_no_deadline) == 0) { while (mc->i == 0) { ASSERT (pthread_cond_wait (&mc->cv, &mc->mu) == 0); } mc->i = 0; } else { struct timespec ts_deadline; memset (&ts_deadline, 0, sizeof (ts_deadline)); ts_deadline.tv_sec = NSYNC_TIME_SEC (abs_deadline); ts_deadline.tv_nsec = NSYNC_TIME_NSEC (abs_deadline); while (mc->i == 0 && ((res = pthread_cond_timedwait (&mc->cv, &mc->mu, &ts_deadline)) == 0 || (res == ETIMEDOUT && /* Various systems wake up too early. */ nsync_time_cmp (abs_deadline, nsync_time_now ()) > 0))) { } ASSERT (res == 0 || res == ETIMEDOUT); if (mc->i != 0) { res = 0; mc->i = 0; } } ASSERT (pthread_mutex_unlock (&mc->mu) == 0); return (res); } /* Ensure that the count of *s is at least 1. */ void nsync_mu_semaphore_v (nsync_semaphore *s) { struct mutex_cond *mc = (struct mutex_cond *) s; ASSERT (pthread_mutex_lock (&mc->mu) == 0); mc->i = 1; ASSERT (pthread_cond_broadcast (&mc->cv) == 0); ASSERT (pthread_mutex_unlock (&mc->mu) == 0); } NSYNC_CPP_END_ nsync-1.24.0/platform/posix/src/nsync_semaphore_sem_t.c000066400000000000000000000041171367521742200232510ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ #define ASSERT(x) do { if (!(x)) { *(volatile int *)0 = 0; } } while (0) static nsync_semaphore *sem_big_enough_for_sem_t = (void *) (1 / (sizeof (sem_t) <= sizeof (*sem_big_enough_for_sem_t))); /* Initialize *s; the initial value is 0. */ void nsync_mu_semaphore_init (nsync_semaphore *s) { ASSERT (sem_init ((sem_t *)s, 0, 0) == 0); } /* Wait until the count of *s exceeds 0, and decrement it. */ void nsync_mu_semaphore_p (nsync_semaphore *s) { while (sem_wait ((sem_t *)s) != 0 && errno == EINTR) { } } /* Wait until one of: the count of *s is non-zero, in which case decrement *s and return 0; or abs_deadline expires, in which case return ETIMEDOUT. */ int nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadline) { int result = 0; if (nsync_time_cmp (abs_deadline, nsync_time_no_deadline) == 0) { while (sem_wait ((sem_t *)s) != 0 && errno == EINTR) { } } else { int rc; struct timespec ts; memset (&ts, 0, sizeof (ts)); ts.tv_sec = NSYNC_TIME_SEC (abs_deadline); ts.tv_nsec = NSYNC_TIME_NSEC (abs_deadline); do { rc = sem_timedwait ((sem_t *)s, &ts); } while (rc != 0 && (errno == EINTR || (errno == ETIMEDOUT && nsync_time_cmp (abs_deadline, nsync_time_now ()) > 0))); if (rc != 0 && errno == ETIMEDOUT) { result = ETIMEDOUT; } } return (result); } /* Ensure that the count of *s is at least 1. */ void nsync_mu_semaphore_v (nsync_semaphore *s) { ASSERT (sem_post ((sem_t *)s) == 0); } NSYNC_CPP_END_ nsync-1.24.0/platform/posix/src/per_thread_waiter.c000066400000000000000000000024641367521742200223600ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ static pthread_key_t waiter_key; static nsync_atomic_uint32_ pt_once; static void do_once (nsync_atomic_uint32_ *ponce, void (*dest) (void *)) { uint32_t o = ATM_LOAD_ACQ (ponce); if (o != 2) { while (o == 0 && !ATM_CAS_ACQ (ponce, 0, 1)) { o = ATM_LOAD (ponce); } if (o == 0) { pthread_key_create (&waiter_key, dest); ATM_STORE_REL (ponce, 2); } while (ATM_LOAD_ACQ (ponce) != 2) { sched_yield (); } } } void *nsync_per_thread_waiter_ (void (*dest) (void *)) { do_once (&pt_once, dest); return (pthread_getspecific (waiter_key)); } void nsync_set_per_thread_waiter_ (void *v, void (*dest) (void *)) { do_once (&pt_once, dest); pthread_setspecific (waiter_key, v); } NSYNC_CPP_END_ nsync-1.24.0/platform/posix/src/start_thread.c000066400000000000000000000020441367521742200213460ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ struct thd_args { void (*f) (void *); void *arg; }; static void *body (void *v) { struct thd_args *args = (struct thd_args *) v; (*args->f) (args->arg); free (args); return (NULL); } void nsync_start_thread_ (void (*f) (void *), void *arg) { struct thd_args *args = (struct thd_args *) malloc (sizeof (*args)); pthread_t t; args->f = f; args->arg = arg; pthread_create (&t, NULL, body, args); pthread_detach (t); } NSYNC_CPP_END_ nsync-1.24.0/platform/posix/src/time_rep.c000066400000000000000000000050751367521742200204750ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync_time_init.h" #include "nsync_time.h" NSYNC_CPP_START_ #define NSYNC_NS_IN_S_ (1000 * 1000 * 1000) /* Return the maximum t, assuming it's an integral type, and the representation is not too strange. */ #define MAX_INT_TYPE(t) (((t)~(t)0) > 1? /*is t unsigned?*/ \ (t)~(t)0 : /*unsigned*/ \ (t) ((((uintmax_t)1) << (sizeof (t) * CHAR_BIT - 1)) - 1)) /*signed*/ const nsync_time nsync_time_no_deadline = NSYNC_TIME_STATIC_INIT (MAX_INT_TYPE (time_t), NSYNC_NS_IN_S_ - 1); const nsync_time nsync_time_zero = NSYNC_TIME_STATIC_INIT (0, 0); nsync_time nsync_time_s_ns (time_t s, unsigned ns) { nsync_time t; memset (&t, 0, sizeof (t)); t.tv_sec = s; t.tv_nsec = ns; return (t); } nsync_time nsync_time_now (void) { struct timespec ts; clock_gettime (CLOCK_REALTIME, &ts); return (ts); } nsync_time nsync_time_sleep (nsync_time delay) { struct timespec ts; struct timespec remain; memset (&ts, 0, sizeof (ts)); ts.tv_sec = NSYNC_TIME_SEC (delay); ts.tv_nsec = NSYNC_TIME_NSEC (delay); if (nanosleep (&ts, &remain) == 0) { /* nanosleep() is not required to fill in "remain" if it returns 0. */ memset (&remain, 0, sizeof (remain)); } return (remain); } nsync_time nsync_time_add (nsync_time a, nsync_time b) { a.tv_sec += b.tv_sec; a.tv_nsec += b.tv_nsec; if (a.tv_nsec >= NSYNC_NS_IN_S_) { a.tv_nsec -= NSYNC_NS_IN_S_; a.tv_sec++; } return (a); } nsync_time nsync_time_sub (nsync_time a, nsync_time b) { a.tv_sec -= b.tv_sec; if (a.tv_nsec < b.tv_nsec) { a.tv_nsec += NSYNC_NS_IN_S_; a.tv_sec--; } a.tv_nsec -= b.tv_nsec; return (a); } int nsync_time_cmp (nsync_time a, nsync_time b) { int cmp = (NSYNC_TIME_SEC (a) > NSYNC_TIME_SEC (b)) - (NSYNC_TIME_SEC (a) < NSYNC_TIME_SEC (b)); if (cmp == 0) { cmp = (NSYNC_TIME_NSEC (a) > NSYNC_TIME_NSEC (b)) - (NSYNC_TIME_NSEC (a) < NSYNC_TIME_NSEC (b)); } return (cmp); } NSYNC_CPP_END_ nsync-1.24.0/platform/posix/src/time_rep_debug.c000066400000000000000000000050151367521742200216350ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "nsync_time_init.h" #include "nsync_time.h" NSYNC_CPP_START_ #define NSYNC_NS_IN_S_ (1000 * 1000 * 1000) /* Return the maximum t, assuming it's an integral type, and the representation is not too strange. */ #define MAX_INT_TYPE(t) (((t)~(t)0) > 1? /*is t unsigned?*/ \ (t)~(t)0 : /*unsigned*/ \ (t) ((((uintmax_t)1) << (sizeof (t) * CHAR_BIT - 1)) - 1)) /*signed*/ const nsync_time nsync_time_no_deadline = NSYNC_TIME_STATIC_INIT (MAX_INT_TYPE (time_t), NSYNC_NS_IN_S_ - 1); const nsync_time nsync_time_zero = NSYNC_TIME_STATIC_INIT (0, 0); nsync_time nsync_time_s_ns (time_t s, unsigned ns) { nsync_time t; t.seconds = s; t.nanoseconds = ns; return (t); } nsync_time nsync_time_now (void) { struct timespec ts; clock_gettime (CLOCK_REALTIME, &ts); return (nsync_time_s_ns (ts.tv_sec, ts.tv_nsec)); } nsync_time nsync_time_sleep (nsync_time delay) { struct timespec ts; struct timespec remain; ts.tv_sec = NSYNC_TIME_SEC (delay); ts.tv_nsec = NSYNC_TIME_NSEC (delay); if (nanosleep (&ts, &remain) == 0) { memset (&remain, 0, sizeof (remain)); } return (nsync_time_s_ns (remain.tv_sec, remain.tv_nsec)); } nsync_time nsync_time_add (nsync_time a, nsync_time b) { a.seconds += b.seconds; a.nanoseconds += b.nanoseconds; if (a.nanoseconds >= NSYNC_NS_IN_S_) { a.nanoseconds -= NSYNC_NS_IN_S_; a.seconds++; } return (a); } nsync_time nsync_time_sub (nsync_time a, nsync_time b) { a.seconds -= b.seconds; if (a.nanoseconds < b.nanoseconds) { a.nanoseconds += NSYNC_NS_IN_S_; a.seconds--; } a.nanoseconds -= b.nanoseconds; return (a); } int nsync_time_cmp (nsync_time a, nsync_time b) { int cmp = (NSYNC_TIME_SEC (a) > NSYNC_TIME_SEC (b)) - (NSYNC_TIME_SEC (a) < NSYNC_TIME_SEC (b)); if (cmp == 0) { cmp = (NSYNC_TIME_NSEC (a) > NSYNC_TIME_NSEC (b)) - (NSYNC_TIME_NSEC (a) < NSYNC_TIME_NSEC (b)); } return (cmp); } NSYNC_CPP_END_ nsync-1.24.0/platform/posix/src/yield.c000066400000000000000000000012451367521742200177720ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ void nsync_yield_ (void) { sched_yield (); } NSYNC_CPP_END_ nsync-1.24.0/platform/ppc32/000077500000000000000000000000001367521742200155145ustar00rootroot00000000000000nsync-1.24.0/platform/ppc32/cputype.h000066400000000000000000000013371367521742200173620ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_PPC32_CPUTYPE_H_ #define NSYNC_PLATFORM_PPC32_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_PPC32_CPUTYPE_H_*/ nsync-1.24.0/platform/ppc64/000077500000000000000000000000001367521742200155215ustar00rootroot00000000000000nsync-1.24.0/platform/ppc64/cputype.h000066400000000000000000000013371367521742200173670ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_PPC64_CPUTYPE_H_ #define NSYNC_PLATFORM_PPC64_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_PPC64_CPUTYPE_H_*/ nsync-1.24.0/platform/ppc64/src/000077500000000000000000000000001367521742200163105ustar00rootroot00000000000000nsync-1.24.0/platform/ppc64/src/nsync_atm_ppc64.s000066400000000000000000000055621367521742200215130ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for ppc64 implementation of atomic operations. */ .text /* Atomically: int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some-non-zero-value); } else { return (0); } } */ .align 3 .global nsync_atm_cas_ .type nsync_atm_cas_, %function nsync_atm_cas_: 1: lwarx %r6,0,%r3 cmpw %r4,%r6 bne 2f stwcx. %r5,0,%r3 bne 1b li %r3,1 blr 2: li %r3,0 blr /* Like nsync_atm_cas_, but with acquire barrier semantics. */ .align 3 .global nsync_atm_cas_acq_ .type nsync_atm_cas_acq_, %function nsync_atm_cas_acq_: 1: lwarx %r6,0,%r3 cmpw %r4,%r6 bne 2f stwcx. %r5,0,%r3 bne 1b li %r3,1 lwsync blr 2: li %r3,0 blr /* Like nsync_atm_cas_, but with release barrier semantics. */ .align 3 .global nsync_atm_cas_rel_ .type nsync_atm_cas_rel_, %function nsync_atm_cas_rel_: lwsync 1: lwarx %r6,0,%r3 cmpw %r4,%r6 bne 2f stwcx. %r5,0,%r3 bne 1b li %r3,1 blr 2: li %r3,0 blr /* Like nsync_atm_cas_, but with both acquire and release barrier semantics. */ .align 3 .global nsync_atm_cas_relacq_ .type nsync_atm_cas_relacq_, %function nsync_atm_cas_relacq_: lwsync 1: lwarx %r6,0,%r3 cmpw %r4,%r6 bne 2f stwcx. %r5,0,%r3 bne 1b li %r3,1 lwsync blr 2: li %r3,0 blr /* Atomically: uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 3 .global nsync_atm_load_ .type nsync_atm_load_, %function nsync_atm_load_: lwz %r3,0(%r3) blr /* Like nsync_atm_load_, but with acquire barrier semantics. */ .align 3 .global nsync_atm_load_acq_ .type nsync_atm_load_acq_, %function nsync_atm_load_acq_: lwz %r3,0(%r3) lwsync blr /* Atomically: void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 3 .global nsync_atm_store_ .type nsync_atm_store_, %function nsync_atm_store_: stw %r4,0(%r3) blr /* Like nsync_atm_store_, but with release barrier semantics. */ .align 3 .global nsync_atm_store_rel_ .type nsync_atm_store_rel_, %function nsync_atm_store_rel_: lwsync stw %r4,0(%r3) blr nsync-1.24.0/platform/riscv/000077500000000000000000000000001367521742200157135ustar00rootroot00000000000000nsync-1.24.0/platform/riscv/cputype.h000066400000000000000000000013371367521742200175610ustar00rootroot00000000000000/* Copyright 2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_RISCV_CPUTYPE_H_ #define NSYNC_PLATFORM_RISCV_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_RISCV_CPUTYPE_H_*/ nsync-1.24.0/platform/riscv/src/000077500000000000000000000000001367521742200165025ustar00rootroot00000000000000nsync-1.24.0/platform/riscv/src/nsync_atm_riscv.s000066400000000000000000000046551367521742200221010ustar00rootroot00000000000000/* Copyright 2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for riscv implementation of atomic operations. */ .text /* Atomically: int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some-non-zero-value); } else { return (0); } } */ .align 1 .globl nsync_atm_cas_ nsync_atm_cas_: 1: lr.w a5,0(a0) bne a5,a1,2f sc.w a4,a2,0(a0) bnez a4,1b li a0, 1 ret 2: li a0, 0 ret /* Like nsync_atm_cas_, but with acquire barrier semantics. */ .align 1 .globl nsync_atm_cas_acq_ nsync_atm_cas_acq_: 1: lr.w a5,0(a0) bne a5,a1,2f sc.w.aq a4,a2,0(a0) bnez a4,1b li a0, 1 ret 2: li a0, 0 ret /* Like nsync_atm_cas_, but with release barrier semantics. */ .align 1 .globl nsync_atm_cas_rel_ nsync_atm_cas_rel_: 1: lr.w.rl a5,0(a0) bne a5,a1,2f sc.w a4,a2,0(a0) bnez a4,1b li a0, 1 ret 2: li a0, 0 ret /* Like nsync_atm_cas_, but with both acquire and release barrier semantics. */ .align 1 .globl nsync_atm_cas_relacq_ nsync_atm_cas_relacq_: 1: lr.w.rl a5,0(a0) bne a5,a1,2f sc.w.aq a4,a2,0(a0) bnez a4,1b li a0, 1 ret 2: li a0, 0 ret /* Atomically: uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 1 .globl nsync_atm_load_ nsync_atm_load_: lw a0,0(a0) ret /* Like nsync_atm_load_, but with acquire barrier semantics. */ .align 1 .globl nsync_atm_load_acq_ nsync_atm_load_acq_: lr.w.aq a0,0(a0) ret /* Atomically: void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 1 .globl nsync_atm_store_ nsync_atm_store_: amoswap.w zero,a1,0(a0) ret /* Like nsync_atm_store_, but with release barrier semantics. */ .align 1 .globl nsync_atm_store_rel_ nsync_atm_store_rel_: amoswap.w.rl zero,a1,0(a0) ret nsync-1.24.0/platform/s390x/000077500000000000000000000000001367521742200154535ustar00rootroot00000000000000nsync-1.24.0/platform/s390x/cputype.h000066400000000000000000000013371367521742200173210ustar00rootroot00000000000000/* Copyright 2017 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_S390X_CPUTYPE_H_ #define NSYNC_PLATFORM_S390X_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 1 #endif /*NSYNC_PLATFORM_S390X_CPUTYPE_H_*/ nsync-1.24.0/platform/s390x/src/000077500000000000000000000000001367521742200162425ustar00rootroot00000000000000nsync-1.24.0/platform/s390x/src/nsync_atm_s390x.s000066400000000000000000000047271367521742200214010ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for s390x implementation of atomic operations. */ .text /* Atomically, with acquire and release barrier semantics, int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some-non-zero-value); } else { return (0); } } */ .align 8 .globl nsync_atm_cas_ .globl nsync_atm_cas_acq_ .globl nsync_atm_cas_rel_ .globl nsync_atm_cas_relacq_ nsync_atm_cas_: nsync_atm_cas_acq_: nsync_atm_cas_rel_: nsync_atm_cas_relacq_: /* The compare-and-swap instruction indicates success as an inverted bit in the processor status word. We need to extract it and invert it. The sequence is not obvious due to the oddities of the available shift and xor instructions. */ cs %r3,%r4,0(%r2) /* CAS old=%3, new=%r4, loc=%r2 ; inverted result->bottom bit of condition code */ ipm %r2 /* move condition code to 2**28 bit of %r2, which is return value */ srl %r2,28 /* move bit to 2**0 bit of %r2 */ ahi %r2,1 /* flip 2**0 bit, so bit has expected sense */ sll %r2,31 /* move bit to to 2**31 */ srl %r2,31 /* move it back to 2**0 bit, zero exteding */ llgfr %r2,%r2 /* zero top 32 bits of %r2 */ br %r14 /* return address is %r14 */ /* Atomically, with acquire barrier semantics, uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 8 .globl nsync_atm_load_ .globl nsync_atm_load_acq_ nsync_atm_load_: nsync_atm_load_acq_: l %r2,0(%r2) llgfr %r2,%r2 br %r14 /* Atomically, with release barrier semantics, void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 8 .globl nsync_atm_store_ .globl nsync_atm_store_rel_ nsync_atm_store_: nsync_atm_store_rel_: st %r3,0(%r2) br %r14 nsync-1.24.0/platform/shark/000077500000000000000000000000001367521742200156755ustar00rootroot00000000000000nsync-1.24.0/platform/shark/cputype.h000066400000000000000000000013371367521742200175430ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_SHARK_CPUTYPE_H_ #define NSYNC_PLATFORM_SHARK_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 1 #endif /*NSYNC_PLATFORM_SHARK_CPUTYPE_H_*/ nsync-1.24.0/platform/sparc64/000077500000000000000000000000001367521742200160475ustar00rootroot00000000000000nsync-1.24.0/platform/sparc64/cputype.h000066400000000000000000000013451367521742200177140ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_SPARC64_CPUTYPE_H_ #define NSYNC_PLATFORM_SPARC64_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 0 #endif /*NSYNC_PLATFORM_SPARC64_CPUTYPE_H_*/ nsync-1.24.0/platform/sparc64/src/000077500000000000000000000000001367521742200166365ustar00rootroot00000000000000nsync-1.24.0/platform/sparc64/src/nsync_atm_sparc64.s000066400000000000000000000050761367521742200223670ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for sparc64 implementation of atomic operations. */ .section ".text" /* Atomically: int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some - non - zero - value); } else { return (0); } } */ .align 4 .global nsync_atm_cas_ .type nsync_atm_cas_, #function nsync_atm_cas_: cas [%o0], %o1, %o2 xor %o2, %o1, %o1 cmp %g0, %o1 retl subx %g0, -1, %o0 /* Like nsync_atm_cas_, but with acquire barrier semantics. */ .align 4 .global nsync_atm_cas_acq_ .type nsync_atm_cas_acq_, #function nsync_atm_cas_acq_: cas [%o0], %o1, %o2 xor %o2, %o1, %o1 cmp %g0, %o1 retl subx %g0, -1, %o0 /* Like nsync_atm_cas_, but with release barrier semantics. */ .align 4 .global nsync_atm_cas_rel_ .type nsync_atm_cas_rel_, #function nsync_atm_cas_rel_: membar 15 cas [%o0], %o1, %o2 xor %o2, %o1, %o1 cmp %g0, %o1 retl subx %g0, -1, %o0 /* Like nsync_atm_cas_, but with both acquire and release barrier semantics. */ .align 4 .global nsync_atm_cas_relacq_ .type nsync_atm_cas_relacq_, #function nsync_atm_cas_relacq_: membar 15 cas [%o0], %o1, %o2 xor %o2, %o1, %o1 cmp %g0, %o1 retl subx %g0, -1, %o0 /* Atomically: uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 4 .global nsync_atm_load_ .type nsync_atm_load_, #function nsync_atm_load_: retl lduw [%o0], %o0 /* Like nsync_atm_load_, but with acquire barrier semantics. */ .align 4 .global nsync_atm_load_acq_ .type nsync_atm_load_acq_, #function nsync_atm_load_acq_: lduw [%o0], %o0 membar 15 retl nop /* Atomically: void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 4 .global nsync_atm_store_ .type nsync_atm_store_, #function nsync_atm_store_: retl st %o1, [%o0] /* Like nsync_atm_store_, but with release barrier semantics. */ .align 4 .global nsync_atm_store_rel_ .type nsync_atm_store_rel_, #function nsync_atm_store_rel_: membar 15 retl st %o1, [%o0] nsync-1.24.0/platform/tcc/000077500000000000000000000000001367521742200153365ustar00rootroot00000000000000nsync-1.24.0/platform/tcc/compiler.h000066400000000000000000000014521367521742200173230ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_TCC_COMPILER_H_ #define NSYNC_PLATFORM_TCC_COMPILER_H_ #define INLINE __inline #define UNUSED __attribute__((unused)) #define THREAD_LOCAL #define HAVE_THREAD_LOCAL 0 #endif /*NSYNC_PLATFORM_TCC_COMPILER_H_*/ nsync-1.24.0/platform/tendracc/000077500000000000000000000000001367521742200163505ustar00rootroot00000000000000nsync-1.24.0/platform/tendracc/compiler.h000066400000000000000000000014401367521742200203320ustar00rootroot00000000000000/* Copyright 2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_TENDRACC_COMPILER_H_ #define NSYNC_PLATFORM_TENDRACC_COMPILER_H_ #define INLINE __inline #define UNUSED #define THREAD_LOCAL #define HAVE_THREAD_LOCAL 0 #endif /*NSYNC_PLATFORM_TENDRACC_COMPILER_H_*/ nsync-1.24.0/platform/vax/000077500000000000000000000000001367521742200153635ustar00rootroot00000000000000nsync-1.24.0/platform/vax/cputype.h000066400000000000000000000013311367521742200172230ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_VAX_CPUTYPE_H_ #define NSYNC_PLATFORM_VAX_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 1 #endif /*NSYNC_PLATFORM_VAX_CPUTYPE_H_*/ nsync-1.24.0/platform/vax/src/000077500000000000000000000000001367521742200161525ustar00rootroot00000000000000nsync-1.24.0/platform/vax/src/nsync_atm_vax.s000066400000000000000000000047611367521742200212170ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for vax implementation of atomic operations. */ /* The vax has no compare-and-swap operation. Instead, we implement interlocked updates to words by protecting such updates with a spin lock. This works because on words where nsync uses atomic operations, no non-atomic operations are used. The spin lock is implemented by mapping from the word location to a bit in the following array, and using test-and-set (bbssi) on that bit. bbcci is used to clear the bit to guarantee isolation between the bits. */ .data .lcomm locks,128 .text /* Atomically, with acquire and release barrier semantics, int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some-non-zero-value); } else { return (0); } } */ .align 1 .globl nsync_atm_cas_ .globl nsync_atm_cas_acq_ .globl nsync_atm_cas_rel_ .globl nsync_atm_cas_relacq_ nsync_atm_cas_: nsync_atm_cas_acq_: nsync_atm_cas_rel_: nsync_atm_cas_relacq_: .word 0x0 1: movl 4(%ap),%r0 ashl $-2,%r0,%r1 bicl2 $-1024,%r1 bbssi %r1, locks, 4f movl (%r0),%r2 clrl %r3 cmpl 8(%ap),%r2 bneq 2f movl 12(%ap),(%r0) movl $1, %r3 2: bbcci %r1, locks, 3f 3: movl %r3,%r0 ret 4: calls $0, nsync_yield_ jmp 1b /* Atomically, with acquire barrier semantics, uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .align 1 .globl nsync_atm_load_ .globl nsync_atm_load_acq_ nsync_atm_load_: nsync_atm_load_acq_: .word 0x0 movl *4(%ap),%r0 ret /* Atomically, with release barrier semantics, void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .align 1 .globl nsync_atm_store_ .globl nsync_atm_store_rel_ nsync_atm_store_: nsync_atm_store_rel_: .word 0x0 1: movl 4(%ap),%r0 ashl $-2,%r0,%r1 bicl2 $-1024,%r1 bbssi %r1, locks, 3f movl 8(%ap),(%r0) bbcci %r1, locks, 2f 2: ret 3: calls $0, nsync_yield_ jmp 1b nsync-1.24.0/platform/win32/000077500000000000000000000000001367521742200155275ustar00rootroot00000000000000nsync-1.24.0/platform/win32/atomic.h000066400000000000000000000104671367521742200171640ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_WIN32_ATOMIC_H_ #define NSYNC_PLATFORM_WIN32_ATOMIC_H_ /* Atomic operations on nsync_atomic_uint32_ quantities CAS, load, and store. Normally, these are used only on nsync_atomic_uint32_ values, but on Linux they may be invoked on int values, because futexes operate on int values. A compile-time check in the futex code ensures that both int and nsync_atomic_uint32_ are 32 bits. Memory barriers: Operations with the suffixes _ACQ and _RELACQ ensure that the operation appears to complete before other memory operations subsequently performed by the same thread, as seen by other threads. (In the case of ATM_CAS_ACQ, this applies only if the operation returns a non-zero value.) Operations with the suffixes _REL and _RELACQ ensure that the operation appears to complete after other memory operations previously performed by the same thread, as seen by other threads. (In the case of ATM_CAS_REL, this applies only if the operation returns a non-zero value.) // Atomically, // int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { // if (*p == old_value) { // *p = new_value; // return (some-non-zero-value); // } else { // return (0); // } // } // *_ACQ, *_REL, *_RELACQ variants are available, // with the barrier semantics described above. int ATM_CAS (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value); // Atomically, // uint32_t ATM_LOAD (nsync_atomic_uint32_ *p) { return (*p); } // A *_ACQ variant is available, // with the barrier semantics described above. uint32_t ATM_LOAD (nsync_atomic_uint32_ *p); // Atomically, // void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } // A *_REL variant is available, // with the barrier semantics described above. void ATM_STORE (nsync_atomic_uint32_ *p, uint32_t value); */ #include "compiler.h" #include "nsync_atomic.h" #include #include NSYNC_CPP_START_ #define ATM_MB_() MemoryBarrier () #if ATM_LD_IS_ACQ_ST_IS_REL_ #define ATM_CB_() _ReadWriteBarrier () /* compiler barrier */ #define ATM_LD_ACQ_ ATM_CB_ #define ATM_ST_REL_ ATM_CB_ #else #define ATM_LD_ACQ_ ATM_MB_ #define ATM_ST_REL_ ATM_MB_ #endif static INLINE int atm_cas_nomb_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { /* InterlockedCompareExchangeNoFence unavailable before Windows 8 */ return (InterlockedCompareExchange ( (LONG volatile *) NSYNC_ATOMIC_UINT32_PTR_ (p), n, o) == o); } static INLINE int atm_cas_barrier_u32_ (nsync_atomic_uint32_ *p, uint32_t o, uint32_t n) { /* InterlockedCompareExchangeAcquire unavailable before Windows Vista */ return (InterlockedCompareExchange ( (LONG volatile *) NSYNC_ATOMIC_UINT32_PTR_ (p), n, o) == o); } #define ATM_CAS(p,o,n) (atm_cas_nomb_u32_ ((p),(o),(n))) #define ATM_CAS_ACQ(p,o,n) (atm_cas_barrier_u32_ ((p),(o),(n))) #define ATM_CAS_REL(p,o,n) (atm_cas_barrier_u32_ ((p),(o),(n))) #define ATM_CAS_RELACQ(p,o,n) (atm_cas_barrier_u32_ ((p),(o),(n))) /*----*/ static INLINE uint32_t atm_load_acq_u32_ (nsync_atomic_uint32_ *p) { uint32_t result = NSYNC_ATOMIC_UINT32_LOAD_ ((volatile nsync_atomic_uint32_ *)p); ATM_LD_ACQ_ (); return (result); } #define ATM_LOAD(p) (NSYNC_ATOMIC_UINT32_LOAD_ ((volatile nsync_atomic_uint32_ *)(p))) #define ATM_LOAD_ACQ(p) (atm_load_acq_u32_ (p)) /*----*/ #define ATM_STORE_X_(p,v,b,a) do { \ b; \ NSYNC_ATOMIC_UINT32_STORE_ ((volatile nsync_atomic_uint32_ *)(p), (uint32_t) (v)); \ a; \ } while (0) #define ATM_STORE(p,v) ATM_STORE_X_ ((p), (v), ; , ; ) #define ATM_STORE_REL(p,v) ATM_STORE_X_ ((p), (v), ATM_ST_REL_ (), ; ) NSYNC_CPP_END_ #endif /*NSYNC_PLATFORM_WIN32_ATOMIC_H_*/ nsync-1.24.0/platform/win32/platform.h000066400000000000000000000075671367521742200175430ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_WIN32_PLATFORM_H_ #define NSYNC_PLATFORM_WIN32_PLATFORM_H_ #include #include #include #include #include #include #include #include #include "compiler.h" #include "nsync_cpp.h" extern int write (int, const char *, size_t); /* Avoid deprecation/safety warning for tmpfile() */ #define tmpfile nsync_tmpfile_wrapper static inline FILE *nsync_tmpfile_wrapper (void) { FILE *fp; if (tmpfile_s (&fp) != 0) { fp = NULL; } return (fp); } NSYNC_C_START_ /* Can't use TlsAlloc() because we use pthread_key_create's destructor argument, so we implement it anew. */ #define pthread_key_t nsync_pthread_key_t typedef int nsync_pthread_key_t; int nsync_pthread_key_create (nsync_pthread_key_t *pkey, void (*dest) (void *)); int nsync_pthread_key_delete (nsync_pthread_key_t key); void *nsync_pthread_getspecific (nsync_pthread_key_t key); int nsync_pthread_setspecific (nsync_pthread_key_t key, void *value); #define pthread_key_create nsync_pthread_key_create #define pthread_key_delete nsync_pthread_key_delete #define pthread_getspecific nsync_pthread_getspecific #define pthread_setspecific nsync_pthread_setspecific NSYNC_C_END_ NSYNC_CPP_START_ #define CLOCK_REALTIME 0 #define TIMER_ABSTIME 1 #define clockid_t nsync_clockid_t typedef int nsync_clockid_t; int nsync_clock_gettime (clockid_t clk_id, struct timespec *tp); #define clock_gettime nsync_clock_gettime int nsync_nanosleep(const struct timespec *delay, struct timespec *remaining); #define nanosleep nsync_nanosleep #define pthread_mutex_t CRITICAL_SECTION #define pthread_mutex_lock EnterCriticalSection #define pthread_mutex_unlock LeaveCriticalSection #define pthread_mutex_init(mu,attr) InitializeCriticalSection (mu) #define pthread_mutex_destroy DeleteCriticalSection #define pthread_cond_t CONDITION_VARIABLE #define pthread_cond_broadcast WakeAllConditionVariable #define pthread_cond_signal WakeConditionVariable #define pthread_cond_wait(cv, mu) SleepConditionVariableCS ((cv), (mu), INFINITE) #define pthread_cond_timedwait nsync_pthread_cond_timedwait #define pthread_cond_init(cv, attr) InitializeConditionVariable (cv) #define pthread_cond_destroy(cv) /*no-op*/ int nsync_pthread_cond_timedwait (pthread_cond_t *cv, pthread_mutex_t *mu, const struct timespec *abstimeout); typedef struct { SRWLOCK srw; int w; } nsync_pthread_rwlock_t; #define pthread_rwlock_t nsync_pthread_rwlock_t #define pthread_rwlock_wrlock(rw) do { AcquireSRWLockExclusive (&(rw)->srw); (rw)->w = 1; } while (0) #define pthread_rwlock_rdlock(rw) AcquireSRWLockShared (&(rw)->srw) #define pthread_rwlock_unlock(rw) do { if ((rw)->w) { (rw)->w = 0; ReleaseSRWLockExclusive (&(rw)->srw); } else { ReleaseSRWLockShared (&(rw)->srw); } } while (0) #define pthread_rwlock_init(rw,attr) do { InitializeSRWLock (&(rw)->srw); (rw)->w = 0; } while (0) #define pthread_rwlock_destroy(rw) /*no-op*/ #define pthread_once_t INIT_ONCE #define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT extern BOOL CALLBACK nsync_init_callback_ (pthread_once_t *o, void *v, void **c); #define pthread_once(o, f) do { \ void (*ff) = (f); \ InitOnceExecuteOnce ((o), &nsync_init_callback_, &ff, NULL); \ } while (0) #define sched_yield() Sleep(0) NSYNC_CPP_END_ #endif /*NSYNC_PLATFORM_WIN32_PLATFORM_H_*/ nsync-1.24.0/platform/win32/platform_c++11_os.h000066400000000000000000000041501367521742200210170ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_WIN32_PLATFORM_CPP_OS_H_ #define NSYNC_PLATFORM_WIN32_PLATFORM_CPP_OS_H_ /* Windows doesn't implement clock_gettime(). */ #include #define clock_gettime nsync_clock_gettime #define CLOCK_REALTIME 0 #define TIMER_ABSTIME 1 NSYNC_CPP_START_ typedef int clockid_t; int clock_gettime (clockid_t clk_id, struct timespec *tp); NSYNC_CPP_END_ /* Avoid deprecation/safety warning for tmpfile(). This is used for the C++11 build. The copy in win32/platform.h is used for the win32 "native" build. */ #define tmpfile nsync_tmpfile_wrapper static inline FILE *nsync_tmpfile_wrapper (void) { FILE *fp; if (tmpfile_s (&fp) != 0) { fp = NULL; } return (fp); } /* Windows lacks pthread_key_t. */ #include "Windows.h" #define sched_yield() Sleep(0) NSYNC_C_START_ /* Can't use TlsAlloc() because we use pthread_key_create's destructor argument, so we implement it anew. */ #define pthread_key_t nsync_pthread_key_t typedef int nsync_pthread_key_t; int nsync_pthread_key_create (nsync_pthread_key_t *pkey, void (*dest) (void *)); int nsync_pthread_key_delete (nsync_pthread_key_t key); void *nsync_pthread_getspecific (nsync_pthread_key_t key); int nsync_pthread_setspecific (nsync_pthread_key_t key, void *value); #define pthread_key_create nsync_pthread_key_create #define pthread_key_delete nsync_pthread_key_delete #define pthread_getspecific nsync_pthread_getspecific #define pthread_setspecific nsync_pthread_setspecific NSYNC_C_END_ #endif /*NSYNC_PLATFORM_WIN32_PLATFORM_CPP_OS_H_*/ nsync-1.24.0/platform/win32/src/000077500000000000000000000000001367521742200163165ustar00rootroot00000000000000nsync-1.24.0/platform/win32/src/clock_gettime.c000066400000000000000000000014571367521742200213020ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ int nsync_clock_gettime (clockid_t clk_id UNUSED, struct timespec *tp) { struct timeb tb; ftime (&tb); tp->tv_sec = tb.time; tp->tv_nsec = tb.millitm * 1000 * 1000; return (0); } NSYNC_CPP_END_ nsync-1.24.0/platform/win32/src/init_callback_win32.c000066400000000000000000000015051367521742200222640ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" NSYNC_CPP_START_ typedef void (*init_once_fn_) (void); BOOL CALLBACK nsync_init_callback_ (pthread_once_t *o, void *v, void **c) { init_once_fn_ *f = (init_once_fn_ *) v; (**f) (); return (TRUE); } NSYNC_CPP_END_ nsync-1.24.0/platform/win32/src/nanosleep.c000066400000000000000000000016761367521742200204600ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ int nsync_nanosleep (const struct timespec *request, struct timespec *remain) { time_t x = request->tv_sec; while (x > 1000) { x -= 1000; Sleep (1000 * 1000); } Sleep ((unsigned) (x * 1000 + (request->tv_nsec + 999999) / (1000 * 1000))); if (remain != NULL) { memset (remain, 0, sizeof (*remain)); } return (0); } NSYNC_CPP_END_ nsync-1.24.0/platform/win32/src/nsync_semaphore_win32.c000066400000000000000000000045161367521742200227070ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include #include "nsync_cpp.h" #include "nsync_time.h" #include "sem.h" NSYNC_CPP_START_ /* Initialize *s; the initial value is 0. */ void nsync_mu_semaphore_init (nsync_semaphore *s) { HANDLE *h = (HANDLE *) s; *h = CreateSemaphore(NULL, 0, 1, NULL); if (*h == NULL) { abort (); } } /* Wait until the count of *s exceeds 0, and decrement it. */ void nsync_mu_semaphore_p (nsync_semaphore *s) { HANDLE *h = (HANDLE *) s; WaitForSingleObject(*h, INFINITE); } /* Wait until one of: the count of *s is non-zero, in which case decrement *s and return 0; or abs_deadline expires, in which case return ETIMEDOUT. */ int nsync_mu_semaphore_p_with_deadline (nsync_semaphore *s, nsync_time abs_deadline) { HANDLE *h = (HANDLE *) s; int result; if (nsync_time_cmp (abs_deadline, nsync_time_no_deadline) == 0) { result = WaitForSingleObject(*h, INFINITE); } else { nsync_time now; now = nsync_time_now (); do { if (nsync_time_cmp (abs_deadline, now) <= 0) { result = WaitForSingleObject (*h, 0); } else { nsync_time delay; delay = nsync_time_sub (abs_deadline, now); if (NSYNC_TIME_SEC (delay) > 1000*1000) { result = WaitForSingleObject (*h, 1000*1000); } else { result = WaitForSingleObject (*h, (unsigned) (NSYNC_TIME_SEC (delay) * 1000 + (NSYNC_TIME_NSEC (delay) + 999999) / (1000 * 1000))); } } if (result == WAIT_TIMEOUT) { now = nsync_time_now (); } } while (result == WAIT_TIMEOUT && /* Windows generates early wakeups. */ nsync_time_cmp (abs_deadline, now) > 0); } return (result == WAIT_TIMEOUT? ETIMEDOUT : 0); } /* Ensure that the count of *s is at least 1. */ void nsync_mu_semaphore_v (nsync_semaphore *s) { HANDLE *h = (HANDLE *) s; ReleaseSemaphore(*h, 1, NULL); } NSYNC_CPP_END_ nsync-1.24.0/platform/win32/src/per_thread_waiter.c000066400000000000000000000024641367521742200221600ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ static pthread_key_t waiter_key; static nsync_atomic_uint32_ pt_once; static void do_once (nsync_atomic_uint32_ *ponce, void (*dest) (void *)) { uint32_t o = ATM_LOAD_ACQ (ponce); if (o != 2) { while (o == 0 && !ATM_CAS_ACQ (ponce, 0, 1)) { o = ATM_LOAD (ponce); } if (o == 0) { pthread_key_create (&waiter_key, dest); ATM_STORE_REL (ponce, 2); } while (ATM_LOAD_ACQ (ponce) != 2) { sched_yield (); } } } void *nsync_per_thread_waiter_ (void (*dest) (void *)) { do_once (&pt_once, dest); return (pthread_getspecific (waiter_key)); } void nsync_set_per_thread_waiter_ (void *v, void (*dest) (void *)) { do_once (&pt_once, dest); pthread_setspecific (waiter_key, v); } NSYNC_CPP_END_ nsync-1.24.0/platform/win32/src/pthread_cond_timedwait_win32.c000066400000000000000000000040771367521742200242150ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" NSYNC_CPP_START_ int nsync_pthread_cond_timedwait (pthread_cond_t *cv, pthread_mutex_t *mu, const struct timespec *abs_deadline) { int result; if (abs_deadline == NULL) { result = SleepConditionVariableCS (cv, mu, INFINITE); } else { int again; do { struct timespec now; again = 0; clock_gettime (CLOCK_REALTIME, &now); if (abs_deadline->tv_sec < now.tv_sec || (abs_deadline->tv_sec == now.tv_sec && abs_deadline->tv_nsec <= now.tv_nsec)) { result = SleepConditionVariableCS (cv, mu, 0); } else { struct timespec delay; delay = *abs_deadline; delay.tv_sec -= now.tv_sec; if (delay.tv_nsec < now.tv_nsec) { delay.tv_nsec += 1000 * 1000 * 1000; delay.tv_sec--; } delay.tv_nsec -= now.tv_nsec; if (delay.tv_sec > 1000*1000) { result = SleepConditionVariableCS (cv, mu, 1000*1000); again = (result == ERROR_TIMEOUT); } else { result = SleepConditionVariableCS (cv, mu, (unsigned) (delay.tv_sec * 1000 + (delay.tv_nsec + 999999) / (1000 * 1000))); if (result == ERROR_TIMEOUT) { /* Windows often generates early wakeups. */ clock_gettime (CLOCK_REALTIME, &now); again = (abs_deadline->tv_sec > now.tv_sec || (abs_deadline->tv_sec == now.tv_sec && abs_deadline->tv_nsec > now.tv_nsec)); } } } } while (again); } return (result == ERROR_TIMEOUT? ETIMEDOUT : 0); } NSYNC_CPP_END_ nsync-1.24.0/platform/win32/src/pthread_key_win32.cc000066400000000000000000000101311367521742200221420ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" // Struct representing an element of the "dest" array, whose elements // indicate the destructor asscoaied with the corresponding key. namespace { struct KeyDestructor { bool allocated; // Whether this key is allocated. pthread_key_t key; // Last used version of key. void (*dest) (void *); // Destructor for the key, or nullptr. }; } // anonymous namespace static SRWLOCK mu = SRWLOCK_INIT; // protects dest. static const int kMaxKeyShift = 7; static const int kMaxKeys = 1 << kMaxKeyShift; static const int kKeyMask = kMaxKeys - 1; static KeyDestructor dest[kMaxKeys]; // Destructors for keys. // Element per key per thread. namespace { struct KeyValue { pthread_key_t key; // last key stored void *value; }; } // anonymous namespace // Each thread has a class instance that represents an array of pointers // to client-specified thread-specific data. // The class destructor calls the key destructors when the accociated // thread exits. namespace { class PerThreadData { public: PerThreadData() { } ~PerThreadData(); void *value(pthread_key_t key) { void *result = 0; int i = key & kKeyMask; if (this->array_[i].key == key) { result = this->array_[i].value; } return (result); } void set_value(pthread_key_t key, void *value) { int i = key & kKeyMask; this->array_[i].key = key; this->array_[i].value = value; } private: KeyValue array_[kMaxKeys]; }; PerThreadData::~PerThreadData() { bool again = true; // Try a few times to clear the thread's array. for (int attempt = 0; attempt != 4 && again; attempt++) { again = false; // Take a snapshot of the destructor state. AcquireSRWLockExclusive (&mu); KeyDestructor dest_copy[kMaxKeys]; memcpy (dest_copy, dest, sizeof (dest_copy)); ReleaseSRWLockExclusive(&mu); // Iterate over the values, calling destructors // when both destructor and value are non-nil. for (int i = 1; i != kMaxKeys; i++) { if (dest_copy[i].allocated) { void (*destructor) (void *) = dest_copy[i].dest; void *value = this->array_[i].value; this->array_[i].value = nullptr; if (dest_copy[i].key == this->array_[i].key && destructor != nullptr && value != nullptr) { again = true; // in case destructors set values. (*destructor) (value); } } } } } } // anonymous namespace static __declspec(thread) class PerThreadData per_thread_data; NSYNC_C_START_ int nsync_pthread_key_create (pthread_key_t *pkey, void (*destructor) (void *)) { int result = EAGAIN; int i; AcquireSRWLockExclusive (&mu); // Search for an unused slot. Slot 1 is never used. for (i = 1; i != kMaxKeys && dest[i].allocated; i++) { } if (i != kMaxKeys) { // found one dest[i].allocated = true; dest[i].dest = destructor; dest[i].key += kMaxKeys; // High bits are version number. dest[i].key |= i; // Low bits are slot number. *pkey = dest[i].key; result = 0; } ReleaseSRWLockExclusive(&mu); return (result); } int nsync_pthread_key_delete (pthread_key_t key) { int result = EINVAL; int i = key & kKeyMask; AcquireSRWLockExclusive (&mu); if (key > 0 && dest[i].allocated) { dest[i].allocated = false; dest[i].dest = nullptr; result = 0; } ReleaseSRWLockExclusive(&mu); return (result); } void *nsync_pthread_getspecific (pthread_key_t key) { return (per_thread_data.value (key)); } int nsync_pthread_setspecific (pthread_key_t key, void *value) { int result = EINVAL; if (key > 0) { per_thread_data.set_value (key, value); result = 0; } return (result); } NSYNC_C_END_ nsync-1.24.0/platform/win32/src/start_thread.c000066400000000000000000000021131367521742200211430ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "headers.h" NSYNC_CPP_START_ struct nsync_thd_args { void (*f) (void *); void *arg; }; static DWORD WINAPI body (void *v) { struct nsync_thd_args *args = (struct nsync_thd_args *) v; (*args->f) (args->arg); free (args); return (0); } void nsync_start_thread_ (void (*f) (void *), void *arg) { struct nsync_thd_args *args = (struct nsync_thd_args *) malloc (sizeof (*args)); HANDLE t; args->f = f; args->arg = arg; t = CreateThread (NULL, 0, &body, args, 0, NULL); CloseHandle (t); } NSYNC_CPP_END_ nsync-1.24.0/platform/x86_32/000077500000000000000000000000001367521742200155165ustar00rootroot00000000000000nsync-1.24.0/platform/x86_32/cputype.h000066400000000000000000000013421367521742200173600ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_X86_32_CPUTYPE_H_ #define NSYNC_PLATFORM_X86_32_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 1 #endif /*NSYNC_PLATFORM_X86_32_CPUTYPE_H_*/ nsync-1.24.0/platform/x86_32/src/000077500000000000000000000000001367521742200163055ustar00rootroot00000000000000nsync-1.24.0/platform/x86_32/src/nsync_atm_x86_32.s000066400000000000000000000035741367521742200215060ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for x86_32 implementation of atomic operations. */ /* Atomically, with acquire and release barrier semantics, int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some-non-zero-value); } else { return (0); } } */ .text .globl nsync_atm_cas_ .globl nsync_atm_cas_acq_ .globl nsync_atm_cas_rel_ .globl nsync_atm_cas_relacq_ .type nsync_atm_cas_, @function nsync_atm_cas_: nsync_atm_cas_acq_: nsync_atm_cas_rel_: nsync_atm_cas_relacq_: movl %esp, %eax movl 4(%eax), %edx movl 12(%eax), %ecx movl 8(%eax), %eax lock cmpxchgl %ecx, (%edx) movl $0, %eax sete %al ret /* Atomically, with acquire barrier semantics, uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .globl nsync_atm_load_ .globl nsync_atm_load_acq_ .type nsync_atm_load_, @function nsync_atm_load_: nsync_atm_load_acq_: movl %esp, %eax movl 4(%eax), %eax movl (%eax), %eax ret /* Atomically, with release barrier semantics, void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .globl nsync_atm_store_ .globl nsync_atm_store_rel_ .type nsync_atm_store_, @function nsync_atm_store_: nsync_atm_store_rel_: movl %esp, %eax movl 8(%eax), %edx movl 4(%eax), %eax movl %edx, (%eax) ret nsync-1.24.0/platform/x86_64/000077500000000000000000000000001367521742200155235ustar00rootroot00000000000000nsync-1.24.0/platform/x86_64/cputype.h000066400000000000000000000013421367521742200173650ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PLATFORM_X86_64_CPUTYPE_H_ #define NSYNC_PLATFORM_X86_64_CPUTYPE_H_ #define ATM_LD_IS_ACQ_ST_IS_REL_ 1 #endif /*NSYNC_PLATFORM_X86_64_CPUTYPE_H_*/ nsync-1.24.0/platform/x86_64/src/000077500000000000000000000000001367521742200163125ustar00rootroot00000000000000nsync-1.24.0/platform/x86_64/src/nsync_atm_x86_64.s000066400000000000000000000034221367521742200215100ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Helper routines for x86_64 implementation of atomic operations. */ /* Atomically, with acquire and release barrier semantics, int nsync_atm_cas_ (nsync_atomic_uint32_ *p, uint32_t old_value, uint32_t new_value) { if (*p == old_value) { *p = new_value; return (some-non-zero-value); } else { return (0); } } */ .text .globl nsync_atm_cas_ .globl nsync_atm_cas_acq_ .globl nsync_atm_cas_rel_ .globl nsync_atm_cas_relacq_ .type nsync_atm_cas_, @function nsync_atm_cas_: nsync_atm_cas_acq_: nsync_atm_cas_rel_: nsync_atm_cas_relacq_: movl %esi, %eax lock cmpxchgl %edx, (%rdi) movl $0, %eax sete %al ret /* Atomically, with acquire barrier semantics, uint32_t nsync_atm_load_ (nsync_atomic_uint32_ *p) { return (*p); } */ .globl nsync_atm_load_ .globl nsync_atm_load_acq_ .type nsync_atm_load_, @function nsync_atm_load_: nsync_atm_load_acq_: movl (%rdi), %eax ret /* Atomically, with release barrier semantics, void nsync_atm_store_ (nsync_atomic_uint32_ *p, uint32_t value) { *p = value; } */ .globl nsync_atm_store_ .globl nsync_atm_store_rel_ .type nsync_atm_store_, @function nsync_atm_store_: nsync_atm_store_rel_: movl %esi, (%rdi) ret nsync-1.24.0/public/000077500000000000000000000000001367521742200142175ustar00rootroot00000000000000nsync-1.24.0/public/nsync.h000066400000000000000000000015431367521742200155250ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_H_ #define NSYNC_PUBLIC_NSYNC_H_ #include "nsync_mu.h" #include "nsync_mu_wait.h" #include "nsync_cv.h" #include "nsync_note.h" #include "nsync_counter.h" #include "nsync_waiter.h" #include "nsync_once.h" #include "nsync_debug.h" #endif /*NSYNC_PUBLIC_NSYNC_H_*/ nsync-1.24.0/public/nsync_atomic.h000066400000000000000000000041631367521742200170620ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_ATOMIC_H_ #define NSYNC_PUBLIC_NSYNC_ATOMIC_H_ #include "nsync_cpp.h" /* This file is not to be included directly by the client. It exists because on some platforms, one cannot use a simple uint32_t with atomic operations. */ #if NSYNC_ATOMIC_TYPECHECK #include NSYNC_CPP_START_ typedef struct { uint32_t value; } nsync_atomic_uint32_; NSYNC_CPP_END_ #define NSYNC_ATOMIC_UINT32_INIT_ { 0 } #define NSYNC_ATOMIC_UINT32_LOAD_(p) ((p)->value) #define NSYNC_ATOMIC_UINT32_STORE_(p,v) ((p)->value = (v)) #define NSYNC_ATOMIC_UINT32_PTR_(p) (&(p)->value) #elif NSYNC_ATOMIC_C11 #include NSYNC_CPP_START_ typedef atomic_uint_least32_t nsync_atomic_uint32_; NSYNC_CPP_END_ #define NSYNC_ATOMIC_UINT32_INIT_ 0 #define NSYNC_ATOMIC_UINT32_LOAD_(p) (*(p)) #define NSYNC_ATOMIC_UINT32_STORE_(p,v) (*(p) = (v)) #define NSYNC_ATOMIC_UINT32_PTR_(p) (p) #elif NSYNC_ATOMIC_CPP11 #include NSYNC_CPP_START_ typedef std::atomic nsync_atomic_uint32_; NSYNC_CPP_END_ #define NSYNC_ATOMIC_UINT32_INIT_ ATOMIC_VAR_INIT (0) #define NSYNC_ATOMIC_UINT32_LOAD_(p) (std::atomic_load (p)) #define NSYNC_ATOMIC_UINT32_STORE_(p,v) (std::atomic_store ((p), (uint32_t) (v))) #define NSYNC_ATOMIC_UINT32_PTR_(p) (p) #else #include NSYNC_CPP_START_ typedef uint32_t nsync_atomic_uint32_; NSYNC_CPP_END_ #define NSYNC_ATOMIC_UINT32_INIT_ 0 #define NSYNC_ATOMIC_UINT32_LOAD_(p) (*(p)) #define NSYNC_ATOMIC_UINT32_STORE_(p,v) (*(p) = (v)) #define NSYNC_ATOMIC_UINT32_PTR_(p) (p) #endif #endif /*NSYNC_PUBLIC_NSYNC_ATOMIC_H_*/ nsync-1.24.0/public/nsync_counter.h000066400000000000000000000042741367521742200172700ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_COUNTER_H_ #define NSYNC_PUBLIC_NSYNC_COUNTER_H_ #include #include "nsync_cpp.h" #include "nsync_mu.h" #include "nsync_atomic.h" #include "nsync_time.h" NSYNC_CPP_START_ struct nsync_dll_element_s_; /* An nsync_counter represents an unsigned integer that can count up and down, and wake waiters when zero. */ typedef struct nsync_counter_s_ *nsync_counter; /* Return a freshly allocated nsync_counter with the specified value, of NULL if an nsync_counter cannot be created. Any non-NULL returned value should be passed to nsync_counter_free() when no longer needed. */ nsync_counter nsync_counter_new (uint32_t value); /* Free resources associated with c. Requires that c was allocated by nsync_counter_new(), and no concurrent or future operations are applied to c. */ void nsync_counter_free (nsync_counter c); /* Add delta to c, and return its new value. It is a checkable runtime error to decrement c below 0, or to increment c (i.e., apply a delta > 0) after a waiter has waited. */ uint32_t nsync_counter_add (nsync_counter c, int32_t delta); /* Return the current value of c. */ uint32_t nsync_counter_value (nsync_counter c); /* Wait until c has value 0, or until abs_deadline, then return the value of c. It is a checkable runtime error to increment c after a waiter may have been woken due to the counter reaching zero. If abs_deadline==nsync_time_no_deadline, the deadline is far in the future. */ uint32_t nsync_counter_wait (nsync_counter c, nsync_time abs_deadline); NSYNC_COUNTER_CPP_OVERLOAD_ NSYNC_CPP_END_ #endif /*NSYNC_PUBLIC_NSYNC_COUNTER_H_*/ nsync-1.24.0/public/nsync_cpp.h000066400000000000000000000030351367521742200163650ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_CPP_H_ #define NSYNC_PUBLIC_NSYNC_CPP_H_ /* This header file permits compilation via a C++ compiler using the macros NSYNC_CPP_START_, NSYNC_CPP_END_, and NSYNC_CPP_USING_. NSYNC_CPP_START_ and NSYNC_CPP_END_ surround C code in the public library. They put all public symbols into the "nsync" name space. NSYNC_CPP_USING_ is used before C code (used for testing) that might use public exports from this package. It makes symbols in the "nsync" name space available without the "nsync::" prefix. NSYNC_C_START_ and NSYNC_C_END_ surround C code in the C++ modules. */ #if defined(__cplusplus) #define NSYNC_CPP_START_ namespace nsync { #define NSYNC_CPP_END_ } #define NSYNC_CPP_USING_ using namespace nsync; #define NSYNC_C_START_ extern "C" { #define NSYNC_C_END_ } #else #define NSYNC_CPP_START_ #define NSYNC_CPP_END_ #define NSYNC_CPP_USING_ #define NSYNC_C_START_ #define NSYNC_C_END_ #endif #endif /*NSYNC_PUBLIC_NSYNC_CPP_H_*/ nsync-1.24.0/public/nsync_cv.h000066400000000000000000000152701367521742200162170ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_CV_H_ #define NSYNC_PUBLIC_NSYNC_CV_H_ #include #include "nsync_cpp.h" #include "nsync_mu.h" #include "nsync_atomic.h" #include "nsync_time.h" NSYNC_CPP_START_ struct nsync_dll_element_s_; struct nsync_note_s_; /* An nsync_cv is a condition variable in the style of Mesa, Java, POSIX, and Go's sync.Cond. It allows a thread to wait for a condition on state protected by a mutex, and to proceed with the mutex held and the condition true. See also nsync_mu_wait() and nsync_mu_wait_with_deadline(), which implement conditional critical sections. In many cases, they are easier to use than condition variables. Usage: after making the desired predicate true, call: nsync_cv_signal (&cv); // If at most one thread can make use of the predicate becoming true. or nsync_cv_broadcast (&cv); // If multiple threads can make use of the predicate becoming true. To wait for a predicate with no deadline (assuming nsync_cv_broadcast() or nsync_cv_signal() is called whenever the predicate becomes true): nsync_mu_lock (μ) while (!some_predicate_protected_by_mu) { // the while-loop is required. nsync_cv_wait (&cv, &mu); } // predicate is now true nsync_mu_unlock (&mu); To wait for a predicate with a deadline (assuming nsync_cv_broadcast() or nsync_cv_signal() is called whenever the predicate becomes true): nsync_mu_lock (&mu); while (!some_predicate_protected_by_mu && nsync_cv_wait_with_deadline (&cv, &mu, abs_deadline, cancel_note) == 0) { } if (some_predicate_protected_by_mu) { // predicate is true } else { // predicate is false, and deadline expired, or cancel_note was notified. } nsync_mu_unlock (&mu); or, if the predicate is complex and you wish to write it just once and inline, you could use the following instead of the for-loop above: nsync_mu_lock (&mu); int pred_is_true = 0; int outcome = 0; while (!(pred_is_true = some_predicate_protected_by_mu) && outcome == 0) { outcome = nsync_cv_wait_with_deadline (&cv, &mu, abs_deadline, cancel_note); } if (pred_is_true) { // predicate is true } else { // predicate is false, and deadline expired, or cancel_note was notified. } nsync_mu_unlock (&mu); As the examples show, Mesa-style condition variables require that waits use a loop that tests the predicate anew after each wait. It may be surprising that these are preferred over the precise wakeups offered by the condition variables in Hoare monitors. Imprecise wakeups make more efficient use of the critical section, because threads can enter it while a woken thread is still emerging from the scheduler, which may take thousands of cycles. Further, they make the programme easier to read and debug by making the predicate explicit locally at the wait, where the predicate is about to be assumed; the reader does not have to infer the predicate by examining all the places where wakeups may occur. */ typedef struct nsync_cv_s_ { nsync_atomic_uint32_ word; /* see bits below */ struct nsync_dll_element_s_ *waiters; /* points to tail of list of waiters; under mu. */ } nsync_cv; /* An nsync_cv should be zeroed to initialize, which can be accomplished by initializing with static initializer NSYNC_CV_INIT, or by setting the entire struct to 0, or using nsync_cv_init(). */ #define NSYNC_CV_INIT { NSYNC_ATOMIC_UINT32_INIT_, 0 } void nsync_cv_init (nsync_cv *cv); /* Wake at least one thread if any are currently blocked on *cv. If the chosen thread is a reader on an nsync_mu, wake all readers and, if possible, a writer. */ void nsync_cv_signal (nsync_cv *cv); /* Wake all threads currently blocked on *cv. */ void nsync_cv_broadcast (nsync_cv *cv); /* Atomically release "mu" (which must be held on entry) and block the caller on *cv. Wait until awakened by a call to nsync_cv_signal() or nsync_cv_broadcast(), or a spurious wakeup; then reacquire "mu", and return. Equivalent to a call to nsync_mu_wait_with_deadline() with abs_deadline==nsync_time_no_deadline, and cancel_note==NULL. Callers should use nsync_cv_wait() in a loop, as with all standard Mesa-style condition variables. See examples above. */ void nsync_cv_wait (nsync_cv *cv, nsync_mu *mu); /* Atomically release "mu" (which must be held on entry) and block the calling thread on *cv. It then waits until awakened by a call to nsync_cv_signal() or nsync_cv_broadcast() (or a spurious wakeup), or by the time reaching abs_deadline, or by cancel_note being notified. In all cases, it reacquires "mu", and returns the reason for the call returned (0, ETIMEDOUT, or ECANCELED). Use abs_deadline==nsync_time_no_deadline for no deadline, and cancel_note==NULL for no cancellation. wait_with_deadline() should be used in a loop, as with all Mesa-style condition variables. See examples above. There are two reasons for using an absolute deadline, rather than a relative timeout---these are why pthread_cond_timedwait() also uses an absolute deadline. First, condition variable waits have to be used in a loop; with an absolute times, the deadline does not have to be recomputed on each iteration. Second, in most real programmes, some activity (such as an RPC to a server, or when guaranteeing response time in a UI), there is a deadline imposed by the specification or the caller/user; relative delays can shift arbitrarily with scheduling delays, and so after multiple waits might extend beyond the expected deadline. Relative delays tend to be more convenient mostly in tests and trivial examples than they are in real programmes. */ int nsync_cv_wait_with_deadline (nsync_cv *cv, nsync_mu *mu, nsync_time abs_deadline, struct nsync_note_s_ *cancel_note); /* Like nsync_cv_wait_with_deadline(), but allow an arbitrary lock *v to be used, given its (*lock)(mu) and (*unlock)(mu) routines. */ int nsync_cv_wait_with_deadline_generic (nsync_cv *cv, void *mu, void (*lock) (void *), void (*unlock) (void *), nsync_time abs_deadline, struct nsync_note_s_ *cancel_note); NSYNC_CV_CPP_OVERLOAD_ NSYNC_CPP_END_ #endif /*NSYNC_PUBLIC_NSYNC_CV_H_*/ nsync-1.24.0/public/nsync_debug.h000066400000000000000000000044301367521742200166710ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_DEBUG_H_ #define NSYNC_PUBLIC_NSYNC_DEBUG_H_ /* Debugging operations for mutexes and condition variables. These operations should not be relied upon for normal functionality. The implementation may be slow, output formats may change, and the implementation is free to yield the empty string. */ #include "nsync_cpp.h" #include "nsync_mu.h" #include "nsync_cv.h" NSYNC_CPP_START_ /* Place in buf[0,..,n-1] a nul-terminated, human readable string indicative of some of the internal state of the mutex or condition variable, and return buf. If n>=4, buffer overflow is indicated by placing the characters "..." at the end of the string. The *_and_waiters() variants attempt to output the waiter lists in addition to the basic state. These variants may acquire internal locks and follow internal pointers. Thus, they are riskier if invoked in an address space whose overall health is uncertain. */ char *nsync_mu_debug_state (nsync_mu *mu, char *buf, int n); char *nsync_cv_debug_state (nsync_cv *cv, char *buf, int n); char *nsync_mu_debug_state_and_waiters (nsync_mu *mu, char *buf, int n); char *nsync_cv_debug_state_and_waiters (nsync_cv *cv, char *buf, int n); /* Like nsync_*_debug_state_and_waiters(), but ignoring all locking and safety considerations, and using an internal, possibly static buffer that may be overwritten by subsequent or concurrent calls to these routines. These variants should be used only from an interactive debugger, when all other threads are stopped; the debugger is expected to recover from errors. */ char *nsync_mu_debugger (nsync_mu *mu); char *nsync_cv_debugger (nsync_cv *cv); NSYNC_CPP_END_ #endif /*NSYNC_PUBLIC_NSYNC_DEBUG_H_*/ nsync-1.24.0/public/nsync_mu.h000066400000000000000000000102711367521742200162240ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_MU_H_ #define NSYNC_PUBLIC_NSYNC_MU_H_ #include #include "nsync_cpp.h" #include "nsync_atomic.h" NSYNC_CPP_START_ struct nsync_dll_element_s_; /* An nsync_mu is a lock. If initialized to all zeroes, it is valid and unlocked. An nsync_mu can be "free", held by a single thread (aka fiber, goroutine) in "write" (exclusive) mode, or by many threads in "read" (shared) mode. A thread that acquires it should eventually release it. It is illegal to acquire an nsync_mu in one thread and release it in another. It is illegal for a thread to reacquire an nsync_mu while holding it (even a second share of a "read" lock). Example usage: static struct foo { nsync_mu mu; // protects invariant a+b==0 on fields below. int a; int b; } p = { NSYNC_MU_INIT, 0, 0 }; .... nsync_mu_lock (&p.mu); // The current thread now has exclusive access to p.a and p.b; invariant assumed true. p.a++; p.b--; // restore invariant p.a+p.b==0 before releasing p.mu nsync_mu_unlock (&p.mu) Mutexes can be used with condition variables; see nsync_cv.h. nsync_mu_wait() and nsync_mu_wait_with_deadline() can be used instead of condition variables. See nsync_mu_wait.h for more details. Example use of nsync_mu_wait() to wait for p.a==0, using definition above: int a_is_zero (const void *condition_arg) { return (((const struct foo *)condition_arg)->a == 0); } ... nsync_mu_lock (&p.mu); nsync_mu_wait (&p.mu, &a_is_zero, &p, NULL); // The current thread now has exclusive access to p.a and p.b, and p.a==0. ... nsync_mu_unlock (&p.mu); */ typedef struct nsync_mu_s_ { nsync_atomic_uint32_ word; /* internal use only */ struct nsync_dll_element_s_ *waiters; /* internal use only */ } nsync_mu; /* An nsync_mu should be zeroed to initialize, which can be accomplished by initializing with static initializer NSYNC_MU_INIT, or by setting the entire structure to all zeroes, or using nsync_mu_init(). */ #define NSYNC_MU_INIT { NSYNC_ATOMIC_UINT32_INIT_, 0 } void nsync_mu_init (nsync_mu *mu); /* Block until *mu is free and then acquire it in writer mode. Requires that the calling thread not already hold *mu in any mode. */ void nsync_mu_lock (nsync_mu *mu); /* Unlock *mu, which must have been acquired in write mode by the calling thread, and wake waiters, if appropriate. */ void nsync_mu_unlock (nsync_mu *mu); /* Attempt to acquire *mu in writer mode without blocking, and return non-zero iff successful. Return non-zero with high probability if *mu was free on entry. */ int nsync_mu_trylock (nsync_mu *mu); /* Block until *mu can be acquired in reader mode and then acquire it. Requires that the calling thread not already hold *mu in any mode. */ void nsync_mu_rlock (nsync_mu *mu); /* Unlock *mu, which must have been acquired in read mode by the calling thread, and wake waiters, if appropriate. */ void nsync_mu_runlock (nsync_mu *mu); /* Attempt to acquire *mu in reader mode without blocking, and return non-zero iff successful. Return non-zero with high probability if *mu was free on entry. Perhaps fail to acquire if a writer is waiting, to avoid starvation. */ int nsync_mu_rtrylock (nsync_mu *mu); /* May abort if *mu is not held in write mode by the calling thread. */ void nsync_mu_assert_held (const nsync_mu *mu); /* May abort if *mu is not held in read or write mode by the calling thread. */ void nsync_mu_rassert_held (const nsync_mu *mu); /* Return whether *mu is held in read mode. Requires that the calling thread holds *mu in some mode. */ int nsync_mu_is_reader (const nsync_mu *mu); NSYNC_CPP_END_ #endif /*NSYNC_PUBLIC_NSYNC_MU_H_*/ nsync-1.24.0/public/nsync_mu_wait.h000066400000000000000000000127161367521742200172560ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_MU_WAIT_H_ #define NSYNC_PUBLIC_NSYNC_MU_WAIT_H_ /* nsync_mu_wait() and nsync_mu_wait_with_deadline() can be used instead of condition variables. In many straightforward situations they are of equivalent performance and are somewhat easier to use, because unlike condition variables, they do not require that the waits be placed in a loop, and they do not require explicit wakeup calls. Example: Definitions: static nsync_mu mu = NSYNC_MU_INIT; static int i = 0; // protected by mu // Condition for use with nsync_mu_wait(). static int int_is_zero (const void *v) { return (*(const int *)v == 0); } Waiter: nsync_mu_lock (&mu); // Wait until i is zero. nsync_mu_wait (&mu, &int_is_zero, &i, NULL); // i is known to be zero here. // ... nsync_mu_unlock (&mu); Thread potentially making i zero: nsync_mu_lock (&mu); i--; // No need to signal that i may have become zero. The unlock call below // will evaluate waiters' conditions to decide which to wake. nsync_mu_unlock (&mu); It is legal to use conditional critical sections and condition variables on the same mutex. -------------- The implementation benefits from determining whether waiters are waiting for the same condition; it may then evaluate a condition once on behalf of several waiters. Two waiters have equal condition if their "condition" pointers are equal, and either: - their "condition_arg" pointers are equal, or - "condition_arg_eq" is non-null and (*condition_arg_eq) (condition_arg0, condition_arg1) returns non-zero. *condition_arg_eq will not be invoked unless the "condition" pointers are equal, and the "condition_arg" pointers are unequal. If many waiters wait for distinct conditions simultaneously, condition variables may be faster. */ #include "nsync_cpp.h" #include "nsync_mu.h" #include "nsync_time.h" NSYNC_CPP_START_ struct nsync_note_s_; /* forward declaration for an nsync_note */ /* Return when (*condition) (condition_arg) is true. Perhaps unlock and relock *mu while blocked waiting for the condition to become true. nsync_mu_wait() is equivalent to nsync_mu_wait_with_deadline() with abs_deadline==nsync_time_no_deadline, and cancel_note==NULL. Requires that *mu be held on entry. See nsync_mu_wait_with_deadline() for more details on *condition and *condition_arg_eq. */ void nsync_mu_wait (nsync_mu *mu, int (*condition) (const void *condition_arg), const void *condition_arg, int (*condition_arg_eq) (const void *a, const void *b)); /* Return when at least one of: (*condition) (condition_arg) is true, the deadline expires, or *cancel_note is notified. Perhaps unlock and relock *mu while blocked waiting for one of these events, but always return with *mu held. Return 0 iff the (*condition) (condition_arg) is true on return, and otherwise either ETIMEDOUT or ECANCELED, depending on why the call returned early. Callers should use abs_deadline==nsync_time_no_deadline for no deadline, and cancel_note==NULL for no cancellation. Requires that *mu be held on entry. The implementation may call *condition from any thread using the mutex, and while holding *mu in either read or write mode; it guarantees that any thread calling *condition will hold *mu in some mode. Requires that (*condition) (condition_arg) neither modify state protected by *mu, nor return a value dependent on state not protected by *mu. To depend on time, use the abs_deadline parameter. (Conventional use of condition variables have the same restrictions on the conditions tested by the while-loop.) If non-null, condition_arg_eq should return whether two condition_arg calls with the same "condition" pointer are considered equivalent; it should have no side-effects. */ int nsync_mu_wait_with_deadline (nsync_mu *mu, int (*condition) (const void *condition_arg), const void *condition_arg, int (*condition_arg_eq) (const void *a, const void *b), nsync_time abs_deadline, struct nsync_note_s_ *cancel_note); /* Unlock *mu, which must be held in write mode, and wake waiters, if appropriate. Unlike nsync_mu_unlock(), this call is not required to wake nsync_mu_wait/nsync_mu_wait_with_deadline calls on conditions that were false before this thread acquired the lock. This call should be used only at the end of critical sections for which: - nsync_mu_wait and/or nsync_mu_wait_with_deadline are in use on the same mutex, - this critical section cannot make the condition true for any of those nsync_mu_wait/nsync_mu_wait_with_deadline waits, and - when performance is significantly improved by using this call. */ void nsync_mu_unlock_without_wakeup (nsync_mu *mu); NSYNC_MU_WAIT_CPP_OVERLOAD_ NSYNC_CPP_END_ #endif /*NSYNC_PUBLIC_NSYNC_MU_WAIT_H_*/ nsync-1.24.0/public/nsync_note.h000066400000000000000000000051171367521742200165530ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_NOTE_H_ #define NSYNC_PUBLIC_NSYNC_NOTE_H_ #include "nsync_cpp.h" #include "nsync_time.h" NSYNC_CPP_START_ /* An nsync_note represents a single bit that can transition from 0 to 1 at most once. When 1, the note is said to be notified. There are operations to wait for the transition, which can be triggered either by an explicit call, or timer expiry. Notes can have parent notes; a note becomes notified if its parent becomes notified. */ typedef struct nsync_note_s_ *nsync_note; /* Return a freshly allocated nsync_note, or NULL if an nsync_note cannot be created. If parent!=NULL, the allocated nsync_note's parent will be parent. The newaly allocated note will be automatically notified at abs_deadline, and is notified at initialization if abs_deadline==nsync_zero_time. nsync_notes should be passed to nsync_note_free() when no longer needed. */ nsync_note nsync_note_new (nsync_note parent, nsync_time abs_deadline); /* Free resources associated with n. Requires that n was allocated by nsync_note_new(), and no concurrent or future operations are applied to n directly. It is legal to call nsync_note_free() on a node even if it has a parent or children that are in use; if n has both a parent and children, n's parent adopts its children. */ void nsync_note_free (nsync_note n); /* Notify n and all its descendants. */ void nsync_note_notify (nsync_note n); /* Return whether n has been notified. */ int nsync_note_is_notified (nsync_note n); /* Wait until n has been notified or abs_deadline is reached, and return whether n has been notified. If abs_deadline==nsync_time_no_deadline, the deadline is far in the future. */ int nsync_note_wait (nsync_note n, nsync_time abs_deadline); /* Return the expiry time associated with n. This is the minimum of the abs_deadline passed on creation and that of any of its ancestors. */ nsync_time nsync_note_expiry (nsync_note n); NSYNC_NOTE_CPP_OVERLOAD_ NSYNC_CPP_END_ #endif /*NSYNC_PUBLIC_NSYNC_NOTE_H_*/ nsync-1.24.0/public/nsync_once.h000066400000000000000000000040151367521742200165260ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_ONCE_H_ #define NSYNC_PUBLIC_NSYNC_ONCE_H_ #include #include "nsync_cpp.h" #include "nsync_atomic.h" NSYNC_CPP_START_ /* An nsync_once allows a function to be called exactly once, when first referenced. */ typedef nsync_atomic_uint32_ nsync_once; /* An initializer for nsync_once; it is guaranteed to be all zeroes. */ #define NSYNC_ONCE_INIT NSYNC_ATOMIC_UINT32_INIT_ /* The first time nsync_run_once() or nsync_run_once_arg() is applied to *once, the supplied function is run (with argument, in the case of nsync_run_once_arg()). Other callers will wait until the run of the function is complete, and then return without running the function again. */ void nsync_run_once (nsync_once *once, void (*f) (void)); void nsync_run_once_arg (nsync_once *once, void (*farg) (void *arg), void *arg); /* Same as nsync_run_once()/nsync_run_once_arg() but uses a spinloop. Can be used on the same nsync_once as nsync_run_once/nsync_run_once_arg(). These *_spin variants should be used only in contexts where normal blocking is disallowed, such as within user-space schedulers, when the runtime is not fully initialized, etc. They provide no significant performance benefit, and they should be avoided in normal code. */ void nsync_run_once_spin (nsync_once *once, void (*f) (void)); void nsync_run_once_arg_spin (nsync_once *once, void (*farg) (void *arg), void *arg); NSYNC_CPP_END_ #endif /*NSYNC_PUBLIC_NSYNC_ONCE_H_*/ nsync-1.24.0/public/nsync_time.h000066400000000000000000000043171367521742200165450ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_TIME_H_ #define NSYNC_PUBLIC_NSYNC_TIME_H_ #include "nsync_cpp.h" #include "nsync_time_internal.h" /* The type nsync_time represents the interval elapsed between two moments in time. Often the first such moment is an address-space-wide epoch, such as the Unix epoch, but clients should not rely on the epoch in one address space being the same as that in another. Intervals relative to the epoch are known as absolute times. The internals of nsync_time should be treated as opaque by clients. See nsync_time_internal.h. */ NSYNC_CPP_START_ extern const nsync_time nsync_time_no_deadline; /* A deadline infinitely far in the future. */ extern const nsync_time nsync_time_zero; /* The zero delay, or an expired deadline. */ nsync_time nsync_time_now (void); /* Return the current time since the epoch. */ /* Sleep for the specified delay. Returns the unslept time which may be non-zero if the call was interrupted. */ nsync_time nsync_time_sleep (nsync_time delay); /* Return a+b */ nsync_time nsync_time_add (nsync_time a, nsync_time b); /* Return a-b */ nsync_time nsync_time_sub (nsync_time a, nsync_time b); /* Return +ve, 0, or -ve according to whether a>b, a==b, or a NSYNC_CPP_START_ typedef NSYNC_USE_INT_TIME nsync_time; #define NSYNC_TIME_SEC(t) (sizeof (nsync_time) >= 8? \ (t) / (1000 * 1000 * 1000): \ ((t) / 1000)) #define NSYNC_TIME_NSEC(t) (sizeof (nsync_time) >= 8? \ (t) % (1000 * 1000 * 1000): \ (((t) % 1000) * 1000 * 1000)) #define NSYNC_TIME_MAX_ MAX_INT_TYPE (nsync_time) NSYNC_CPP_END_ #elif defined(NSYNC_USE_FLOATING_TIME) #include #include NSYNC_CPP_START_ typedef NSYNC_USE_FLOATING_TIME nsync_time; #define NSYNC_TIME_SEC(t) (trunc ((t) / (nsync_time) (1000 * 1000 * 1000))) #define NSYNC_TIME_NSEC(t) ((t) - ((1000 * 1000 * 1000) * NSYNC_TIME_SEC (t))) #define NSYNC_TIME_MAX_ DBL_MAX NSYNC_CPP_END_ #elif NSYNC_USE_DEBUG_TIME /* Check that the library can be built with a different time struct. */ #include NSYNC_CPP_START_ typedef struct { time_t seconds; unsigned nanoseconds; } nsync_time; #define NSYNC_TIME_SEC(t) ((t).seconds) #define NSYNC_TIME_NSEC(t) ((t).nanoseconds) NSYNC_CPP_END_ #elif defined(__cplusplus) && \ (NSYNC_USE_CPP11_TIMEPOINT || (__cplusplus >= 201103L) || (_MSC_VER >= 1700)) /* The inline functions below provide function overloads that accept the most likely C++11 time type(s). C++11 time types have many variations and subtleties: - There are multiple clocks with potentially differing epochs; these clocks are not necessarily phase-locked to the same rate, making conversion and comparison between clocks tricky. - Relative and absolute times are distinguished in the type system. - Either integral or floating point counters may be used to represent time intervals, and code valid with one may not be valid with the other (see std::chrono::treat_as_floating_point). - A counter increment of one can represent any rational number of seconds (for whatever "seconds" means for this clock). - Conversions between duration types may round or truncate at the implementation's discretion. - As mentioned above, common implementations of the default monotonic clock ("steady_clock") illegally allow a thread to observe time going backwards, especially in the face of scheduling on a different CPU, making its use misleading, at best. I've chosen to handle this complexity by doing a conversion to absolute timespec at the interface layer, so all the C++ complication is here, rather than spread throughout the library. */ #include #include NSYNC_CPP_START_ typedef struct timespec nsync_time; #define NSYNC_TIME_SEC(t) ((t).tv_sec) #define NSYNC_TIME_NSEC(t) ((t).tv_nsec) typedef std::chrono::system_clock::time_point nsync_cpp_time_point_; nsync_time nsync_from_time_point_ (nsync_cpp_time_point_); nsync_cpp_time_point_ nsync_to_time_point_ (nsync_time); #define NSYNC_COUNTER_CPP_OVERLOAD_ \ static inline uint32_t nsync_counter_wait (nsync_counter c, \ nsync_cpp_time_point_ abs_deadline) { \ return (nsync_counter_wait (c, nsync_from_time_point_ (abs_deadline))); \ } #define NSYNC_CV_CPP_OVERLOAD_ \ static inline int nsync_cv_wait_with_deadline (nsync_cv *cv, nsync_mu *mu, \ nsync_cpp_time_point_ abs_deadline, struct nsync_note_s_ *cancel_note) { \ return (nsync_cv_wait_with_deadline (cv, mu, \ nsync_from_time_point_ (abs_deadline), \ cancel_note)); \ } \ static inline int nsync_cv_wait_with_deadline_generic (nsync_cv *cv, \ void *mu, void (*lock) (void *), void (*unlock) (void *), \ nsync_cpp_time_point_ abs_deadline, struct nsync_note_s_ *cancel_note) { \ return (nsync_cv_wait_with_deadline_generic (cv, mu, lock, unlock, \ nsync_from_time_point_ (abs_deadline), \ cancel_note)); \ } #define NSYNC_MU_WAIT_CPP_OVERLOAD_ \ static inline int nsync_mu_wait_with_deadline (nsync_mu *mu, \ int (*condition) (const void *condition_arg), const void *condition_arg, \ int (*condition_arg_eq) (const void *a, const void *b), \ nsync_cpp_time_point_ abs_deadline, struct nsync_note_s_ *cancel_note) { \ return (nsync_mu_wait_with_deadline (mu, condition, condition_arg, \ condition_arg_eq, \ nsync_from_time_point_ (abs_deadline), \ cancel_note)); \ } #define NSYNC_NOTE_CPP_OVERLOAD_ \ static inline nsync_note nsync_note_new (nsync_note parent, \ nsync_cpp_time_point_ abs_deadline) { \ return (nsync_note_new (parent, nsync_from_time_point_ (abs_deadline))); \ } \ static inline int nsync_note_wait (nsync_note n, nsync_cpp_time_point_ abs_deadline) { \ return (nsync_note_wait (n, nsync_from_time_point_ (abs_deadline))); \ } \ static inline nsync_cpp_time_point_ nsync_note_expiry_timepoint (nsync_note n) { \ return (nsync_to_time_point_ (nsync_note_expiry (n))); \ } #define NSYNC_WAITER_CPP_OVERLOAD_ \ static inline int nsync_wait_n (void *mu, void (*lock) (void *), \ void (*unlock) (void *), \ nsync_cpp_time_point_ abs_deadline, \ int count, struct nsync_waitable_s *waitable[]) { \ return (nsync_wait_n (mu, lock, unlock, \ nsync_from_time_point_ (abs_deadline), count, waitable)); \ } NSYNC_CPP_END_ #else /* Default is to use timespec. */ #include NSYNC_CPP_START_ typedef struct timespec nsync_time; #define NSYNC_TIME_SEC(t) ((t).tv_sec) #define NSYNC_TIME_NSEC(t) ((t).tv_nsec) NSYNC_CPP_END_ #endif #if !defined(NSYNC_COUNTER_CPP_OVERLOAD_) #define NSYNC_COUNTER_CPP_OVERLOAD_ #define NSYNC_CV_CPP_OVERLOAD_ #define NSYNC_MU_WAIT_CPP_OVERLOAD_ #define NSYNC_NOTE_CPP_OVERLOAD_ #define NSYNC_WAITER_CPP_OVERLOAD_ #endif #endif /*NSYNC_PUBLIC_NSYNC_TIME_INTERNAL_H_*/ nsync-1.24.0/public/nsync_waiter.h000066400000000000000000000133311367521742200170760ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_PUBLIC_NSYNC_WAITER_H_ #define NSYNC_PUBLIC_NSYNC_WAITER_H_ /* nsync_wait_n() allows the client to wait on multiple objects (condition variables, nsync_notes, nsync_counters, etc.) until at least one of them becomes ready, or a deadline expires. It can be thought of as rather like Unix's select() or poll(), except the the objects being waited for are synchronization data structures, rather than file descriptors. The client can construct new objects that can be waited for by implementing three routines. Examples: To wait on two nsync_notes n0, n1, and a nsync_counter c0, with a deadline of abs_deadline: // Form an array of struct nsync_waitable_s, identifying the // objects and the corresponding descriptors. (static initialization // syntax is used for brevity) static struct nsync_waitable_s w[] = { { &n0, &nsync_note_waitable_funcs }, { &n1, &nsync_note_waitable_funcs }, { &c0, &nsync_counter_waitable_funcs } }; static struct nsync_waitable_s *pw[] = { &w[0], &w[1], &w[2] }; int n = sizeof (w) / sizeof (w[0]); // Wait. The mu, lock, and unlock arguments are NULL because // no condition variables are invovled. int i = nsync_wait_n (NULL, NULL, NULL, abs_deadline, n, pw); if (i == n) { // timeout } else { // w[i].v became ready. } To wait on multiple condition variables, the mu/lock/unlock parameters are used. Imagine cv0 and cv1 are signalled when predicates pred0() (under lock mu0) and pred1() (under lock mu1) become true respectively. Assume that mu0 is acquired before mu1. static void lock2 (void *v) { // lock two mutexes in order nsync_mu **mu = (nsync_mu **) v; nsync_mu_lock (mu[0]); nsync_mu_lock (mu[1]); } static void unlock2 (void *v) { // unlock two mutexes. nsync_mu **mu = (nsync_mu **) v; nsync_mu_unlock (mu[1]); nsync_mu_unlock (mu[0]); } // Describe the condition variables and the locks. static struct nsync_waitable_s w[] = { { &cv0, &nsync_cv_waitable_funcs }, { &cv1, &nsync_cv_waitable_funcs } }; static struct nsync_waitable_s *pw[] = { &w[0], &w[1] }; nsync_mu *lock_list[] = { &mu0, &mu1 }; int n = sizeof (w) / sizeof (w[0]); lock2 (list_list); while (!pred0 () && !pred1 ()) { // Wait for one of the condition variables to be signalled, // with no timeout. nsync_wait_n (lock_list, &lock2, &unlock2, nsync_time_no_deadline, n, pw); } if (pred0 ()) { ... } if (pred1 ()) { ... } unlock2 (list_list); */ #include #include #include "nsync_cpp.h" #include "nsync_atomic.h" #include "nsync_time.h" NSYNC_CPP_START_ struct nsync_waitable_funcs_s; /* forward declaration of struct that contains type dependent wait operations */ /* Clients wait on objects by forming an array of struct nsync_waitable_s. Each each element points to one object and its type-dependent functions. */ struct nsync_waitable_s { void *v; /* pointer to object */ /* pointer to type-dependent functions. Use &nsync_note_waitable_funcs for an nsync_note, &nsync_counternote_waitable_funcs for an nsync_counter, &nsync_cv_waitable_funcs for an nsync_cv. */ const struct nsync_waitable_funcs_s *funcs; }; /* Wait until at least one of *waitable[0,..,count-1] is has been notified, or abs_deadline is reached. Return the index of the notified element of waitable[], or count if no such element exists. If mu!=NULL, (*unlock)(mu) is called after the thread is queued on the various waiters, and (*lock)(mu) is called before return; mu/lock/unlock are used to acquire and release the relevant locks whan waiting on condition variables. */ int nsync_wait_n (void *mu, void (*lock) (void *), void (*unlock) (void *), nsync_time abs_deadline, int count, struct nsync_waitable_s *waitable[]); /* --------------------------------------------------- */ /* A "struct nsync_waitable_s" implementation must implement these functions. Clients should ignore the internals. */ struct nsync_waiter_s; struct nsync_waitable_funcs_s { /* Return the time when *v will be ready (max time if unknown), or 0 if it is already ready. The parameter nw may be passed as NULL, in which case the result should indicate whether the thread would block if it were to wait on *v. All calls with the same *v must report the same result until the object becomes ready, from which point calls must report 0. */ nsync_time (*ready_time) (void *v, struct nsync_waiter_s *nw); /* If *v is ready, return zero; otherwise enqueue *nw on *v and return non-zero. */ int (*enqueue) (void *v, struct nsync_waiter_s *nw); /* If nw has been previously dequeued, return zero; otherwise dequeue *nw from *v and return non-zero. */ int (*dequeue) (void *v, struct nsync_waiter_s *nw); }; /* The "struct nsync_waitable_s" for nsync_note, nsync_counter, and nsync_cv. */ extern const struct nsync_waitable_funcs_s nsync_note_waitable_funcs; extern const struct nsync_waitable_funcs_s nsync_counter_waitable_funcs; extern const struct nsync_waitable_funcs_s nsync_cv_waitable_funcs; NSYNC_WAITER_CPP_OVERLOAD_ NSYNC_CPP_END_ #endif /*NSYNC_PUBLIC_NSYNC_WAITER_H_*/ nsync-1.24.0/testing/000077500000000000000000000000001367521742200144165ustar00rootroot00000000000000nsync-1.24.0/testing/array.c000066400000000000000000000022141367521742200156770ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "array.h" void a_ensure_ (void *v, int delta, int sz) { typedef A_TYPE (void *) a_void_ptr; a_void_ptr *a = (a_void_ptr *) v; int omax = a->h_.max_; if (omax < 0) { omax = -omax; } if (a->h_.len_ + delta > omax) { int nmax = a->h_.len_ + delta; void *na; if (nmax < omax * 2) { nmax = omax * 2; } if (a->h_.max_ <= 0) { na = malloc (nmax * sz); memcpy (na, a->a_, omax*sz); } else { na = realloc (a->a_, nmax*sz); } memset (omax *sz + (char *)na, 0, (nmax - omax) * sz); a->a_ = (void **) na; a->h_.max_ = nmax; } } nsync-1.24.0/testing/array.h000066400000000000000000000055421367521742200157130ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_TESTING_ARRAY_H_ #define NSYNC_TESTING_ARRAY_H_ /* Return the number of elements in a C array a. A constant expression if a is a constant expression. */ #define NELEM(a) ((int) (sizeof (a) / sizeof (a[0]))) /* A dynamic array */ /* internal routines */ void a_ensure_ (void *v, int delta, int sz); /* The following struct prefixes all array values. */ struct a_hdr_ { int len_; /* The number of elements considererf to be part of the array. */ int max_; /* abs(max_) is the number of elements that have been set aside to store elements of the array. If max_ < 0, the space has been allocated statically. If max_ > 0, the space has been allocated dynamically. */ }; /* A type declaration for an array of "type". Example: typedef A_TYPE (int) array_of_int; */ #define A_TYPE(type) struct { struct a_hdr_ h_; type *a_; } /* The empty array initializer. Empty arrays can also be initialized by zeroing. */ #define A_EMPTY { { 0, 0 }, NULL } /* A static initializer using the contents of C array "data". Example: static int some_ints[] = { 7, 11, 13 }; static array_of_int x = A_INIT (some_ints); */ #define A_INIT(data) { { NELEM (data), -NELEM (data) }, data } /* Element i of the array *a (l-value or r-value) */ #define A(a,i) ((a)->a_[i]) /* Append an entry to array *a, and yield it as an l-value. */ #define A_PUSH(a) (*(a_ensure_ ((a), 1, sizeof ((a)->a_[0])), &(a)->a_[(a)->h_.len_++])) /* Return the length of array *a. */ #define A_LEN(a) ((a)->h_.len_) /* Set the length of array *a to l. Requires that 0 <= l <= A_LEN (a). */ #define A_SET_LEN(a, l) do { if (0 <= (l) && (l) <= (a)->h_.len_) { \ (a)->h_.len_ = (l); } else { \ *(volatile int *)0 = 0; } } while (0) /* Reduce the length of array *a by n. Requires that 0 <= n <= A_LEN (a). */ #define A_DISCARD(a, n) do { if (0 <= (n) && (n) <= (a)->h_.len_) { \ (a)->h_.len_ -= (n); } else { \ *(volatile int *)0 = 0; } } while (0) /* Deallocate and disassociate any storage associated with *a, and make *a empty. */ #define A_FREE(a) do { if ((a)->h_.max_ > 0) { free ((void *) (a)->a_); } \ (a)->a_ = NULL; (a)->h_.max_ = 0; (a)->h_.len_ = 0; \ } while (0) #endif /*NSYNC_TESTING_ARRAY_H_*/ nsync-1.24.0/testing/atm_log.c000066400000000000000000000044621367521742200162120ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #ifndef NSYNC_ATM_LOG #define NSYNC_ATM_LOG 0 #endif struct atm_log { uintptr_t i; uintptr_t thd_id; uintptr_t c; void *p; uintptr_t o; uintptr_t n; const char *file; uintptr_t line; }; #define LOG_N 14 static struct atm_log log_entries[1 << LOG_N]; static uint32_t log_i; static pthread_mutex_t log_mu; static pthread_key_t key; static pthread_once_t once = PTHREAD_ONCE_INIT; static void do_once (void) { pthread_mutex_init (&log_mu, NULL); pthread_key_create (&key, NULL); } static int thread_id; void nsync_atm_log_ (int c, void *p, uint32_t o, uint32_t n, const char *file, int line) { if (NSYNC_ATM_LOG) { struct atm_log *e; uint32_t i; int *pthd_id; int thd_id; pthread_once (&once, &do_once); pthd_id = (int *) pthread_getspecific (key); pthread_mutex_lock (&log_mu); i = log_i++; if (pthd_id == NULL) { thd_id = thread_id++; pthd_id = (int *) malloc (sizeof (*pthd_id)); pthread_setspecific (key, pthd_id); *pthd_id = thd_id; } else { thd_id = *pthd_id; } pthread_mutex_unlock (&log_mu); e = &log_entries[i & ((1 << LOG_N) - 1)]; e->i = i; e->thd_id = thd_id; e->c = c; e->p = p; e->o = o; e->n = n; e->file = file; e->line = line; } } void nsync_atm_log_print_ (void) { if (NSYNC_ATM_LOG) { uint32_t i; pthread_once (&once, &do_once); pthread_mutex_lock (&log_mu); for (i = 0; i != (1 << LOG_N); i++) { struct atm_log *e = &log_entries[i]; if (e->file != 0) { fprintf (stderr, "%6lx %3d %c p %16p o %8x n %8x %10s:%d\n", (unsigned long) e->i, (int) e->thd_id, e->c <= ' '? '?' : (char)e->c, e->p, (uint32_t) e->o, (uint32_t) e->n, e->file, (int) e->line); } } pthread_mutex_unlock (&log_mu); } } nsync-1.24.0/testing/atm_log.h000066400000000000000000000014721367521742200162150ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_TESTING_ATM_LOG_H_ #define NSYNC_TESTING_ATM_LOG_H_ #include "platform.h" void nsync_atm_log_ (int c, void *p, uint32_t o, uint32_t n, const char *file, int line); void nsync_atm_log_print_ (void); #endif /*NSYNC_TESTING_ATM_LOG_H_*/ nsync-1.24.0/testing/closure.c000066400000000000000000000021041367521742200162330ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "nsync_cpp.h" #include "platform.h" #include "compiler.h" #include "cputype.h" #include "closure.h" NSYNC_CPP_START_ void nsync_start_thread_ (void (*f) (void *), void *arg); NSYNC_CPP_END_ NSYNC_CPP_USING_ /* Run the closure *cl. */ void closure_run (closure *cl) { (*cl->f0) (cl); } /* Run the closure (closure *), but wrapped to fix the type. */ static void closure_run_body (void *v) { closure_run ((closure *)v); } void closure_fork (closure *cl) { nsync_start_thread_ (&closure_run_body, cl); } nsync-1.24.0/testing/closure.h000066400000000000000000000166451367521742200162570ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_TESTING_CLOSURE_H_ #define NSYNC_TESTING_CLOSURE_H_ /* A run-once, self-freeing closure. */ typedef struct closure_s { void (*f0) (void *); } closure; /* Run the closure *cl, and free it. */ void closure_run (closure *cl); /* Fork a new thread running the closure *cl, which will be freed when the thread exits. */ void closure_fork (closure *cl); /* To create a closure, declare a closure constructor with the right function arguments. For functions taking no arguments, use CLOSURE_DECL_BODY0 (foo) to generate the static routine: static closure *closure_foo (void (*f) (void)); that will return a closure for any function *f that takes no argument. For an 1-argument function, use CLOSURE_DECL_BODY1 (foo, type) to generate the static routine: static closure *closure_foo (void (*f) (type), type x); that will return a closure for any function taking a single argument of the specified type. For an 2-argument function, use CLOSURE_DECL_BODY2 (foo, type0, type1) to generate the static routine: static closure *closure_foo (void (*f) (type0, type1), type0 x0, type1 x1); that will return a closure for any function taking a "type0" argument, and a "type1" argument. And so on, up to 9 arguments. For example, to make closures out of qsort(): // First, just once (per module) define: // static closure *closure_qsort_args ( // void (*f) (void *, size_t, size_t, int (*)(const void *, const void *)) // void *x0, size_t x1, size_t x2, int (*x3)(const void *, const void *)); // by writing: CLOSURE_DECL_BODY4 (qsort_args, void *, size_t, size_t, int (*)(const void *, const void *)) // Second, for each closure to be created, write something like this: closure *cl = closure_qsort_args (array, n_elements, sizeof (array[0]), &elem_cmp); // Then to run (and free) each closure: closure_run (cl); // This is like calling // qsort (array, n_elements, sizeof (array[0]), &elem_cmp); // free (cl); */ /* ------------------------------------------------------------------ */ /* Internal macro details follow. */ #define CLOSURE_S0(x,e) e #define CLOSURE_S1(x,e) x##0 #define CLOSURE_S2(x,e) x##0, x##1 #define CLOSURE_S3(x,e) x##0, x##1, x##2 #define CLOSURE_S4(x,e) x##0, x##1, x##2, x##3 #define CLOSURE_S5(x,e) x##0, x##1, x##2, x##3, x##4 #define CLOSURE_S6(x,e) x##0, x##1, x##2, x##3, x##4, x##5 #define CLOSURE_S7(x,e) x##0, x##1, x##2, x##3, x##4, x##5, x##6 #define CLOSURE_S8(x,e) x##0, x##1, x##2, x##3, x##4, x##5, x##6, x##7 #define CLOSURE_S9(x,e) x##0, x##1, x##2, x##3, x##4, x##5, x##6, x##7, x##8 #define CLOSURE_P0(x,y,p,s,t) #define CLOSURE_P1(x,y,p,s,t) p x##0 y##0 t #define CLOSURE_P2(x,y,p,s,t) p x##0 y##0 s x##1 y##1 t #define CLOSURE_P3(x,y,p,s,t) p x##0 y##0 s x##1 y##1 s x##2 y##2 t #define CLOSURE_P4(x,y,p,s,t) p x##0 y##0 s x##1 y##1 s x##2 y##2 s x##3 y##3 t #define CLOSURE_P5(x,y,p,s,t) p x##0 y##0 s x##1 y##1 s x##2 y##2 s x##3 y##3 s x##4 y##4 t #define CLOSURE_P6(x,y,p,s,t) p x##0 y##0 s x##1 y##1 s x##2 y##2 s x##3 y##3 s x##4 y##4 s \ x##5 y##5 t #define CLOSURE_P7(x,y,p,s,t) p x##0 y##0 s x##1 y##1 s x##2 y##2 s x##3 y##3 s x##4 y##4 s \ x##5 y##5 s x##6 y##6 t #define CLOSURE_P8(x,y,p,s,t) p x##0 y##0 s x##1 y##1 s x##2 y##2 s x##3 y##3 s x##4 y##4 s \ x##5 y##5 s x##6 y##6 s x##7 y##7 t #define CLOSURE_P9(x,y,p,s,t) p x##0 y##0 s x##1 y##1 s x##2 y##2 s x##3 y##3 s x##4 y##4 s \ x##5 y##5 s x##6 y##6 s x##7 y##7 s x##8 y##8 t #define CLOSURE_COMMA_ , #define CLOSURE_SEMI_ ; #define CLOSURE_BLANK_ #define CLOSURE_DECL_BODY_N_(name, n) \ struct closure_s_##name { \ void (*f0) (void *); /* must be first; matches closure. */ \ void (*f) (CLOSURE_S##n (closure_t_##name##_,void)); \ CLOSURE_P##n (closure_t_##name##_, a, CLOSURE_BLANK_, \ CLOSURE_SEMI_, CLOSURE_SEMI_) \ }; \ static void closure_f0_##name (void *v) { \ struct closure_s_##name *a = (struct closure_s_##name *) v; \ (*a->f) (CLOSURE_S##n (a->a,CLOSURE_BLANK_)); \ free (a); \ } \ static closure *closure_##name (void (*f) (CLOSURE_S##n (closure_t_##name##_,void)) \ CLOSURE_P##n (closure_t_##name##_, a, CLOSURE_COMMA_, \ CLOSURE_COMMA_, CLOSURE_BLANK_)) { \ struct closure_s_##name *cl = (struct closure_s_##name *) malloc (sizeof (*cl)); \ cl->f0 = &closure_f0_##name; \ cl->f = f; \ CLOSURE_P##n (cl->a, = a, CLOSURE_BLANK_, CLOSURE_SEMI_, CLOSURE_SEMI_) \ return ((closure *) cl); \ } #define CLOSURE_DECL_BODY0(name) \ CLOSURE_DECL_BODY_N_ (name, 0) #define CLOSURE_DECL_BODY1(name, t0) \ typedef t0 closure_t_##name##_0; \ CLOSURE_DECL_BODY_N_ (name, 1) #define CLOSURE_DECL_BODY2(name, t0, t1) \ typedef t0 closure_t_##name##_0; \ typedef t1 closure_t_##name##_1; \ CLOSURE_DECL_BODY_N_ (name, 2) #define CLOSURE_DECL_BODY3(name, t0, t1, t2) \ typedef t0 closure_t_##name##_0; \ typedef t1 closure_t_##name##_1; \ typedef t2 closure_t_##name##_2; \ CLOSURE_DECL_BODY_N_ (name, 3) #define CLOSURE_DECL_BODY4(name, t0, t1, t2, t3) \ typedef t0 closure_t_##name##_0; \ typedef t1 closure_t_##name##_1; \ typedef t2 closure_t_##name##_2; \ typedef t3 closure_t_##name##_3; \ CLOSURE_DECL_BODY_N_ (name, 4) #define CLOSURE_DECL_BODY5(name, t0, t1, t2, t3, t4) \ typedef t0 closure_t_##name##_0; \ typedef t1 closure_t_##name##_1; \ typedef t2 closure_t_##name##_2; \ typedef t3 closure_t_##name##_3; \ typedef t4 closure_t_##name##_4; \ CLOSURE_DECL_BODY_N_ (name, 5) #define CLOSURE_DECL_BODY6(name, t0, t1, t2, t3, t4, t5) \ typedef t0 closure_t_##name##_0; \ typedef t1 closure_t_##name##_1; \ typedef t2 closure_t_##name##_2; \ typedef t3 closure_t_##name##_3; \ typedef t4 closure_t_##name##_4; \ typedef t5 closure_t_##name##_5; \ CLOSURE_DECL_BODY_N_ (name, 6) #define CLOSURE_DECL_BODY7(name, t0, t1, t2, t3, t4, t5, t6) \ typedef t0 closure_t_##name##_0; \ typedef t1 closure_t_##name##_1; \ typedef t2 closure_t_##name##_2; \ typedef t3 closure_t_##name##_3; \ typedef t4 closure_t_##name##_4; \ typedef t5 closure_t_##name##_5; \ typedef t6 closure_t_##name##_6; \ CLOSURE_DECL_BODY_N_ (name, 7) #define CLOSURE_DECL_BODY8(name, t0, t1, t2, t3, t4, t5, t6, t7) \ typedef t0 closure_t_##name##_0; \ typedef t1 closure_t_##name##_1; \ typedef t2 closure_t_##name##_2; \ typedef t3 closure_t_##name##_3; \ typedef t4 closure_t_##name##_4; \ typedef t5 closure_t_##name##_5; \ typedef t6 closure_t_##name##_6; \ typedef t7 closure_t_##name##_7; \ CLOSURE_DECL_BODY_N_ (name, 8) #define CLOSURE_DECL_BODY9(name, t0, t1, t2, t3, t4, t5, t6, t7, t8) \ typedef t0 closure_t_##name##_0; \ typedef t1 closure_t_##name##_1; \ typedef t2 closure_t_##name##_2; \ typedef t3 closure_t_##name##_3; \ typedef t4 closure_t_##name##_4; \ typedef t5 closure_t_##name##_5; \ typedef t6 closure_t_##name##_6; \ typedef t7 closure_t_##name##_7; \ typedef t8 closure_t_##name##_8; \ CLOSURE_DECL_BODY_N_ (name, 9) #endif /*NSYNC_TESTING_CLOSURE_H_*/ nsync-1.24.0/testing/counter_test.c000066400000000000000000000122601367521742200173010ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "nsync.h" #include "time_extra.h" #include "smprintf.h" #include "closure.h" #include "testing.h" NSYNC_CPP_USING_ /* Verify the properties of a zero counter. */ static void test_counter_zero (testing t) { int i; nsync_counter c = nsync_counter_new (0); for (i = 0; i != 2; i++) { if (nsync_counter_value (c) != 0) { TEST_ERROR (t, ("zero counter is not zero (test, %d)", i)); } if (nsync_counter_wait (c, nsync_time_zero) != 0) { TEST_ERROR (t, ("zero counter is not zero (poll, %d)", i)); } if (nsync_counter_wait (c, nsync_time_no_deadline) != 0) { TEST_ERROR (t, ("zero counter is not zero (infinite wait, %d)", i)); } nsync_counter_add (c, 0); } nsync_counter_free (c); } /* Verify the properties of a non-zero counter. */ static void test_counter_non_zero (testing t) { nsync_time start; nsync_time waited; nsync_time abs_deadline; nsync_counter c = nsync_counter_new (1); if (nsync_counter_value (c) != 1) { TEST_ERROR (t, ("counter is not 1 (test)")); } if (nsync_counter_wait (c, nsync_time_zero) != 1) { TEST_ERROR (t, ("counter is not 1 (poll)")); } start = nsync_time_now (); abs_deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (1000)); if (nsync_counter_wait (c, abs_deadline) != 1) { TEST_ERROR (t, ("counter is not 1 (1s wait)")); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("timed wait on non-zero counter returned too quickly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed wait on non-zero counter returned too slowly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_counter_add (c, -1) != 0) { TEST_ERROR (t, ("zero counter note is not 0 (add)")); } if (nsync_counter_value (c) != 0) { TEST_ERROR (t, ("zero counter note is not 0 (test)")); } if (nsync_counter_wait (c, nsync_time_zero) != 0) { TEST_ERROR (t, ("zero counter note is not 0 (poll)")); } if (nsync_counter_wait (c, nsync_time_no_deadline) != 0) { TEST_ERROR (t, ("zero counter note is not 0 (infinite wait)")); } nsync_counter_free (c); } static void decrement_at (nsync_counter c, nsync_time abs_deadline) { nsync_time_sleep_until (abs_deadline); nsync_counter_add (c, -1); } CLOSURE_DECL_BODY2 (decrement, nsync_counter, nsync_time) /* Test decrement of a counter. */ static void test_counter_decrement (testing t) { nsync_time start; nsync_time waited; nsync_counter c = nsync_counter_new (1); closure_fork (closure_decrement (&decrement_at, c, nsync_time_add (nsync_time_now (), nsync_time_ms (1000)))); start = nsync_time_now (); if (nsync_counter_wait (c, nsync_time_no_deadline) != 0) { TEST_ERROR (t, ("counter is not 0")); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("counter wait too fast (1s delay took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("counter wait too slow (1s delay took %s)", nsync_time_str (waited, 2))); } if (nsync_counter_value (c) != 0) { TEST_ERROR (t, ("counter is not 0 (test)")); } if (nsync_counter_wait (c, nsync_time_zero) != 0) { TEST_ERROR (t, ("counter is not 0 (poll)")); } if (nsync_counter_wait (c, nsync_time_no_deadline) != 0) { TEST_ERROR (t, ("counter is not 0 (infinite wait)")); } nsync_counter_free (c); c = nsync_counter_new (1); closure_fork (closure_decrement (&decrement_at, c, nsync_time_add (nsync_time_now (), nsync_time_ms (1000)))); start = nsync_time_now (); while (nsync_counter_value (c) != 0) { nsync_time_sleep (nsync_time_ms (10)); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("counter wait too fast (1s delay took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("counter wait too slow (1s delay took %s)", nsync_time_str (waited, 2))); } if (nsync_counter_value (c) != 0) { TEST_ERROR (t, ("counter is not 0 (test)")); } if (nsync_counter_wait (c, nsync_time_zero) != 0) { TEST_ERROR (t, ("counter is not 0 (poll)")); } if (nsync_counter_wait (c, nsync_time_no_deadline) != 0) { TEST_ERROR (t, ("counter is not 0 (infinite wait)")); } nsync_counter_free (c); } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_counter_zero); TEST_RUN (tb, test_counter_non_zero); TEST_RUN (tb, test_counter_decrement); return (testing_base_exit (tb)); } nsync-1.24.0/testing/cv_mu_timeout_stress_test.c000066400000000000000000000462161367521742200221140ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "nsync.h" #include "smprintf.h" #include "testing.h" #include "closure.h" NSYNC_CPP_USING_ /* A cv_stress_data represents the data used by the threads of the tests below. */ typedef struct cv_stress_data_s { nsync_mu mu; /* protects fields below */ uintmax_t count; /* incremented by the various threads */ uintmax_t timeouts; /* incremented on each timeout */ uintmax_t reader_loops; /* the number of loops executed by the reader threads, if any */ unsigned refs; /* ref count: one per normal test thread, decremented on its exit */ unsigned reader_refs; /* ref count: one per reader test thread, decremented on its exit */ int use_cv; /* threads are using CVs; under mu */ nsync_cv count_is_imod4[4]; /* element i signalled when count==i mod 4 if use_cv non-0. */ nsync_cv refs_is_zero; /* signalled when refs==0 */ nsync_cv reader_refs_is_zero; /* signalled when reader_refs==0 */ /* iterations per writer thread; under mu--increased until deadline exceeded */ uintmax_t loop_count; /* number of various types of thread to create -- r/o after init */ uintmax_t cv_threads_per_value; uintmax_t cv_reader_threads_per_value; uintmax_t mu_threads_per_value; uintmax_t mu_reader_threads_per_value; /* end times */ nsync_time deadline; /* r/o after init */ } cv_stress_data; /* --------------------------- */ /* The delays in cv_stress_inc_loop(), cv_stress_reader_loop(), mu_stress_inc_loop(), and mu_stress_reader_loop() are uniformly distributed from 0 to STRESS_MAX_DELAY_MICROS-1 microseconds. */ #define STRESS_MAX_DELAY_MICROS (4000) /* maximum delay */ #define STRESS_MEAN_DELAY_MICROS (STRESS_MAX_DELAY_MICROS / 2) /* mean delay */ #define STRESS_EXPECT_TIMEOUTS_PER_SEC (1000000 / STRESS_MEAN_DELAY_MICROS) /* expect timeouts/s*/ /* Acquire s.mu, then increment s.count n times, each time waiting until condition is true. Use a random delay between 0us and 999us for each wait; if the timeout expires, increment s.timeouts, and retry the wait. Decrement s.refs before the returning. */ static void cv_stress_inc_loop (cv_stress_data *s, uintmax_t count_imod4) { uintmax_t i; nsync_mu_lock (&s->mu); s->use_cv = 1; nsync_mu_assert_held (&s->mu); for (i = 0; i != s->loop_count; i++) { nsync_mu_assert_held (&s->mu); while ((s->count & 3) != count_imod4) { nsync_time abs_deadline; abs_deadline = nsync_time_add (nsync_time_now (), nsync_time_us (rand () % STRESS_MAX_DELAY_MICROS)); while (nsync_cv_wait_with_deadline ( &s->count_is_imod4[count_imod4], &s->mu, abs_deadline, NULL) != 0 && (s->count&3) != count_imod4) { nsync_mu_assert_held (&s->mu); s->timeouts++; nsync_mu_assert_held (&s->mu); abs_deadline = nsync_time_add (nsync_time_now (), nsync_time_us (rand () % STRESS_MAX_DELAY_MICROS)); } } nsync_mu_assert_held (&s->mu); s->count++; nsync_cv_signal (&s->count_is_imod4[s->count&3]); } s->refs--; if (s->refs == 0) { if (s->reader_refs != 0) { /* wake any readers so they will exit */ for (i = 0; i != 4; i++) { nsync_cv_broadcast (&s->count_is_imod4[i]); } } nsync_cv_signal (&s->refs_is_zero); } nsync_mu_assert_held (&s->mu); nsync_mu_unlock (&s->mu); } CLOSURE_DECL_BODY2 (cv_stress_inc_loop, cv_stress_data *, uintmax_t) /* Acquires s.u in reader mode, and wait until a condition is true or a timeout occurs on a random wait between 0us and 999us, repeatedly. Every 16 times, release the reader lock, but immediately reacquire it. Once the count of threads running cv_stress_inc_loop() reaches zero (s.refs == 0), sum the number of loops complete into s.reader_loops, and the number of timeouts experience into s.timeouts. Then decrement s.reader_refs before returning. */ static void cv_stress_reader_loop (cv_stress_data *s, uintmax_t count_imod4) { uintmax_t loops; uintmax_t timeouts = 0; nsync_mu_lock (&s->mu); s->use_cv = 1; nsync_mu_unlock (&s->mu); nsync_mu_rlock (&s->mu); nsync_mu_rassert_held (&s->mu); loops = 0; while (s->refs != 0) { nsync_mu_rassert_held (&s->mu); while ((s->count&3) != count_imod4 && s->refs != 0) { nsync_time abs_deadline; abs_deadline = nsync_time_add (nsync_time_now (), nsync_time_us (rand () % STRESS_MAX_DELAY_MICROS)); while (nsync_cv_wait_with_deadline (&s->count_is_imod4[count_imod4], &s->mu, abs_deadline, NULL) != 0 && (s->count&3) != count_imod4 && s->refs != 0) { nsync_mu_rassert_held (&s->mu); timeouts++; abs_deadline = nsync_time_add (nsync_time_now (), nsync_time_us (rand () % STRESS_MAX_DELAY_MICROS)); } } nsync_mu_rassert_held (&s->mu); loops++; if ((loops & 0xf) == 0) { nsync_mu_runlock (&s->mu); if ((loops & 0xfff) == 0) { nsync_time_sleep (nsync_time_ms (1)); } nsync_mu_rlock (&s->mu); } } nsync_mu_rassert_held (&s->mu); nsync_mu_runlock (&s->mu); nsync_mu_lock (&s->mu); s->reader_loops += loops; s->timeouts += timeouts; s->reader_refs--; if (s->reader_refs == 0) { nsync_cv_signal (&s->reader_refs_is_zero); } nsync_mu_assert_held (&s->mu); nsync_mu_unlock (&s->mu); } CLOSURE_DECL_BODY2 (cv_stress_reader_loop, cv_stress_data *, uintmax_t) /* --------------------------- */ /* These tests use the data structure cv_stress_data defined above. One test uses nsync_mu and nsync_cv, one nsync_mu and its conditional critical sections, while a third mixes conditional critical sections and condition variables; they all the routines above */ /* --------------------------- The various conditions that threads wait for on cv_stress_data. */ static int count_is0mod4 (const void *v) { const cv_stress_data *s = (const cv_stress_data *) v; nsync_mu_rassert_held (&s->mu); return ((s->count & 3) == 0); } static int count_is1mod4 (const void *v) { const cv_stress_data *s = (const cv_stress_data *) v; nsync_mu_rassert_held (&s->mu); return ((s->count & 3) == 1); } static int count_is2mod4 (const void *v) { const cv_stress_data *s = (const cv_stress_data *) v; nsync_mu_rassert_held (&s->mu); return ((s->count & 3) == 2); } static int count_is3mod4 (const void *v) { const cv_stress_data *s = (const cv_stress_data *) v; nsync_mu_rassert_held (&s->mu); return ((s->count & 3) == 3); } static int count_is0mod4or_refs_is0 (const void *v) { const cv_stress_data *s = (const cv_stress_data *) v; nsync_mu_rassert_held (&s->mu); return ((s->count&3) == 0 || s->refs == 0); } static int count_is1mod4or_refs_is0 (const void *v) { const cv_stress_data *s = (const cv_stress_data *) v; nsync_mu_rassert_held (&s->mu); return ((s->count&3) == 1 || s->refs == 0); } static int count_is2mod4or_refs_is0 (const void *v) { const cv_stress_data *s = (const cv_stress_data *) v; nsync_mu_rassert_held (&s->mu); return ((s->count&3) == 2 || s->refs == 0); } static int count_is3mod4or_refs_is0 (const void *v) { const cv_stress_data *s = (const cv_stress_data *) v; nsync_mu_rassert_held (&s->mu); return ((s->count&3) == 3 || s->refs == 0); } /* --------------------------- */ typedef int (*condition_func) (const void *); /* Acquire s.mu, then increment s.count n times, each time waiting until condition is true. Use a random delay between 0us and 999us for each wait; if the timeout expires, increment s.timeouts, and the retry the wait. Decrement s.refs before returning. */ static void mu_stress_inc_loop (cv_stress_data *s, condition_func condition, const void *condition_arg) { uintmax_t i; nsync_mu_lock (&s->mu); nsync_mu_assert_held (&s->mu); for (i = 0; i != s->loop_count; i++) { nsync_time abs_deadline; nsync_mu_assert_held (&s->mu); abs_deadline = nsync_time_add (nsync_time_now (), nsync_time_us (rand () % STRESS_MAX_DELAY_MICROS)); while (nsync_mu_wait_with_deadline (&s->mu, condition, condition_arg, NULL, abs_deadline, NULL) != 0) { nsync_mu_assert_held (&s->mu); s->timeouts++; nsync_mu_assert_held (&s->mu); abs_deadline = nsync_time_add (nsync_time_now (), nsync_time_us (rand () % STRESS_MAX_DELAY_MICROS)); } nsync_mu_assert_held (&s->mu); s->count++; if (s->use_cv) { nsync_cv_signal (&s->count_is_imod4[s->count&3]); } } s->refs--; if (s->refs == 0) { if (s->use_cv && s->reader_refs != 0) { /* wake any readers so they will exit */ for (i = 0; i != 4; i++) { nsync_cv_broadcast (&s->count_is_imod4[i]); } } nsync_cv_signal (&s->refs_is_zero); } nsync_mu_assert_held (&s->mu); nsync_mu_unlock (&s->mu); } CLOSURE_DECL_BODY3 (mu_stress_inc_loop, cv_stress_data *, condition_func, const void *) /* Acquire s.u in reader mode, and wait until a condition is true or a timeout occurs on a random wait between 0us and 999us, repeatedly. Every 16 times, release the reader lock, but immediately reacquire it. Once the count of threads running mu_stress_inc_loop() reaches zero (s.refs == 0), sum the number of loops completed into s.reader_loops, and the number of timeouts it experienced into s.timeouts. Then decrement s.reader_refs before returning. */ static void mu_stress_reader_loop (cv_stress_data *s, condition_func condition, const void *condition_arg) { uintmax_t loops; uintmax_t timeouts = 0; nsync_mu_rlock (&s->mu); nsync_mu_rassert_held (&s->mu); loops = 0; while (s->refs != 0) { nsync_time abs_deadline; nsync_mu_rassert_held (&s->mu); abs_deadline = nsync_time_add (nsync_time_now (), nsync_time_us (rand () % STRESS_MAX_DELAY_MICROS)); while (nsync_mu_wait_with_deadline (&s->mu, condition, condition_arg, NULL, abs_deadline, NULL) != 0) { nsync_mu_rassert_held (&s->mu); s->timeouts++; nsync_mu_rassert_held (&s->mu); abs_deadline = nsync_time_add (nsync_time_now (), nsync_time_us (rand () % STRESS_MAX_DELAY_MICROS)); } nsync_mu_rassert_held (&s->mu); loops++; if ((loops & 0xf) == 0) { nsync_mu_runlock (&s->mu); if ((loops & 0xfff) == 0) { nsync_time_sleep (nsync_time_ms (1)); } nsync_mu_rlock (&s->mu); } } nsync_mu_rassert_held (&s->mu); nsync_mu_runlock (&s->mu); nsync_mu_lock (&s->mu); s->reader_loops += loops; s->timeouts += timeouts; s->reader_refs--; if (s->reader_refs == 0) { nsync_cv_signal (&s->reader_refs_is_zero); } nsync_mu_assert_held (&s->mu); nsync_mu_unlock (&s->mu); } CLOSURE_DECL_BODY3 (mu_stress_reader_loop, cv_stress_data *, condition_func, const void *) static const condition_func is_n_mod_4[] = { &count_is0mod4, &count_is1mod4, &count_is2mod4, &count_is3mod4 }; static const condition_func is_n_mod_4_or_refs0[] = { &count_is0mod4or_refs_is0, &count_is1mod4or_refs_is0, &count_is2mod4or_refs_is0, &count_is3mod4or_refs_is0 }; /* Create cv_threads_per_value threads using cv_stress_inc_loop(), and mu_threads_per_value threads using mu_stress_inc_loop(), all trying to increment s.count from 1 to 2 mod 4, plus the same from 2 to 3 mod 4, and again from 3 to 0 mod 4, using random delays in their waits. Sleep a few seconds, ensuring many random timeouts by these threads, because there is no thread incrementing s.count from 0 (which is 0 mod 4). Then create cv_threads_per_value threads using cv_stress_inc_loop(), and mu_threads_per_value threads using mu_stress_inc_loop(), all trying to increment s.count from 0 to 1 mod 4. This allows all the threads to run to completion, since there are equal numbers for each condition. At the same time, create cv_reader_threads_per_value threads using cv_stress_reader_loop and mu_reader_threads_per_value using mu_stress_reader_loop, for each of the transitions 0 to 1, 1, to 2, 2 to 3, and 3 to 0 mod 4. All these loops count how many timeouts they encounter. The reader loops count how many times they manage to run. These counts are tested against expected values. Finally, it waits for all threads to exit. It returns whether the deadlie has expired. */ static int run_stress_test (cv_stress_data *s, testing t, const char *test_name) { int done = 0; uintmax_t expected_timeouts; uintmax_t timeouts_seen; uintmax_t expected_count; uintmax_t i; static const int sleep_seconds = 1; nsync_mu_lock (&s->mu); nsync_mu_assert_held (&s->mu); /* Create threads trying to increment from 1, 2, and 3 mod 4. They will continually hit their timeouts because s.count==0 */ for (i = 0; i != s->cv_threads_per_value; i++) { nsync_mu_assert_held (&s->mu); s->refs++; closure_fork (closure_cv_stress_inc_loop (&cv_stress_inc_loop, s, 1)); s->refs++; closure_fork (closure_cv_stress_inc_loop (&cv_stress_inc_loop, s, 2)); s->refs++; closure_fork (closure_cv_stress_inc_loop (&cv_stress_inc_loop, s, 3)); } for (i = 0; i != s->cv_reader_threads_per_value; i++) { nsync_mu_assert_held (&s->mu); s->reader_refs++; closure_fork (closure_cv_stress_reader_loop (&cv_stress_reader_loop, s, 1)); s->reader_refs++; closure_fork (closure_cv_stress_reader_loop (&cv_stress_reader_loop, s, 2)); s->reader_refs++; closure_fork (closure_cv_stress_reader_loop (&cv_stress_reader_loop, s, 3)); } for (i = 0; i != s->mu_threads_per_value; i++) { nsync_mu_assert_held (&s->mu); s->refs++; closure_fork (closure_mu_stress_inc_loop (&mu_stress_inc_loop, s, is_n_mod_4[1], s)); s->refs++; closure_fork (closure_mu_stress_inc_loop (&mu_stress_inc_loop, s, is_n_mod_4[2], s)); s->refs++; closure_fork (closure_mu_stress_inc_loop (&mu_stress_inc_loop, s, is_n_mod_4[3], s)); } for (i = 0; i != s->mu_reader_threads_per_value; i++) { nsync_mu_assert_held (&s->mu); s->reader_refs++; closure_fork (closure_mu_stress_reader_loop (&mu_stress_reader_loop, s, is_n_mod_4_or_refs0[1], s)); s->reader_refs++; closure_fork (closure_mu_stress_reader_loop (&mu_stress_reader_loop, s, is_n_mod_4_or_refs0[2], s)); s->reader_refs++; closure_fork (closure_mu_stress_reader_loop (&mu_stress_reader_loop, s, is_n_mod_4_or_refs0[3], s)); } nsync_mu_assert_held (&s->mu); nsync_mu_unlock (&s->mu); /* Sleep a while to cause many timeouts. */ nsync_time_sleep (nsync_time_ms (sleep_seconds * 1000)); nsync_mu_lock (&s->mu); nsync_mu_assert_held (&s->mu); /* Check that approximately the right number of timeouts have occurred. The 3 below is the three classes of thread produced before the Sleep(). The factor of 1/8 is to allow for randomness and slow test machines. */ expected_timeouts = (s->cv_threads_per_value + s->mu_threads_per_value) * 3 * sleep_seconds * STRESS_EXPECT_TIMEOUTS_PER_SEC / 8; timeouts_seen = s->timeouts; /* actual check is below. */ /* Create the threads that increment from 0 mod 4. s.count will then be incremented. */ for (i = 0; i != s->cv_threads_per_value; i++) { nsync_mu_assert_held (&s->mu); s->refs++; closure_fork (closure_cv_stress_inc_loop (&cv_stress_inc_loop, s, 0)); } for (i = 0; i != s->cv_reader_threads_per_value; i++) { nsync_mu_assert_held (&s->mu); s->reader_refs++; closure_fork (closure_cv_stress_reader_loop (&cv_stress_reader_loop, s, 0)); } for (i = 0; i != s->mu_threads_per_value; i++) { nsync_mu_assert_held (&s->mu); s->refs++; closure_fork (closure_mu_stress_inc_loop (&mu_stress_inc_loop, s, is_n_mod_4[0], s)); } for (i = 0; i != s->mu_reader_threads_per_value; i++) { nsync_mu_assert_held (&s->mu); s->reader_refs++; closure_fork (closure_mu_stress_reader_loop (&mu_stress_reader_loop, s, is_n_mod_4_or_refs0[0], s)); } /* wait for threads to exit. */ nsync_mu_assert_held (&s->mu); while (s->refs != 0) { nsync_cv_wait (&s->refs_is_zero, &s->mu); } while (s->reader_refs != 0) { nsync_cv_wait (&s->reader_refs_is_zero, &s->mu); } nsync_mu_assert_held (&s->mu); nsync_mu_unlock (&s->mu); if (nsync_time_cmp (s->deadline, nsync_time_now ()) < 0) { if (timeouts_seen < expected_timeouts && !testing_is_uniprocessor (t)) { TEST_ERROR (t, ("%s: expected more than %d timeouts, got %d", test_name, expected_timeouts, timeouts_seen)); } /* Check that s.count has the right value. */ expected_count = s->loop_count * (s->cv_threads_per_value + s->mu_threads_per_value) * 4; if (s->count != expected_count) { TEST_ERROR (t, ("%s: expected to increment s->count to %d, got %d", test_name, expected_count, s->count)); } /* Some timeouts should have happened while the counts were being incremented. */ expected_timeouts = timeouts_seen + 1; if (s->timeouts < expected_timeouts) { TEST_ERROR (t, ("%s: expected more than %d timeouts, got %d", test_name, expected_timeouts, s->timeouts)); } done = 1; } return (done); } /* Test many threads using a single lock, using condition variables and timeouts. See run_stress_test() for details. */ static void test_cv_timeout_stress (testing t) { uintmax_t loop_count = 3; cv_stress_data s; nsync_time deadline; deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (5000)); do { memset ((void *) &s, 0, sizeof (s)); s.loop_count = loop_count; s.cv_threads_per_value = 4; s.cv_reader_threads_per_value = 2; s.mu_threads_per_value = 0; s.mu_reader_threads_per_value = 0; s.deadline = deadline; loop_count *= 2; } while (!run_stress_test (&s, t, "test_cv_timeout_stress")); } /* Test many threads using a single lock, using conditional critical sections and timeouts. See run_stress_test() for details. */ static void test_mu_timeout_stress (testing t) { uintmax_t loop_count = 3; cv_stress_data s; nsync_time deadline; deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (5000)); do { memset ((void *) &s, 0, sizeof (s)); s.loop_count = loop_count; s.cv_threads_per_value = 0; s.cv_reader_threads_per_value = 0; s.mu_threads_per_value = 4; s.mu_reader_threads_per_value = 2; s.deadline = deadline; loop_count *= 2; } while (!run_stress_test (&s, t, "test_mu_timeout_stress")); } /* Like test_mu_timeout_stress() but has both threads that use conditional critical sections and threads that use condition variables, to ensure that they work together. */ static void test_mu_cv_timeout_stress (testing t) { uintmax_t loop_count = 3; cv_stress_data s; nsync_time deadline; deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (5000)); do { memset ((void *) &s, 0, sizeof (s)); s.loop_count = loop_count; s.cv_threads_per_value = 4; s.cv_reader_threads_per_value = 1; s.mu_threads_per_value = 4; s.mu_reader_threads_per_value = 1; s.deadline = deadline; loop_count *= 2; } while (!run_stress_test (&s, t, "test_mu_cv_timeout_stress")); } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_cv_timeout_stress); TEST_RUN (tb, test_mu_timeout_stress); TEST_RUN (tb, test_mu_cv_timeout_stress); return (testing_base_exit (tb)); } nsync-1.24.0/testing/cv_test.c000066400000000000000000000651071367521742200162420ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "nsync.h" #include "time_extra.h" #include "smprintf.h" #include "testing.h" #include "closure.h" NSYNC_CPP_USING_ /* --------------------------- */ /* A cv_queue represents a FIFO queue with up to limit elements. The storage for the queue expands as necessary up to limit. */ typedef struct cv_queue_s { int limit; /* max value of count---should not be changed after initialization */ nsync_cv non_empty; /* signalled when count transitions from zero to non-zero */ nsync_cv non_full; /* signalled when count transitions from limit to less than limit */ nsync_mu mu; /* protects fields below */ int pos; /* index of first in-use element */ int count; /* number of elements in use */ void *data[1]; /* in use elements are data[pos, ..., (pos+count-1)%limit] */ } cv_queue; /* Return a pointer to new cv_queue. */ static cv_queue *cv_queue_new (int limit) { cv_queue *q; int size = offsetof (struct cv_queue_s, data) + sizeof (q->data[0]) * limit; q = (cv_queue *) malloc (size); memset ((void *) q, 0, size); q->limit = limit; return (q); } /* Add v to the end of the FIFO *q and return non-zero, or if the FIFO already has limit elements and continues to do so until abs_deadline, do nothing and return 0. */ static int cv_queue_put (cv_queue *q, void *v, nsync_time abs_deadline) { int added = 0; int wake = 0; nsync_mu_lock (&q->mu); while (q->count == q->limit && nsync_cv_wait_with_deadline (&q->non_full, &q->mu, abs_deadline, NULL) == 0) { } if (q->count != q->limit) { int i = q->pos + q->count; if (q->limit <= i) { i -= q->limit; } q->data[i] = v; if (q->count == 0) { wake = 1; } q->count++; added = 1; } nsync_mu_unlock (&q->mu); if (wake) { nsync_cv_broadcast (&q->non_empty); } return (added); } /* Remove the first value from the front of the FIFO *q and return it, or if the FIFO is empty and continues to be so until abs_deadline, do nothing and return NULL. */ static void *cv_queue_get (cv_queue *q, nsync_time abs_deadline) { void *v = NULL; nsync_mu_lock (&q->mu); while (q->count == 0 && nsync_cv_wait_with_deadline (&q->non_empty, &q->mu, abs_deadline, NULL) == 0) { } if (q->count != 0) { v = q->data[q->pos]; q->data[q->pos] = NULL; if (q->count == q->limit) { nsync_cv_broadcast (&q->non_full); } q->pos++; q->count--; if (q->pos == q->limit) { q->pos = 0; } } nsync_mu_unlock (&q->mu); return (v); } /* --------------------------- */ static char ptr_to_int_c; #define INT_TO_PTR(x) ((x) + &ptr_to_int_c) #define PTR_TO_INT(p) (((char *) (p)) - &ptr_to_int_c) /* Put count integers on *q, in the sequence start*3, (start+1)*3, (start+2)*3, .... */ static void producer_cv_n (testing t, cv_queue *q, int start, int count) { int i; for (i = 0; i != count; i++) { if (!cv_queue_put (q, INT_TO_PTR ((start+i)*3), nsync_time_no_deadline)) { TEST_FATAL (t, ("cv_queue_put() returned 0 with no deadline")); } } } CLOSURE_DECL_BODY4 (producer_cv_n, testing, cv_queue *, int, int) /* Get count integers from *q, and check that they are in the sequence start*3, (start+1)*3, (start+2)*3, .... */ static void consumer_cv_n (testing t, cv_queue *q, int start, int count) { int i; for (i = 0; i != count; i++) { void *v = cv_queue_get (q, nsync_time_no_deadline); int x; if (v == NULL) { TEST_FATAL (t, ("cv_queue_get() returned NULL with no deadline")); } x = PTR_TO_INT (v); if (x != (start+i)*3) { TEST_FATAL (t, ("cv_queue_get() returned bad value; want %d, got %d", (start+i)*3, x)); } } } /* CV_PRODUCER_CONSUMER_N is the number of elements passed from producer to consumer in the test_cv_producer_consumer*() tests below. */ #define CV_PRODUCER_CONSUMER_N 100000 /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**0. */ static void test_cv_producer_consumer0 (testing t) { cv_queue *q = cv_queue_new (1); closure_fork (closure_producer_cv_n (&producer_cv_n, t, q, 0, CV_PRODUCER_CONSUMER_N)); consumer_cv_n (t, q, 0, CV_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**1. */ static void test_cv_producer_consumer1 (testing t) { cv_queue *q = cv_queue_new (10); closure_fork (closure_producer_cv_n (&producer_cv_n, t, q, 0, CV_PRODUCER_CONSUMER_N)); consumer_cv_n (t, q, 0, CV_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**2. */ static void test_cv_producer_consumer2 (testing t) { cv_queue *q = cv_queue_new (100); closure_fork (closure_producer_cv_n (&producer_cv_n, t, q, 0, CV_PRODUCER_CONSUMER_N)); consumer_cv_n (t, q, 0, CV_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**3. */ static void test_cv_producer_consumer3 (testing t) { cv_queue *q = cv_queue_new (1000); closure_fork (closure_producer_cv_n (&producer_cv_n, t, q, 0, CV_PRODUCER_CONSUMER_N)); consumer_cv_n (t, q, 0, CV_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**4. */ static void test_cv_producer_consumer4 (testing t) { cv_queue *q = cv_queue_new (10 * 1000); closure_fork (closure_producer_cv_n (&producer_cv_n, t, q, 0, CV_PRODUCER_CONSUMER_N)); consumer_cv_n (t, q, 0, CV_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**5. */ static void test_cv_producer_consumer5 (testing t) { cv_queue *q = cv_queue_new (100 * 1000); closure_fork (closure_producer_cv_n (&producer_cv_n, t, q, 0, CV_PRODUCER_CONSUMER_N)); consumer_cv_n (t, q, 0, CV_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**6. */ static void test_cv_producer_consumer6 (testing t) { cv_queue *q = cv_queue_new (1000 * 1000); closure_fork (closure_producer_cv_n (&producer_cv_n, t, q, 0, CV_PRODUCER_CONSUMER_N)); consumer_cv_n (t, q, 0, CV_PRODUCER_CONSUMER_N); free (q); } /* The following values control how aggressively we police the timeout. */ #define TOO_EARLY_MS 1 #define TOO_LATE_MS 100 /* longer, to accommodate scheduling delays */ #define TOO_LATE_ALLOWED 25 /* number of iterations permitted to violate too_late */ /* Check timeouts on a CV wait_with_deadline(). */ static void test_cv_deadline (testing t) { int too_late_violations; nsync_mu mu; nsync_cv cv; int i; nsync_time too_early; nsync_time too_late; nsync_mu_init (&mu); nsync_cv_init (&cv); too_early = nsync_time_ms (TOO_EARLY_MS); too_late = nsync_time_ms (TOO_LATE_MS); too_late_violations = 0; nsync_mu_lock (&mu); for (i = 0; i != 50; i++) { nsync_time end_time; nsync_time start_time; nsync_time expected_end_time; start_time = nsync_time_now (); expected_end_time = nsync_time_add (start_time, nsync_time_ms (87)); if (nsync_cv_wait_with_deadline (&cv, &mu, expected_end_time, NULL) != ETIMEDOUT) { TEST_FATAL (t, ("nsync_cv_wait() returned non-expired for a timeout")); } end_time = nsync_time_now (); if (nsync_time_cmp (end_time, nsync_time_sub (expected_end_time, too_early)) < 0) { char *elapsed_str = nsync_time_str (nsync_time_sub (expected_end_time, end_time), 2); TEST_ERROR (t, ("nsync_cv_wait() returned %s too early", elapsed_str)); free (elapsed_str); } if (nsync_time_cmp (nsync_time_add (expected_end_time, too_late), end_time) < 0) { too_late_violations++; } } nsync_mu_unlock (&mu); if (too_late_violations > TOO_LATE_ALLOWED) { TEST_ERROR (t, ("nsync_cv_wait() returned too late %d times", too_late_violations)); } } /* Check cancellations with nsync_cv_wait_with_deadline(). */ static void test_cv_cancel (testing t) { nsync_time future_time; int too_late_violations; nsync_mu mu; nsync_cv cv; int i; nsync_time too_early; nsync_time too_late; nsync_mu_init (&mu); nsync_cv_init (&cv); too_early = nsync_time_ms (TOO_EARLY_MS); too_late = nsync_time_ms (TOO_LATE_MS); /* The loops below cancel after 87 milliseconds, like the timeout tests above. */ future_time = nsync_time_add (nsync_time_now (), nsync_time_ms (3600000)); /* test cancels with timeout */ too_late_violations = 0; nsync_mu_lock (&mu); for (i = 0; i != 50; i++) { int x; nsync_note cancel; nsync_time end_time; nsync_time start_time; nsync_time expected_end_time; start_time = nsync_time_now (); expected_end_time = nsync_time_add (start_time, nsync_time_ms (87)); cancel = nsync_note_new (NULL, expected_end_time); x = nsync_cv_wait_with_deadline (&cv, &mu, future_time, cancel); if (x != ECANCELED) { TEST_FATAL (t, ("nsync_cv_wait() returned non-cancelled (%d) for " "a cancellation; expected %d", x, ECANCELED)); } end_time = nsync_time_now (); if (nsync_time_cmp (end_time, nsync_time_sub (expected_end_time, too_early)) < 0) { char *elapsed_str = nsync_time_str (nsync_time_sub (expected_end_time, end_time), 2); TEST_ERROR (t, ("nsync_cv_wait() returned %s too early", elapsed_str)); free (elapsed_str); } if (nsync_time_cmp (nsync_time_add (expected_end_time, too_late), end_time) < 0) { too_late_violations++; } /* Check that an already cancelled wait returns immediately. */ start_time = nsync_time_now (); x = nsync_cv_wait_with_deadline (&cv, &mu, nsync_time_no_deadline, cancel); if (x != ECANCELED) { TEST_FATAL (t, ("nsync_cv_wait() returned non-cancelled (%d) for " "a cancellation; expected %d", x, ECANCELED)); } end_time = nsync_time_now (); if (nsync_time_cmp (end_time, start_time) < 0) { char *elapsed_str = nsync_time_str (nsync_time_sub (expected_end_time, end_time), 2); TEST_ERROR (t, ("nsync_cv_wait() returned %s too early", elapsed_str)); free (elapsed_str); } if (nsync_time_cmp (nsync_time_add (start_time, too_late), end_time) < 0) { too_late_violations++; } nsync_note_notify (cancel); nsync_note_free (cancel); } nsync_mu_unlock (&mu); if (too_late_violations > TOO_LATE_ALLOWED) { TEST_ERROR (t, ("nsync_cv_wait() returned too late %d times", too_late_violations)); } } /* --------------------------- */ /* Names of debug results for test_cv_debug. */ static const char *result_name[] = { "init_mu0", "init_cv0", "init_mu1", "init_cv1", "init_mu2", "init_cv2", "held_mu", "wait0_mu", "wait0_cv", "wait1_mu", "wait1_cv", "wait2_mu", "wait2_cv", "wait3_mu", "wait3_cv", "rheld1_mu", "rheld2_mu", "rheld1again_mu", NULL /* sentinel */ }; /* state for test_cv_debug() */ struct debug_state { nsync_mu mu; /* protects flag field */ nsync_cv cv; /* signalled when flag becomes zero */ int flag; /* 0 => threads proceed; non-zero => threads block */ /* result[] is an array of nul-terminated string values, accessed via name (in result_name[]) via slot(). Entries accessed from multiple threads are protected by result_mu. */ char *result[sizeof (result_name) / sizeof (result_name[0])]; nsync_mu result_mu; }; /* Return a pointer to the slot in s->result[] associated with the nul-terminated name[] */ static char **slot (struct debug_state *s, const char *name) { int i = 0; while (result_name[i] != NULL && strcmp (result_name[i], name) != 0) { i++; } if (result_name[i] == NULL) { /* caller gave non-existent name */ abort (); } return (&s->result[i]); } /* Check that the strings associated with nul-terminated strings name0[] and name1[] have the same values in s->result[]. */ static void check_same (testing t, struct debug_state *s, const char *name0, const char *name1) { if (strcmp (*slot (s, name0), *slot (s, name1)) != 0) { TEST_ERROR (t, ("nsync_mu_debug_state() %s state != %s state (%s vs. %s)", name0, name1, *slot (s, name0), *slot (s, name1))); } } /* Check that the strings associated with nul-terminated strings name0[] and name1[] have different values in s->result[]. */ static void check_different (testing t, struct debug_state *s, const char *name0, const char *name1) { if (strcmp (*slot (s, name0), *slot (s, name1)) == 0) { TEST_ERROR (t, ("nsync_mu_debug_state() %s state == %s state", name0, name1)); } } /* Return whether the integer at address v is zero. */ static int int_is_zero (const void *v) { return (*(int *)v == 0); } /* Acquire and release s->mu in write mode, waiting for s->flag==0 using nsync_mu_wait(). */ static void debug_thread_writer (struct debug_state *s) { nsync_mu_lock (&s->mu); nsync_mu_wait (&s->mu, &int_is_zero, &s->flag, NULL); nsync_mu_unlock (&s->mu); } /* Acquire and release s->mu in write mode, waiting for s->flag==0 using nsync_cv_wait(). */ static void debug_thread_writer_cv (struct debug_state *s) { nsync_mu_lock (&s->mu); while (s->flag != 0) { nsync_cv_wait (&s->cv, &s->mu); } nsync_mu_unlock (&s->mu); } /* Acquire and release s->mu in read mode, waiting for s->flag==0 using nsync_mu_wait(). If name!=NULL, record state of s->mu while held using name[]. */ static void debug_thread_reader (struct debug_state *s, const char *name) { nsync_mu_rlock (&s->mu); nsync_mu_wait (&s->mu, &int_is_zero, &s->flag, NULL); if (name != NULL) { int len = 1024; nsync_mu_lock (&s->result_mu); *slot (s, name) = nsync_mu_debug_state_and_waiters ( &s->mu, (char *) malloc (len), len); nsync_mu_unlock (&s->result_mu); } nsync_mu_runlock (&s->mu); } /* Acquire and release s->mu in read mode, waiting for s->flag==0 using nsync_cv_wait(). If name!=NULL, record state of s->mu while held using name[]. */ static void debug_thread_reader_cv (struct debug_state *s, const char *name) { nsync_mu_rlock (&s->mu); while (s->flag != 0) { nsync_cv_wait (&s->cv, &s->mu); } if (name != NULL) { int len = 1024; nsync_mu_lock (&s->result_mu); *slot (s, name) = nsync_mu_debug_state_and_waiters ( &s->mu, (char *) malloc (len), len); nsync_mu_unlock (&s->result_mu); } nsync_mu_runlock (&s->mu); } CLOSURE_DECL_BODY1 (debug_thread, struct debug_state *) CLOSURE_DECL_BODY2 (debug_thread_reader, struct debug_state *, const char *) /* Check that nsync_mu_debug_state() and nsync_cv_debug_state() and their variants yield reasonable results. The specification of those routines is intentionally loose, so this do not check much, but the various possibilities can be examined using the verbose testing flag (-v). */ static void test_cv_debug (testing t) { int i; int len = 1024; char *tmp; char *buf; int buflen; struct debug_state xs; struct debug_state *s = &xs; memset ((void *) s, 0, sizeof (*s)); /* Use nsync_*_debugger to check that they work. */ tmp = nsync_mu_debugger (&s->mu); buflen = strlen (tmp)+1; buf = (char *) malloc (buflen); snprintf (buf, buflen, "%s", tmp); *slot (s, "init_mu0") = buf; tmp = nsync_cv_debugger (&s->cv); buflen = strlen (tmp)+1; buf = (char *) malloc (buflen); snprintf (buf, buflen, "%s", tmp); *slot (s, "init_cv0") = buf; /* Get the same information via the other routines */ *slot (s, "init_mu1") = nsync_mu_debug_state ( &s->mu, (char *) malloc (len), len); *slot (s, "init_cv1") = nsync_cv_debug_state ( &s->cv, (char *) malloc (len), len); *slot (s, "init_mu2") = nsync_mu_debug_state_and_waiters ( &s->mu, (char *) malloc (len), len); *slot (s, "init_cv2") = nsync_cv_debug_state_and_waiters ( &s->cv, (char *) malloc (len), len); nsync_mu_lock (&s->mu); *slot (s, "held_mu") = nsync_mu_debug_state_and_waiters ( &s->mu, (char *) malloc (len), len); nsync_mu_unlock (&s->mu); /* set up several threads waiting on the mutex */ nsync_mu_lock (&s->mu); s->flag = 1; /* so thread will block on conditions */ closure_fork (closure_debug_thread (&debug_thread_writer, s)); closure_fork (closure_debug_thread (&debug_thread_writer, s)); closure_fork (closure_debug_thread (&debug_thread_writer, s)); closure_fork (closure_debug_thread_reader (&debug_thread_reader, s, NULL)); closure_fork (closure_debug_thread (&debug_thread_writer_cv, s)); closure_fork (closure_debug_thread (&debug_thread_writer_cv, s)); closure_fork (closure_debug_thread (&debug_thread_writer_cv, s)); closure_fork (closure_debug_thread_reader (&debug_thread_reader_cv, s, NULL)); nsync_time_sleep (nsync_time_ms (500)); *slot (s, "wait0_mu") = nsync_mu_debug_state_and_waiters ( &s->mu, (char *) malloc (len), len); *slot (s, "wait0_cv") = nsync_cv_debug_state_and_waiters ( &s->cv, (char *) malloc (len), len); /* allow the threads to proceed to their conditional waits */ nsync_mu_unlock (&s->mu); nsync_time_sleep (nsync_time_ms (500)); *slot (s, "wait1_mu") = nsync_mu_debug_state_and_waiters ( &s->mu, (char *) malloc (len), len); *slot (s, "wait1_cv") = nsync_cv_debug_state_and_waiters ( &s->cv, (char *) malloc (len), len); nsync_mu_lock (&s->mu); /* move cv waiters to mutex queue */ nsync_cv_broadcast (&s->cv); *slot (s, "wait2_mu") = nsync_mu_debug_state_and_waiters ( &s->mu, (char *) malloc (len), len); *slot (s, "wait2_cv") = nsync_cv_debug_state_and_waiters ( &s->cv, (char *) malloc (len), len); /* allow all threads to proceed and exit */ s->flag = 0; nsync_mu_unlock (&s->mu); nsync_time_sleep (nsync_time_ms (500)); *slot (s, "wait3_mu") = nsync_mu_debug_state_and_waiters ( &s->mu, (char *) malloc (len), len); *slot (s, "wait3_cv") = nsync_cv_debug_state_and_waiters ( &s->cv, (char *) malloc (len), len); /* Test with more than one reader */ nsync_mu_rlock (&s->mu); *slot (s, "rheld1_mu") = nsync_mu_debug_state_and_waiters ( &s->mu, (char *) malloc (len), len); closure_fork (closure_debug_thread_reader ( &debug_thread_reader, s, "rheld2_mu")); nsync_time_sleep (nsync_time_ms (500)); *slot (s, "rheld1again_mu") = nsync_mu_debug_state_and_waiters ( &s->mu, (char *) malloc (len), len); nsync_mu_runlock (&s->mu); check_same (t, s, "init_mu0", "init_mu1"); check_same (t, s, "init_mu0", "init_mu2"); check_same (t, s, "init_cv0", "init_cv1"); check_same (t, s, "init_cv0", "init_cv2"); check_different (t, s, "init_mu0", "held_mu"); check_different (t, s, "rheld1_mu", "held_mu"); /* Must acquire result_mu, because the "rheld2_mu" slot is accessed from the debug_thread_reader() thread created above. */ nsync_mu_lock (&s->result_mu); check_different (t, s, "rheld1_mu", "rheld2_mu"); nsync_mu_unlock (&s->result_mu); check_different (t, s, "init_mu0", "init_cv0"); for (i = 0; result_name[i] != NULL; i++) { if (testing_verbose (t)) { const char *str = *slot (s, result_name[i]); TEST_LOG (t, ("%-16s %s\n", result_name[i], str)); } if (strlen (s->result[i]) == 0) { TEST_ERROR (t, ("nsync_mu_debug_state() %s empty", result_name[i])); } free (s->result[i]); } } /* --------------------------- */ /* Max number of waiter threads used in transfer test. The last uses a conditional critical section, and others use a condition variable. */ #define TRANSFER_MAX_WAITERS 8 /* A struct cv_transfer is used to test cv-to-mu thread transfer. There are up to TRANSFER_MAX_WAITERS waiter threads, and a wakeup thread. Some threads wait using conditional critical sections, and others using a condition variable. */ struct cv_transfer { nsync_mu mu; nsync_cv cv; /* signalled each time a cond[] element becomes non-zero */ /* Thread i waits for cond[i] to be non-zero; under mu. */ int cond[TRANSFER_MAX_WAITERS]; nsync_mu control_mu; /* protects fields below */ nsync_cv done_cv; /* signalled each time an element of done[] becomes non-zero */ int ready[TRANSFER_MAX_WAITERS]; /* set by waiters as they wait */ int done[TRANSFER_MAX_WAITERS]; /* set by completed waiters: to 1 by readers, and to 2 by writers */ }; /* Return whether *(int *)v != 0. Used as a condition for nsync_mu_wait(). */ static int int_is_non_zero (const void *v) { return (0 != *(const int *)v); } /* Return when *pi becomes non-zero, where *pi is protected by *mu. Acquires and releases *mu. */ static void transfer_await_nonzero (nsync_mu *mu, int *pi) { nsync_mu_lock (mu); nsync_mu_wait (mu, &int_is_non_zero, pi, NULL); nsync_mu_unlock (mu); } /* Set *pi to x value, where *pi is protected by *mu. Acquires and releases *mu. */ static void transfer_set (nsync_mu *mu, int *pi, int x) { nsync_mu_lock (mu); *pi = x; nsync_mu_unlock (mu); } /* Lock and unlock routines for writers (index 0), and readers (index 1). */ static const struct { void (*lock) (nsync_mu *); void (*unlock) (nsync_mu *); } lock_type[2] = { { &nsync_mu_lock, &nsync_mu_unlock }, { &nsync_mu_rlock, &nsync_mu_runlock }, }; /* Signal and broadcast routines */ typedef void (*wakeup_func_type) (nsync_cv *); static wakeup_func_type wakeup_func[2] = { &nsync_cv_broadcast, &nsync_cv_signal }; /* Acquire cvt->mu in write or read mode (depending on "reader"), set cvt->ready[i], wait for cvt->cond[i] to become non-zero (using a condition variable if use_cv!=0), then release cvt->mu, and set cvt->done[i]. Used as the body of waiter threads created by test_cv_transfer(). */ static void transfer_waiter_thread (struct cv_transfer *cvt, int i, int reader, int use_cv) { (*lock_type[reader].lock) (&cvt->mu); transfer_set (&cvt->control_mu, &cvt->ready[i], 1); if (use_cv) { while (!cvt->cond[i]) { nsync_cv_wait (&cvt->cv, &cvt->mu); } } else { nsync_mu_wait (&cvt->mu, &int_is_non_zero, &cvt->cond[i], NULL); } (*lock_type[reader].unlock) (&cvt->mu); transfer_set (&cvt->control_mu, &cvt->done[i], reader? 1 : 2); nsync_cv_broadcast (&cvt->done_cv); } /* Return whether all the elements a[0..n-1] are less than x. */ static int are_all_below (int a[], int n, int x) { int i; for (i = 0; i != n && a[i] < x; i++) { } return (i == n); } CLOSURE_DECL_BODY4 (transfer_thread, struct cv_transfer *, int, int, int) /* Test cv-to-mutex queue transfer. (See the code in cv.c, wake_waiters().) The queue transfer needs to work regardless of: - whether the mutex is also being used with conditional critical sections, - whether reader locks are used, - whether the waker signals from within the critical section (as it would in a traditional monitor), or after that critical section, and - the number of threads that might be awoken. */ static void test_cv_transfer (testing t) { int waiters; /* number of waiters (in [2, TRANSFER_MAX_WAITERS]). */ int cv_writers; /* number of cv_writers: -1 means all */ int ccs_reader; /* ccs waiter is a reader */ int wakeup_type; /* bits: use_signal and after_region */ enum { use_signal = 0x1 }; /* use signal rather than broadcast */ enum { after_region = 0x2 }; /* perform wakeup after region, rather than within */ struct cv_transfer Xcvt; struct cv_transfer *cvt = &Xcvt; /* So all accesses are of form cvt-> */ int i; /* for all settings of all of wakeup_type, ccs_reader, cv_writers, and various different numbers of waiters */ for (waiters = 2; waiters <= TRANSFER_MAX_WAITERS; waiters <<= 1) { for (wakeup_type = 0; wakeup_type != 4; wakeup_type++) { for (cv_writers = -1; cv_writers != 3; cv_writers++) { for (ccs_reader = 0; ccs_reader != 2; ccs_reader++) { if (testing_verbose (t)) { TEST_LOG (t, ("transfer waiters %d wakeup_type %d cv_writers %d ccs_reader %d\n", waiters, wakeup_type, cv_writers, ccs_reader)); } memset ((void *) cvt, 0, sizeof (*cvt)); /* Start the waiter threads that use condition variables. */ for (i = 0; i < waiters-1; i++) { int is_reader = (cv_writers != -1 && i < waiters-1-cv_writers); closure_fork (closure_transfer_thread (&transfer_waiter_thread, cvt, i, is_reader, 1/*use_cv*/)); transfer_await_nonzero (&cvt->control_mu, &cvt->ready[i]); } /* Start the waiter thread that uses conditional critical sections. */ closure_fork (closure_transfer_thread (&transfer_waiter_thread, cvt, i, ccs_reader, 0/*use_cv*/)); /* Wait for all waiters to enter their regions. */ for (i = 0; i != waiters; i++) { transfer_await_nonzero (&cvt->control_mu, &cvt->ready[i]); } nsync_mu_lock (&cvt->mu); /* At this point, all the waiter threads are in waiting: they have set their ready[] flags, and have released cvt->mu. */ /* Mark all the condition-variable as runnable, and signal at least one of them. This may wake more than one, depending on the presence of readers, and the use of signal vs broadcast. */ for (i = 0; i != waiters-1; i++) { cvt->cond[i] = 1; } if ((wakeup_type & after_region) == 0) { (*wakeup_func[wakeup_type & use_signal]) (&cvt->cv); } nsync_mu_unlock (&cvt->mu); if ((wakeup_type & after_region) != 0) { for (i = 0; i != waiters-1; i++) { (*wakeup_func[wakeup_type & use_signal]) (&cvt->cv); } } /* Wait for at least one woken waiter to proceed, and at least one writer if there is one. */ nsync_mu_lock (&cvt->control_mu); while (are_all_below (&cvt->done[0], waiters-1, cv_writers!=0? 2 : 1)) { nsync_cv_wait (&cvt->done_cv, &cvt->control_mu); } nsync_mu_unlock (&cvt->control_mu); /* Wake all remaining threads. */ nsync_cv_broadcast (&cvt->cv); transfer_set (&cvt->mu, &cvt->cond[waiters-1], 1); /* And wait for all to finish. */ for (i = 0; i != waiters; i++) { transfer_await_nonzero (&cvt->control_mu, &cvt->done[i]); } if (testing_verbose (t)) { TEST_LOG (t, ("transfer waiters %d wakeup_type %d cv_writers %d ccs_reader %d complete\n", waiters, wakeup_type, cv_writers, ccs_reader)); } } } } } } /* --------------------------- */ int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_cv_producer_consumer0); TEST_RUN (tb, test_cv_producer_consumer1); TEST_RUN (tb, test_cv_producer_consumer2); TEST_RUN (tb, test_cv_producer_consumer3); TEST_RUN (tb, test_cv_producer_consumer4); TEST_RUN (tb, test_cv_producer_consumer5); TEST_RUN (tb, test_cv_producer_consumer6); TEST_RUN (tb, test_cv_deadline); TEST_RUN (tb, test_cv_cancel); TEST_RUN (tb, test_cv_debug); TEST_RUN (tb, test_cv_transfer); return (testing_base_exit (tb)); } nsync-1.24.0/testing/cv_wait_example_test.c000066400000000000000000000132701367521742200207730ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "compiler.h" #include "nsync.h" #include "time_extra.h" #include "smprintf.h" #include "testing.h" #include "closure.h" #include "array.h" #include "heap.h" NSYNC_CPP_USING_ /* Example use of CV.wait(): A priority queue of strings whose "remove_with_deadline" operation has a deadline. */ /* --------------------------------------- */ typedef A_TYPE (const char *) a_string; /* An array used as a heap of strings. */ /* heap comparison function */ static int str_lt (const char *e0, const char *e1) { return (strcmp (e0, e1) < 0); } static void no_set (const char *a UNUSED, int b UNUSED) { } /* --------------------------------------- */ /* A string_priority_queue_cv is a priority queue of strings, which emits the lexicographically least string available. */ typedef struct string_priority_queue_cv_s { nsync_cv non_empty; /* signalled when heap becomes non-empty */ nsync_mu mu; /* protects heap */ a_string heap; } string_priority_queue_cv; /* Add "s" to the queue *q. */ static void string_priority_queue_cv_add (string_priority_queue_cv *q, const char *s) { int alen; nsync_mu_lock (&q->mu); alen = A_LEN (&q->heap); if (alen == 0) { nsync_cv_broadcast (&q->non_empty); } A_PUSH (&q->heap) = s; heap_add (&A (&q->heap, 0), alen, str_lt, no_set, s); nsync_mu_unlock (&q->mu); } /* Wait until queue *q is non-empty, then remove a string from its beginning, and return it; or if abs_deadline is reached before the queue becomes non-empty, return NULL. */ static const char *string_priority_queue_cv_remove_with_deadline (string_priority_queue_cv *q, nsync_time abs_deadline) { int alen; const char *s = NULL; nsync_mu_lock (&q->mu); while (A_LEN (&q->heap) == 0 && nsync_cv_wait_with_deadline (&q->non_empty, &q->mu, abs_deadline, NULL) == 0) { } alen = A_LEN (&q->heap); if (alen != 0) { s = A (&q->heap, 0); heap_remove (&A (&q->heap, 0), alen, str_lt, no_set, 0); A_DISCARD (&q->heap, 1); } nsync_mu_unlock (&q->mu); return (s); } /* Free resources associates with *q */ static void string_priority_queue_cv_destroy (string_priority_queue_cv *q) { A_FREE (&q->heap); } /* --------------------------------------- */ /* Add strings s[0, ..., n-1] to *q, with the specified delay between additions. */ static void add_and_wait_cv (string_priority_queue_cv *q, nsync_time delay, int n, const char *s[]) { int i; for (i = 0; i != n; i++) { string_priority_queue_cv_add (q, s[i]); nsync_time_sleep (delay); } } CLOSURE_DECL_BODY4 (add_and_wait_cv, string_priority_queue_cv *, nsync_time, int, const char **) typedef A_TYPE (char) a_char; /* an array or characters */ /* Append the nul-terminated string str[] to *a. */ static void a_char_append (a_char *a, const char *str) { while (*str != 0) { A_PUSH (a) = *str; str++; } } /* Remove the first item from *q and output it on stdout, or output "timeout: " if no value can be found before "delay" elapses. */ static void remove_and_print_cv (string_priority_queue_cv *q, nsync_time delay, a_char *output) { const char *s; if ((s = string_priority_queue_cv_remove_with_deadline ( q, nsync_time_add (nsync_time_now(), delay))) != NULL) { a_char_append (output, s); a_char_append (output, "\n"); } else { char buf[64]; snprintf (buf, sizeof (buf), "timeout %gs\n", nsync_time_to_dbl (delay)); a_char_append (output, buf); } } /* Demonstrates the use of nsync_mu_wait() via a priority queue of strings. See the routine string_priority_queue_cv_remove_with_deadline(), above. */ static void example_cv_wait (testing t) { static const char *input[] = { "one", "two", "three", "four", "five" }; string_priority_queue_cv q; a_char output; static const char *expected = "one\n" "three\n" "two\n" "timeout 0.1s\n" "four\n" "timeout 0.1s\n" "five\n" "timeout 1s\n"; memset ((void *) &q, 0, sizeof (q)); memset (&output, 0, sizeof (output)); closure_fork (closure_add_and_wait_cv (&add_and_wait_cv, &q, nsync_time_ms (500), NELEM (input), input)); /* delay: "one", "two", "three" are queued; not "four" */ nsync_time_sleep (nsync_time_ms (1200)); remove_and_print_cv (&q, nsync_time_ms (1000), &output); /* "one" */ remove_and_print_cv (&q, nsync_time_ms (1000), &output); /* "three" (less than "two") */ remove_and_print_cv (&q, nsync_time_ms (1000), &output); /* "two" */ remove_and_print_cv (&q, nsync_time_ms (100), &output); /* time out because 1.3 < 0.5*3 */ remove_and_print_cv (&q, nsync_time_ms (1000), &output); /* "four" */ remove_and_print_cv (&q, nsync_time_ms (100), &output); /* time out because 0.1 < 0.5 */ remove_and_print_cv (&q, nsync_time_ms (1000), &output); /* "five" */ remove_and_print_cv (&q, nsync_time_ms (1000), &output); /* time out: no more to fetch */ A_PUSH (&output) = 0; if (strcmp (&A (&output, 0), expected) != 0) { TEST_ERROR (t, ("expected = %s\ngot = %s\n", expected, &A (&output, 0))); } A_FREE (&output); string_priority_queue_cv_destroy (&q); } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, example_cv_wait); return (testing_base_exit (tb)); } nsync-1.24.0/testing/dll_test.c000066400000000000000000000261771367521742200164110ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* This tests internal abstractions. */ #include "platform.h" #include "nsync_time.h" #include "dll.h" #include "smprintf.h" #include "testing.h" #include "array.h" NSYNC_CPP_USING_ typedef A_TYPE (int) a_int; /* an array of 32-bit integers */ static const a_int a_int_empty = A_EMPTY; /* the empty array */ /* Append the integers in the argument list to *a, until the first negative one is found. */ static a_int *a_set (a_int *a, ...) { va_list ap; int x; A_SET_LEN (a, 0); va_start (ap, a); for (x = va_arg (ap, int); x >= 0; x = va_arg (ap, int)) { A_PUSH (a) = x; } va_end (ap); return (a); } /* Remove the first element from *a. Requires that *a be non-empty. */ static void a_remove_first (a_int *a) { int len = A_LEN (a); if (len == 0) { *(volatile int *)0 = 0; } else { memmove (&A (a, 0), &A (a, 1), sizeof (A (a, 0)) * (len - 1)); A_SET_LEN (a, len-1); } } /* Return a malloced, nul-terminated string representation of the elements of *a. */ static char *a_string (const a_int *a) { int m = A_LEN (a) * 3 + 3; int n = 0; char *buf = (char *) malloc (m); char single[32]; int i; snprintf (buf+n, m-n, "["); n = strlen (buf); for (i = 0; i != A_LEN (a); i++) { int len; snprintf (single, sizeof (single), "%s%lu", i == 0? "": " ", (unsigned long)A (a, i)); len = strlen (single); if (m < n + len + 2) { buf = (char *) realloc (buf, m *= 2); } snprintf (buf + n, m-n, "%s", single); n += len; } snprintf (buf+n, m-n, "]"); return (buf); } /* A list item for use in the tests below */ struct list_item_s { nsync_dll_element_ e; int i; }; /* Return a pointer to the struct list_item_s containing nsync_dll_element_ *e_. */ #define LIST_ITEM(e_) ((struct list_item_s *) ((e_)->container)) /* Check that list l contains elements containing the values in expected, by scanning both forwards and backwards through the list. Also verify that nsync_dll_first_() and nsync_dll_last_() return the first and last element found during those iterations, and that nsync_dll_is_empty_() yields the right value. */ static void verify_list (testing t, const char *label, nsync_dll_list_ l, const a_int *expected, const char *file, int line) { nsync_dll_element_ *first; nsync_dll_element_ *last = NULL; nsync_dll_element_ *p; int i = 0; char *expected_str = a_string (expected); for (p = nsync_dll_first_ (l); p != NULL; p = nsync_dll_next_ (l, p)) { if (A (expected, i) != LIST_ITEM (p)->i) { TEST_ERROR (t, ("%s:%d; %s:expected=%s: expected %d as " "value %d in list, but found %d\n", file, line, label, expected_str, A (expected, i), i, LIST_ITEM (p)->i)); } last = p; i++; } if (last != nsync_dll_last_ (l)) { TEST_ERROR (t, ("%s:%d: %s:expected=%s: expected %p as " "last item in list, but found %p\n", file, line, label, expected_str, last, nsync_dll_last_ (l))); } if (i != A_LEN (expected)) { TEST_ERROR (t, ("%s:%d: %s:expected=%s: expected %d items in " "list, but found %d\n", file, line, label, expected_str, A_LEN (expected), i)); } first = NULL; for (p = nsync_dll_last_ (l); p != NULL; p = nsync_dll_prev_ (l, p)) { i--; if (A (expected, i) != LIST_ITEM (p)->i) { TEST_ERROR (t, ("%s:%d: %s:expected=%s: expected %d as " "value %d in reverse list, but found %d\n", file, line, label, expected_str, A (expected, i), i, LIST_ITEM (p)->i)); } first = p; } if (first != nsync_dll_first_ (l)) { TEST_ERROR (t, ("%s:%d: %s:expected=%s: expected %p as " "first item in list, but found %p\n", file, line, label, expected_str, first, nsync_dll_last_ (l))); } if (i != 0) { TEST_ERROR (t, ("%s:%d: %s:expected=%s: expected %d items " "in reverse list, but found %d\n", file, line, label, expected_str, A_LEN (expected), A_LEN (expected)-i)); } if ((A_LEN (expected) == 0) != nsync_dll_is_empty_ (l)) { TEST_ERROR (t, ("%s:%d: %s:expected=%s: expected nsync_dll_is_empty_() " "to yield %d but got %d\n", file, line, label, expected_str, (A_LEN (expected) == 0), nsync_dll_is_empty_ (l))); } free (expected_str); } /* Return a new list containing the count integers from start to start+count-1 by appending successive elements to the list. This exercises nsync_dll_make_last_in_list_() using singleton elements. */ static nsync_dll_list_ make_list (int start, int count) { nsync_dll_list_ l = NULL; int i; for (i = start; i != start+count; i++) { struct list_item_s *item = (struct list_item_s *) malloc (sizeof (*item)); nsync_dll_init_ (&item->e, item); item->i = i; l = nsync_dll_make_last_in_list_ (l, &item->e); } return (l); } /* Return a new list containing the count integers from start to start+count-1 by prefixing the list with elements, starting with the last. It exercises nsync_dll_make_first_in_list_() using singleton elements. */ static nsync_dll_list_ make_rlist (int start, int count) { nsync_dll_list_ l = NULL; int i; for (i = start + count - 1; i != start-1; i--) { struct list_item_s *item = (struct list_item_s *) malloc (sizeof (*item)); nsync_dll_init_ (&item->e, item); item->i = i; l = nsync_dll_make_first_in_list_ (l, &item->e); } return (l); } /* Test the functionality of the various doubly-linked list operations internal to the nsync_mu implementation. */ static void test_dll (testing t) { int i; a_int expected; struct list_item_s *item; nsync_dll_list_ empty = NULL; nsync_dll_list_ list = NULL; nsync_dll_list_ x10 = NULL; nsync_dll_list_ x20 = NULL; nsync_dll_list_ x30 = NULL; nsync_dll_list_ x40 = NULL; nsync_dll_list_ x50 = NULL; memset (&expected, 0, sizeof (expected)); /* All lists are initially empty. */ verify_list (t, "empty (0)", empty, &a_int_empty, __FILE__, __LINE__); verify_list (t, "list (0)", list, &a_int_empty, __FILE__, __LINE__); verify_list (t, "x10", x10, &a_int_empty, __FILE__, __LINE__); verify_list (t, "x20", x20, &a_int_empty, __FILE__, __LINE__); verify_list (t, "x30", x30, &a_int_empty, __FILE__, __LINE__); verify_list (t, "x40", x40, &a_int_empty, __FILE__, __LINE__); verify_list (t, "x50", x50, &a_int_empty, __FILE__, __LINE__); /* Make the xN list have the values N, N+1, N+2. */ x10 = make_list (10, 3); verify_list (t, "x10", x10, a_set (&expected, 10, 11, 12, -1), __FILE__, __LINE__); x20 = make_rlist (20, 3); verify_list (t, "x20", x20, a_set (&expected, 20, 21, 22, -1), __FILE__, __LINE__); x30 = make_list (30, 3); verify_list (t, "x30", x30, a_set (&expected, 30, 31, 32, -1), __FILE__, __LINE__); x40 = make_list (40, 3); verify_list (t, "x40", x40, a_set (&expected, 40, 41, 42, -1), __FILE__, __LINE__); x50 = make_list (50, 3); verify_list (t, "x50", x50, a_set (&expected, 50, 51, 52, -1), __FILE__, __LINE__); /* Check that adding nothing to an empty list leaves it empty. */ list = nsync_dll_make_first_in_list_ (list, NULL); verify_list (t, "list(1)", list, &a_int_empty, __FILE__, __LINE__); list = nsync_dll_make_first_in_list_ (list, nsync_dll_first_ (empty)); verify_list (t, "list(2)", list, &a_int_empty, __FILE__, __LINE__); list = nsync_dll_make_first_in_list_ (list, nsync_dll_last_ (empty)); verify_list (t, "list(3)", list, &a_int_empty, __FILE__, __LINE__); /* Prefix an empty list with some elements. */ list = nsync_dll_make_first_in_list_ (list, nsync_dll_first_ (x10)); verify_list (t, "list(4)", list, a_set (&expected, 10, 11, 12, -1), __FILE__, __LINE__); /* Check that adding nothing no a non-empty list leaves it unchanged. */ list = nsync_dll_make_first_in_list_ (list, NULL); verify_list (t, "list(5)", list, a_set (&expected, 10, 11, 12, -1), __FILE__, __LINE__); list = nsync_dll_make_first_in_list_ (list, nsync_dll_first_ (empty)); verify_list (t, "list(6)", list, a_set (&expected, 10, 11, 12, -1), __FILE__, __LINE__); list = nsync_dll_make_first_in_list_ (list, nsync_dll_last_ (empty)); verify_list (t, "list(7)", list, a_set (&expected, 10, 11, 12, -1), __FILE__, __LINE__); /* Check prefixing the list with some elements. */ list = nsync_dll_make_first_in_list_ (list, nsync_dll_first_ (x20)); verify_list (t, "list(8)", list, a_set (&expected, 20, 21, 22, 10, 11, 12, -1), __FILE__, __LINE__); /* Check appending elements to list. */ list = nsync_dll_make_last_in_list_ (list, nsync_dll_last_ (x30)); verify_list (t, "list(9)", list, a_set (&expected, 20, 21, 22, 10, 11, 12, 30, 31, 32, -1), __FILE__, __LINE__); /* Remove the first element. */ item = (struct list_item_s *) nsync_dll_first_ (list)->container; list = nsync_dll_remove_ (list, &item->e); verify_list (t, "list(10)", list, a_set (&expected, 21, 22, 10, 11, 12, 30, 31, 32, -1), __FILE__, __LINE__); free (item); /* Remove the last element. */ item = (struct list_item_s *) nsync_dll_last_ (list)->container; list = nsync_dll_remove_ (list, &item->e); verify_list (t, "list(11)", list, a_set (&expected, 21, 22, 10, 11, 12, 30, 31, -1), __FILE__, __LINE__); free (item); /* Remove the third element. */ item = (struct list_item_s *) nsync_dll_next_ (list, nsync_dll_next_ (list, nsync_dll_first_ (list)))->container; list = nsync_dll_remove_ (list, &item->e); verify_list (t, "list(12)", list, a_set (&expected, 21, 22, 11, 12, 30, 31, -1), __FILE__, __LINE__); free (item); /* Remove all elements. */ a_set (&expected, 21, 22, 11, 12, 30, 31, -1); for (i = 0; !nsync_dll_is_empty_ (list); i++) { char buf[32]; item = (struct list_item_s *) nsync_dll_first_ (list)->container; list = nsync_dll_remove_ (list, &item->e); a_remove_first (&expected); snprintf (buf, sizeof (buf), "list(13.%d)", i); verify_list (t, buf, list, &expected, __FILE__, __LINE__); free (item); } verify_list (t, "list(14)", list, &a_int_empty, __FILE__, __LINE__); /* Append some elements to an empty list. */ list = nsync_dll_make_last_in_list_ (list, nsync_dll_last_ (x40)); verify_list (t, "list(15)", list, a_set (&expected, 40, 41, 42, -1), __FILE__, __LINE__); /* Use nsync_dll_splice_after_() to put {50, 51, 52} just after 41, which is next (first (list)). */ nsync_dll_splice_after_ (nsync_dll_next_ (list, nsync_dll_first_ (list)), nsync_dll_first_ (x50)); verify_list (t, "list(16)", list, a_set (&expected, 40, 41, 50, 51, 52, 42, -1), __FILE__, __LINE__); A_FREE (&expected); while (!nsync_dll_is_empty_ (list)) { item = (struct list_item_s *) nsync_dll_first_ (list)->container; list = nsync_dll_remove_ (list, &item->e); free (item); } } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_dll); return (testing_base_exit (tb)); } nsync-1.24.0/testing/heap.h000066400000000000000000000044601367521742200155100ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_TESTING_HEAP_H_ #define NSYNC_TESTING_HEAP_H_ /* A heap. Optionally, elements may have storage for the index to allow deletions from arbitrary elements. A "set" operation sets the field. Use heap_no_set when no field is available. Let: set (e,i) sets the index field of the element e to i lt (e0, e1) returns whether element e0 < e1 If "a" is an array, "n" is is its length, then To add an element e: ensure there are n+1 elements in a[] heap_add (a, n, lt, set, e); // modifies n To remove element i: heap_remove (a, n, lt, set, i); // modifies n To replace element i with element e: heap_adjust (a, n, lt, set, i, e); */ #define h_up_(i) (((i)-1) >> 1) #define h_down_(i) (((i)<<1) + 1) #define h_updownall_(up,a,n,i,lt,set,v,s) \ do { \ int i_ = (i); \ int n_ = (n); \ int j_; \ if (up) { \ for (; i_!=0 && ((j_ = h_up_ (i_)), lt ((v), (a)[j_])); i_ = j_) { \ (a)[i_] = (a)[j_]; \ set ((a)[i_], i_); \ } \ } else { \ for (; (j_ = h_down_ (i_)) < n_ && ((j_ += (j_+1 < n_ && \ lt ((a)[j_+1], (a)[j_]))), lt ((a)[j_], (v))); i_ = j_) { \ (a)[i_] = (a)[j_]; \ set ((a)[i_], i_); \ } \ } \ s; \ } while (0) #define heap_no_set(a,b) ((void)0) #define heap_add(a,n,lt,set,v) h_updownall_ (1, (a), 0, \ (n), lt, set, (v), ((a)[i_]=(v), set ((a)[i_], i_), (n)++)) #define heap_remove(a,n,lt,set,i) h_updownall_ (lt ((a)[n_], (a)[i_]), (a), --(n), \ (i), lt, set, (a)[n_], ((a)[i_]=(a)[n_], set ((a)[i_], i_))) #define heap_adjust(a,n,lt,set,i,v) h_updownall_ (lt ((v), (a)[i_]), (a), (n), \ (i), lt, set, (v), ((a)[i_]=(v), set ((a)[i_], i_))) #endif /*NSYNC_TESTING_HEAP_H_*/ nsync-1.24.0/testing/mu_starvation_test.c000066400000000000000000000307631367521742200205250ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "nsync.h" #include "time_extra.h" #include "smprintf.h" #include "testing.h" #include "closure.h" NSYNC_CPP_USING_ /* Test the behaviour of mu in situations where starvation might be expected. */ /* starve_data is the data used by the starvation tests */ typedef struct starve_data_s { nsync_mu mu; /* precedes control_mu in locking order */ int cancel; /* whether threads should shutdown; under mu */ nsync_time start; /* when test started */ nsync_mu control_mu; int not_yet_started; /* threads not yet started; under control_mu */ int not_yet_done; /* threads not yet done; under control_mu */ } starve_data; /* initialize *sd */ static void starve_data_init (starve_data *sd, int threads) { memset ((void *) sd, 0, sizeof (*sd)); sd->not_yet_started = threads; sd->not_yet_done = threads; sd->start = nsync_time_now (); } /* Loop until *cancel or deadline, and on each iteration acquire *mu in reader mode, and hold it until the next odd or even multiple of period, according to parity. Just before return, decrement *done under *mu. Two threads using these calls are used to hold the mutex continually, in the absence of other activity. */ static void starve_with_readers (starve_data *sd, nsync_time period, uint32_t parity, nsync_time deadline) { nsync_time now; uint32_t period_us = (uint32_t) (nsync_time_to_dbl (period) * 1e6); nsync_mu_rlock (&sd->mu); nsync_mu_lock (&sd->control_mu); sd->not_yet_started--; nsync_mu_unlock (&sd->control_mu); for (now = nsync_time_now (); !sd->cancel && nsync_time_cmp (now, deadline) < 0; now = nsync_time_now ()) { uint32_t new_us; uint32_t now_us = (uint32_t) (nsync_time_to_dbl (nsync_time_sub (now, sd->start)) * 1e6); uint32_t index = (now_us + period_us - 1) / period_us; if ((index & 1) != parity) { index++; } new_us = index * period_us; nsync_time_sleep (nsync_time_from_dbl (1e-6 * (double) (new_us-now_us))); nsync_mu_runlock (&sd->mu); nsync_mu_rlock (&sd->mu); } nsync_mu_runlock (&sd->mu); nsync_mu_lock (&sd->control_mu); sd->not_yet_done--; nsync_mu_unlock (&sd->control_mu); } CLOSURE_DECL_BODY4 (starve_with_readers, starve_data *, nsync_time, uint32_t, nsync_time) static int started (const void *v) { return (((const starve_data *) v)->not_yet_started == 0); } static int done (const void *v) { return (((const starve_data *) v)->not_yet_done == 0); } /* Verify the behaviour of nsync_mu in the face of reader threads that conspire keep the lock held continuously in reader mode, even though each of the threads releases and reacquires periodically (while another thread holds the lock). The routine starve_with_readers() is used to achieve this effect. We expect that nsync_mu_trylock() will not be able to acquire while this is happening, but that nsync_mu_lock() will be able to acquire, due to the action of the mu's mu_writer_waiting bit. */ static void test_starve_with_readers (testing t) { nsync_time finish; int trylock_acquires; int expected_lo; int lock_acquires; nsync_time deadline; starve_data sd; starve_data_init (&sd, 2); /* two threads, started below */ /* Threads run for at most 10s. */ deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (10000)); /* These two threads will try to hold a reader lock continuously until cancel is set or deadline is reached, even though each will release the lock every 20ms. */ closure_fork (closure_starve_with_readers ( &starve_with_readers, &sd, nsync_time_ms (10), 0, deadline)); closure_fork (closure_starve_with_readers ( &starve_with_readers, &sd, nsync_time_ms (10), 1, deadline)); /* wait for the threads to acquire their first lock. */ nsync_mu_lock (&sd.control_mu); nsync_mu_wait (&sd.control_mu, &started, &sd, NULL); nsync_mu_unlock (&sd.control_mu); /* If using an nsync_mu, use nsync_mu_trylock() to attempt to acquire while the readers are hogging the lock. We expect no acquisitions to succeed. */ finish = nsync_time_add (nsync_time_now (), nsync_time_ms (500)); trylock_acquires = 0; /* number of acquires */ while (nsync_time_cmp (nsync_time_now (), finish) < 0) { if (nsync_mu_trylock (&sd.mu)) { trylock_acquires++; nsync_mu_unlock (&sd.mu); } sched_yield (); } if (trylock_acquires != 0) { TEST_ERROR (t, ("expected no acquisitions via nsync_mu_trylock(), got %d\n", trylock_acquires)); } /* Use nsync_mu_lock() to attempt to acquire while the readers are hogging the lock. We expect several acquisitions to succeed. */ expected_lo = 2; finish = nsync_time_add (nsync_time_now (), nsync_time_ms (5000)); lock_acquires = 0; /* number of acquires */ while (nsync_time_cmp (nsync_time_now (), finish) < 0 && lock_acquires < expected_lo) { nsync_mu_lock (&sd.mu); lock_acquires++; nsync_mu_unlock (&sd.mu); nsync_time_sleep (nsync_time_ms (1)); } if (nsync_time_cmp (nsync_time_now (), deadline) > 0 && lock_acquires == 1) { lock_acquires = 0; /* hog threads timed out */ } if (lock_acquires < expected_lo) { TEST_ERROR (t, ("expected at least %d acquisitions via nsync_mu_lock(), got %d\n", expected_lo, lock_acquires)); } nsync_mu_lock (&sd.mu); sd.cancel = 1; /* Tell threads to exit. */ nsync_mu_unlock (&sd.mu); nsync_mu_lock (&sd.control_mu); nsync_mu_wait (&sd.control_mu, &done, &sd, NULL); /* wait for exit. */ nsync_mu_unlock (&sd.control_mu); } /* Loop until sd.cancel or deadline. On each iteration< acquire sd.mu in writer mode, sleep for hold_time, and release sd.mu. Just before return, decrement sd.not_yet_done under sd.control_mu. */ static void starve_with_writer (starve_data *sd, nsync_time hold_time, nsync_time deadline) { nsync_time now; nsync_mu_lock (&sd->mu); nsync_mu_lock (&sd->control_mu); sd->not_yet_started--; nsync_mu_unlock (&sd->control_mu); for (now = nsync_time_now (); !sd->cancel && nsync_time_cmp (now, deadline) < 0; now = nsync_time_now ()) { nsync_time_sleep (hold_time); nsync_mu_unlock (&sd->mu); nsync_mu_lock (&sd->mu); } nsync_mu_unlock (&sd->mu); nsync_mu_lock (&sd->control_mu); sd->not_yet_done--; nsync_mu_unlock (&sd->control_mu); } CLOSURE_DECL_BODY3 (starve_with_writer, starve_data *, nsync_time, nsync_time) /* Verify the behaviour of nsync_mu in the face of a single writer thread that repeatedly hogs the lock by acquiring it and holding it for longer than the runtime's wakeup time, then releasing. The next iteration reacquires the lock moments later, a time much shorter than the runtime's wakeup time. The routine starve_with_writer() is used to achieve this effect. These circumstances can make it hard for another thread T to acquire. T will first wait on the mutex's queue. Eventually, it will be woken by the hog thread, but under normal circumstances T will take so long to run that the hog will have reacquired the mutex. Because the hog keeps the lock for longer than the runtime's wakeup time, T will go back to sleep again, and the process repeats indefinitely. We expect that incessant attempts via nsync_mu_trylock() and nsync_mu_rtrylock() will occasionally manage to hit the moments when the lock is not held. nsync_mu_lock() and nsync_mu_rlock() will succeed only because of the action of mu's mu_long_wait bit, which will eventually force the hog to wait itself, and allow a waiter to acquire. We expect few acquires because mu_long_wait kicks in only when things look dire. */ static void test_starve_with_writer (testing t) { int expected_lo; nsync_time finish; int lock_acquires; int rlock_acquires; int trylock_acquires; int rtrylock_acquires; nsync_time deadline; starve_data sd; starve_data_init (&sd, 1); /* one thread, started below */ deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (25000)); /* runs for at most 25s. */ /* This thread will try to hold a writer lock almost continuously, releasing momentarily every 10ms. */ closure_fork (closure_starve_with_writer (&starve_with_writer, &sd, nsync_time_ms (10), deadline)); nsync_mu_lock (&sd.control_mu); nsync_mu_wait (&sd.control_mu, &started, &sd, NULL); nsync_mu_unlock (&sd.control_mu); expected_lo = 0; /* minimum expected operations at each test */ finish = nsync_time_zero; /* finish time for each test */ if (!testing_is_uniprocessor (t)) { /* this test won't work on a uniprocessor */ /* Use nsync_mu_trylock() to attempt to acquire while the writer is hogging the lock. We expect some acquisitions to succeed. */ expected_lo = 1; finish = nsync_time_add (nsync_time_now (), nsync_time_ms (30000)); trylock_acquires = 0; /* number of acquires */ while (nsync_time_cmp (nsync_time_now (), finish) < 0 && trylock_acquires < expected_lo) { if (nsync_mu_trylock (&sd.mu)) { trylock_acquires++; nsync_mu_unlock (&sd.mu); } sched_yield (); } if (trylock_acquires < expected_lo) { TEST_ERROR (t, ("expected at least %d acquisitions via " "nsync_mu_trylock(), got %d\n", expected_lo, trylock_acquires)); } } if (!testing_is_uniprocessor (t)) { /* this test won't work on a uniprocessor */ /* Use nsync_mu_rtrylock() to attempt to read-acquire while the writer is hogging the lock. We expect some acquisitions to succeed. */ expected_lo = 1; finish = nsync_time_add (nsync_time_now (), nsync_time_ms (30000)); rtrylock_acquires = 0; /* number of acquires */ while (nsync_time_cmp (nsync_time_now (), finish) < 0 && rtrylock_acquires < expected_lo) { if (nsync_mu_rtrylock (&sd.mu)) { rtrylock_acquires++; nsync_mu_runlock (&sd.mu); } sched_yield (); } if (rtrylock_acquires < expected_lo) { TEST_ERROR (t, ("expected at least %d acquisitions via " "nsync_mu_rtrylock(), got %d\n", expected_lo, rtrylock_acquires)); } } /* Use nsync_mu_lock() to attempt to acquire while the writer is hogging the lock. We expect several acquisitions to succeed. */ expected_lo = 2; finish = nsync_time_add (nsync_time_now (), nsync_time_ms (5000)); lock_acquires = 0; /* number of acquires */ while (nsync_time_cmp (nsync_time_now (), finish) < 0 && lock_acquires < expected_lo) { nsync_mu_lock (&sd.mu); lock_acquires++; nsync_mu_unlock (&sd.mu); nsync_time_sleep (nsync_time_ms (2)); } if (lock_acquires == 1 && nsync_time_cmp (nsync_time_now (), deadline) > 0) { lock_acquires = 0; /* hog thread timed out */ } if (lock_acquires < expected_lo) { TEST_ERROR (t, ("expected at least %d acquisitions via nsync_mu_lock(), got %d\n", expected_lo, lock_acquires)); } /* If enough time remains to run the test, use nsync_mu_rlock() to attempt to acquire while the writer is hogging the lock. We expect several acquisitions to succeed. It's ok not to run the test if we ran out time----it means that a writer couldn't break in (the test case above failed), so a reader is unlikely to manage it either. */ expected_lo = 2; finish = nsync_time_add (nsync_time_now (), nsync_time_ms (5000)); rlock_acquires = 0; /* number of acquires */ if (nsync_time_cmp (finish, deadline) < 0) { while (nsync_time_cmp (nsync_time_now (), finish) < 0 && rlock_acquires < expected_lo) { nsync_mu_rlock (&sd.mu); rlock_acquires++; nsync_mu_runlock (&sd.mu); nsync_time_sleep (nsync_time_ms (2)); } if (rlock_acquires == 1 && nsync_time_cmp (nsync_time_now (), deadline) > 0) { rlock_acquires = 0; /* hog thread timed out */ } if (rlock_acquires < expected_lo) { TEST_ERROR (t, ("expected at least %d acquisitions via " "nsync_mu_rlock(), got %d\n", expected_lo, rlock_acquires)); } } nsync_mu_lock (&sd.mu); sd.cancel = 1; /* Tell threads to exit. */ nsync_mu_unlock (&sd.mu); nsync_mu_lock (&sd.control_mu); nsync_mu_wait (&sd.control_mu, &done, &sd, NULL); /* wait for exit. */ nsync_mu_unlock (&sd.control_mu); } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_starve_with_readers); TEST_RUN (tb, test_starve_with_writer); return (testing_base_exit (tb)); } nsync-1.24.0/testing/mu_test.c000066400000000000000000001027631367521742200162530ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "nsync.h" #include "time_extra.h" #include "smprintf.h" #include "testing.h" #include "closure.h" NSYNC_CPP_USING_ /* The state shared between the threads in each of the tests below. */ typedef struct test_data_s { testing t; int n_threads; /* Number of test threads; constant after init. */ int loop_count; /* Iteration count for each test thread; constant after init */ /* mu_in_use protects i, id, loop_count, and finished_threads. */ void *mu_in_use; /* points at mu, mutex, or rwmutex depending on which is in use. */ void (*lock) (void *); /* operations on mu_in_use */ void (*unlock) (void *); nsync_mu mu; pthread_mutex_t mutex; pthread_rwlock_t rwmutex; int i; /* counter incremented by test loops. */ volatile int id; /* id of current lock-holding thread in some tests. */ nsync_cv done; /* Signalled when finished_threads==n_threads. */ int finished_threads; /* Count of threads that have finished. */ } test_data; /* Indicate that a thread has finished its operations on test_data by incrementing td.finished_threads, and signal td.done when it reaches td.n_threads. See test_data_wait_for_all_threads(). */ static void test_data_thread_finished (test_data *td) { (*td->lock) (td->mu_in_use); td->finished_threads++; if (td->finished_threads == td->n_threads) { nsync_cv_broadcast (&td->done); } (*td->unlock) (td->mu_in_use); } /* Wait until all td.n_threads have called test_data_thread_finished(), and then return. */ static void test_data_wait_for_all_threads (test_data *td) { (*td->lock) (td->mu_in_use); while (td->finished_threads != td->n_threads) { nsync_cv_wait_with_deadline_generic (&td->done, td->mu_in_use, td->lock, td->unlock, nsync_time_no_deadline, NULL); } (*td->unlock) (td->mu_in_use); } /* --------------------------------------- */ /* The body of each thread executed by test_mu_nthread() and test_mutex_nthread. *td represents the test data that the threads share, and id is an integer unique to each test thread. */ static void counting_loop (test_data *td, int id) { int n = td->loop_count; int i = 0; for (i = 0; i != n; i++) { (*td->lock) (td->mu_in_use); td->id = id; td->i++; if (td->id != id) { testing_panic ("td->id != id"); } (*td->unlock) (td->mu_in_use); } test_data_thread_finished (td); } CLOSURE_DECL_BODY2 (counting, test_data *, int) /* Versions of nsync_mu_lock() and nsync_mu_unlock() that take "void *" arguments, to avoid call through a function pointer of a different type, which is undefined. */ static void void_mu_lock (void *mu) { nsync_mu_lock ((nsync_mu *) mu); } static void void_mu_unlock (void *mu) { nsync_mu_unlock((nsync_mu *) mu); } /* Create a few threads, each of which increments an integer a fixed number of times, using an nsync_mu for mutual exclusion. It checks that the integer is incremented the correct number of times. */ static void test_mu_nthread (testing t) { int loop_count = 100000; nsync_time deadline; deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (1500)); do { int i; test_data td; memset ((void *) &td, 0, sizeof (td)); td.t = t; td.n_threads = 5; td.loop_count = loop_count; td.mu_in_use = &td.mu; td.lock = &void_mu_lock; td.unlock = &void_mu_unlock; for (i = 0; i != td.n_threads; i++) { closure_fork (closure_counting (&counting_loop, &td, i)); } test_data_wait_for_all_threads (&td); if (td.i != td.n_threads*td.loop_count) { TEST_FATAL (t, ("test_mu_nthread final count inconsistent: want %d, got %d", td.n_threads*td.loop_count, td.i)); } loop_count *= 2; } while (nsync_time_cmp (nsync_time_now (), deadline) < 0); } /* void pthread_mutex_lock */ static void void_pthread_mutex_lock (void *mu) { pthread_mutex_lock ((pthread_mutex_t *) mu); } /* void pthread_mutex_unlock */ static void void_pthread_mutex_unlock (void *mu) { pthread_mutex_unlock ((pthread_mutex_t *) mu); } /* Create a few threads, each of which increments an integer a fixed number of times, using a pthread_mutex_t for mutual exclusion. It checks that the integer is incremented the correct number of times. */ static void test_mutex_nthread (testing t) { int loop_count = 100000; nsync_time deadline; deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (1500)); do { int i; test_data td; memset ((void *) &td, 0, sizeof (td)); td.t = t; td.n_threads = 5; td.loop_count = loop_count; td.mu_in_use = &td.mutex; td.lock = &void_pthread_mutex_lock; td.unlock = &void_pthread_mutex_unlock; pthread_mutex_init (&td.mutex, NULL); for (i = 0; i != td.n_threads; i++) { closure_fork (closure_counting (&counting_loop, &td, i)); } test_data_wait_for_all_threads (&td); if (td.i != td.n_threads*td.loop_count) { TEST_FATAL (t, ("test_mutex_nthread final count inconsistent: want %d, got %d", td.n_threads*td.loop_count, td.i)); } pthread_mutex_destroy (&td.mutex); loop_count *= 2; } while (nsync_time_cmp (nsync_time_now (), deadline) < 0); } /* void pthread_rwlock_wrlock */ static void void_pthread_rwlock_wrlock (void *mu) { pthread_rwlock_wrlock ((pthread_rwlock_t *) mu); } /* void pthread_rwlock_unlock */ static void void_pthread_rwlock_unlock (void *mu) { pthread_rwlock_unlock ((pthread_rwlock_t *) mu); } /* Create a few threads, each of which increments an integer a fixed number of times, using a pthread_rwlock_t for mutual exclusion. It checks that the integer is incremented the correct number of times. */ static void test_rwmutex_nthread (testing t) { int loop_count = 100000; nsync_time deadline; deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (1500)); do { int i; test_data td; memset ((void *) &td, 0, sizeof (td)); td.t = t; td.n_threads = 5; td.loop_count = loop_count; td.mu_in_use = &td.rwmutex; td.lock = &void_pthread_rwlock_wrlock; td.unlock = &void_pthread_rwlock_unlock; pthread_rwlock_init (&td.rwmutex, NULL); for (i = 0; i != td.n_threads; i++) { closure_fork (closure_counting (&counting_loop, &td, i)); } test_data_wait_for_all_threads (&td); if (td.i != td.n_threads*td.loop_count) { TEST_FATAL (t, ("test_mutex_nthread final count inconsistent: want %d, got %d", td.n_threads*td.loop_count, td.i)); } pthread_rwlock_destroy (&td.rwmutex); loop_count *= 2; } while (nsync_time_cmp (nsync_time_now (), deadline) < 0); } /* --------------------------------------- */ /* The body of each thread executed by test_try_mu_nthread(). *td represents the test data that the threads share, and id is an integer unique to each test thread. */ static void counting_loop_try_mu (test_data *td, int id) { int i; int n = td->loop_count; for (i = 0; i != n; i++) { while (!nsync_mu_trylock (&td->mu)) { sched_yield (); } td->id = id; td->i++; if (td->id != id) { testing_panic ("td->id != id"); } n = td->loop_count; nsync_mu_unlock (&td->mu); } test_data_thread_finished (td); } /* Test that acquiring an nsync_mu with nsync_mu_trylock() using several threads provides mutual exclusion. */ static void test_try_mu_nthread (testing t) { int loop_count = 100000; nsync_time deadline; deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (1500)); do { int i; test_data td; memset ((void *) &td, 0, sizeof (td)); td.t = t; td.n_threads = 5; td.loop_count = loop_count; td.mu_in_use = &td.mu; td.lock = &void_mu_lock; td.unlock = &void_mu_unlock; for (i = 0; i != td.n_threads; i++) { closure_fork (closure_counting (&counting_loop_try_mu, &td, i)); } test_data_wait_for_all_threads (&td); if (td.i != td.n_threads*td.loop_count) { TEST_FATAL (t, ("test_try_mu_nthread final count inconsistent: want %d, got %d", td.n_threads*td.loop_count, td.i)); } loop_count *= 2; } while (nsync_time_cmp (nsync_time_now (), deadline) < 0); } /* --------------------------------------- */ /* An integer protected by a mutex, and with an associated condition variable that is signalled when the counter reaches 0. */ typedef struct counter_s { nsync_mu mu; /* protects value */ int value; nsync_cv cv; /* signalled when value becomes 0 */ } counter; /* Return a counter with initial value "initial". */ static counter *counter_new (int initial) { counter *c = (counter *) malloc (sizeof (*c)); memset ((void *) c, 0, sizeof (*c)); c->value = initial; return (c); } /* Increment *c by "increment". */ static void counter_inc (counter *c, int increment) { if (increment != 0) { nsync_mu_lock (&c->mu); c->value += increment; if (c->value == 0) { nsync_cv_broadcast (&c->cv); } nsync_mu_unlock (&c->mu); } } /* Wait on *c's condition variable until the counter becomes 0, or abs_deadline is reached. */ static int counter_wait_for_zero_with_deadline (counter *c, nsync_time abs_deadline) { int value; nsync_mu_rlock (&c->mu); while (c->value != 0 && nsync_cv_wait_with_deadline (&c->cv, &c->mu, abs_deadline, NULL) == 0) { } value = c->value; nsync_mu_runlock (&c->mu); return (value); } /* Wait on *c's condition variable until the counter becomes 0. */ static void counter_wait_for_zero (counter *c) { int value = counter_wait_for_zero_with_deadline (c, nsync_time_no_deadline); if (value != 0) { testing_panic (smprintf ("wait_for_zero() about to return with " "non-zero value %d", value)); } } /* Return the current value of *c. */ static int counter_value (counter *c) { int value; nsync_mu_rlock (&c->mu); value = c->value; nsync_mu_runlock (&c->mu); return (value); } /* --------------------------------------- */ CLOSURE_DECL_BODY9 (attempt_trylock, testing , const char *, int, nsync_mu *, int, int, int *, int, counter *) /* Call nsync_mu_trylock(), and compares the result to expected_acquire. If the lock was acquired, then: - if expected_value != -1, compare *value against expected_value. - increment *value. - if release is non-zero, release the lock before returning. In any case, the counter *done is decremented. */ static void attempt_trylock (testing t, const char *id, int verbose, nsync_mu *mu, int expected_acquire, int release, int *value, int expected_value, counter *done) { int acquired = nsync_mu_trylock (mu); if (acquired != expected_acquire) { testing_panic (smprintf ("attempt_trylock %s: expected " "nsync_mu_trylock() to return %d but got %d", id, expected_acquire, acquired)); } if (verbose) { TEST_LOG (t, ("attempt_trylock %s %d\n", id, acquired)); } if (acquired) { nsync_mu_assert_held (mu); if (expected_value != -1 && *value != expected_value) { testing_panic (smprintf ("attempt_trylock %s expected " "value %d, *value=%d", id, expected_value, *value)); } (*value)++; if (verbose) { TEST_LOG (t, ("attempt_trylock %s incremented value to %d\n", id, *value)); } if (release) { nsync_mu_unlock (mu); } } counter_inc (done, -1); } /* Call nsync_mu_rtrylock(), and compare the result to expected_acquire. If the lock was acquired, then: - if expected_value != -1, compare *value against expected_value. - if release is non-zero, release the lock before returning. In any case, decrement *done. */ static void attempt_rtrylock (testing t, const char *id, int verbose, nsync_mu *mu, int expected_acquire, int release, int *value, int expected_value, counter *done) { int acquired = nsync_mu_rtrylock (mu); if (acquired != expected_acquire) { testing_panic (smprintf ("attempt_rtrylock %s: expected " "nsync_mu_rtrylock() to return %d but got %d", id, expected_acquire, acquired)); } if (verbose) { TEST_LOG (t, ("attempt_rtrylock %s %d\n", id, acquired)); } if (acquired) { nsync_mu_rassert_held (mu); if (expected_value != -1 && *value != expected_value) { testing_panic (smprintf ("attempt_rtrylock %s expected " "value %d, *value=%d", id, expected_value, *value)); } if (release) { nsync_mu_runlock (mu); } } counter_inc (done, -1); } CLOSURE_DECL_BODY9 (lock_unlock, testing, const char *, int, nsync_mu *, int *, int, nsync_time, counter *, counter *) /* First acquire *mu, then: - if expected_value != -1, compare *value against expected_value. - increment *value. - sleep for "sleep". Then release *mu and decrement *done. */ static void lock_unlock (testing t, const char *id, int verbose, nsync_mu *mu, int *value, int expected_value, nsync_time sleep, counter *sleeping, counter *done) { if (verbose) { TEST_LOG (t, ("lock_unlock %s\n", id)); } if (sleeping != NULL) { counter_inc (sleeping, -1); } nsync_mu_lock (mu); nsync_mu_assert_held (mu); if (expected_value != -1 && *value != expected_value) { testing_panic (smprintf ("lock_unlock %s expected " "value %d, *value=%d", id, expected_value, *value)); } (*value)++; if (verbose) { TEST_LOG (t, ("lock_unlock %s incremented value to %d\n", id, *value)); } nsync_time_sleep (sleep); nsync_mu_unlock (mu); counter_inc (done, -1); } /* First acquire *mu in read mode, then: - if expected_value != -1, compare *value against expected_value. - sleep for "sleep". Then release *mu and decrement *done. */ static void rlock_runlock (testing t, const char *id, int verbose, nsync_mu *mu, int *value, int expected_value, nsync_time sleep, counter *sleeping, counter *done) { if (verbose) { TEST_LOG (t, ("rlock_runlock %s\n", id)); } if (sleeping != NULL) { counter_inc (sleeping, -1); } nsync_mu_rlock (mu); nsync_mu_rassert_held (mu); if (expected_value != -1 && *value != expected_value) { testing_panic (smprintf ("rlock_runlock %s expected " "value %d, *value=%d", id, expected_value, *value)); } nsync_time_sleep (sleep); nsync_mu_runlock (mu); counter_inc (done, -1); } /* Check that the time since start_time is between expected_duration-1ms. If the time exceeds expected_duration+slop_duration, return 1, else 0. */ static int check_times (testing t, const char *id, nsync_time start_time, nsync_time expected_duration, nsync_time slop_duration) { int exceeds_count = 0; nsync_time now; nsync_time measured_duration; now = nsync_time_now (); measured_duration = nsync_time_sub (now, start_time); if (nsync_time_cmp (measured_duration, nsync_time_sub (expected_duration, nsync_time_ms (5))) < 0) { char *m_str = nsync_time_str (measured_duration, 2); char *e_str = nsync_time_str (expected_duration, 2); TEST_ERROR (t, ("check_times %s too short a delay: %s instead of %s", id, m_str, e_str)); free (m_str); free (e_str); } if (nsync_time_cmp (nsync_time_add (expected_duration, slop_duration), measured_duration) < 0) { exceeds_count++; } return (exceeds_count); } /* Check the operation of nsync_mu as a reader/writer lock. */ static void test_rlock (testing t) { int loop; int i; int max_write_wait_exceeded; int max_read_wait_exceeded; nsync_time time_unit; nsync_time slop_duration; nsync_time delay_duration; nsync_time writer_duration; nsync_time reader_duration; static const int loop_count = 5; static const int read_threads = 3; static const int limit = 3; static const int verbose = 0; max_write_wait_exceeded = 0; max_read_wait_exceeded = 0; time_unit = nsync_time_ms (100); slop_duration = nsync_time_add (nsync_time_add (time_unit, time_unit), time_unit); delay_duration = time_unit; writer_duration = time_unit; reader_duration = nsync_time_add (time_unit, time_unit); max_write_wait_exceeded = 0; max_read_wait_exceeded = 0; for (loop = 0; loop != loop_count; loop++) { counter *lock_unlock_sleeping; counter *rlock_runlock_sleeping; counter *lock_unlock_done; counter *rlock_runlock_done; nsync_time read_start_time; nsync_mu mu; int value = 0; counter *thread_done; nsync_time start_time; nsync_mu_init (&mu); start_time = nsync_time_now (); /* ------------------------------------ */ /* Acquire lock with nsync_mu_rtrylock(). This thread will hold a read lock until the next line with =====. */ thread_done = counter_new (1); attempt_rtrylock (t, "a", verbose, &mu, 1, 0, &value, 0, thread_done); counter_wait_for_zero (thread_done); nsync_mu_rassert_held (&mu); counter_inc (thread_done, 1); /* Can get read lock holding read lock. */ closure_fork (closure_attempt_trylock (&attempt_rtrylock, t, "b", verbose, &mu, 1, 1, &value, 0, thread_done)); counter_wait_for_zero (thread_done); nsync_mu_rassert_held (&mu); counter_inc (thread_done, 1); /* Can't get write lock holding read lock. */ closure_fork (closure_attempt_trylock (&attempt_trylock, t, "c", verbose, &mu, 0, 1, &value, -1, thread_done)); counter_wait_for_zero (thread_done); if (!nsync_mu_is_reader (&mu)) { TEST_FATAL(t, ("expected mu held in reader mode")); } counter_inc (thread_done, 1); closure_fork (closure_lock_unlock (&rlock_runlock, t, "d", verbose, &mu, &value, 0, nsync_time_zero /*no delay*/, NULL, thread_done)); counter_wait_for_zero (thread_done); nsync_mu_rassert_held (&mu); lock_unlock_done = counter_new (1); lock_unlock_sleeping = counter_new (1); closure_fork (closure_lock_unlock (&lock_unlock, t, "e", verbose, &mu, &value, 0, writer_duration, lock_unlock_sleeping, lock_unlock_done)); counter_wait_for_zero (lock_unlock_sleeping); nsync_time_sleep (delay_duration); /* give time for lock_unlock() thread to wait. */ nsync_mu_rassert_held (&mu); rlock_runlock_done = counter_new (read_threads); rlock_runlock_sleeping = counter_new (read_threads); for (i = 0; i != read_threads; i++) { /* read lock will be acquired after lock_unlock() completes */ closure_fork (closure_lock_unlock (&rlock_runlock, t, "f", verbose, &mu, &value, 1, reader_duration, rlock_runlock_sleeping, rlock_runlock_done)); } nsync_mu_rassert_held (&mu); counter_wait_for_zero (rlock_runlock_sleeping); nsync_time_sleep (delay_duration); /* time for rlock_runlock() threads to wait. */ nsync_mu_rassert_held (&mu); if (counter_value (lock_unlock_done) == 0) { TEST_FATAL (t, ("thread was able to acquire write lock while read lock held")); } if (counter_value (rlock_runlock_done) == 0) { TEST_FATAL (t, ("thread was able to acquire read lock with " "other reader and waiting writer")); } nsync_mu_rassert_held (&mu); counter_inc (thread_done, 1); /* Still can't get write lock. */ closure_fork (closure_attempt_trylock (&attempt_trylock, t, "g", verbose, &mu, 0, 1, &value, -1, thread_done)); counter_wait_for_zero (thread_done); counter_inc (thread_done, 1); /* Now can't get read lock because a writer is waiting. */ closure_fork (closure_attempt_trylock (&attempt_rtrylock, t, "h", verbose, &mu, 0, 1, &value, -1, thread_done)); counter_wait_for_zero (thread_done); nsync_mu_runlock (&mu); /* ==================================== */ read_start_time = nsync_time_now (); counter_wait_for_zero (lock_unlock_done); /* Now can get write lock. */ max_write_wait_exceeded += check_times (t, "i", start_time, nsync_time_add (nsync_time_add (delay_duration, delay_duration), writer_duration), slop_duration); counter_wait_for_zero (rlock_runlock_done); /* And now an get read lock again. */ max_read_wait_exceeded += check_times (t, "j", read_start_time, reader_duration, slop_duration); free (thread_done); free (lock_unlock_done); free (rlock_runlock_done); free (lock_unlock_sleeping); free (rlock_runlock_sleeping); } if (verbose) { TEST_LOG (t, ("read lock max_write_wait_exceeded %d max_read_wait_exceeded %d\n", max_write_wait_exceeded, max_read_wait_exceeded)); } if (max_write_wait_exceeded > limit) { TEST_ERROR (t, ("lock_unlock() took too long %d " "(more than %d) times out of %d", max_write_wait_exceeded, limit, loop_count)); } if (max_read_wait_exceeded > limit) { TEST_ERROR (t, ("rlock_runlock() took too long %d " "(more than %d) times out of %d", max_read_wait_exceeded, limit, loop_count)); } max_write_wait_exceeded = 0; max_read_wait_exceeded = 0; for (loop = 0; loop != loop_count; loop++) { counter *lock_unlock_sleeping; counter *rlock_runlock_sleeping; counter *lock_unlock_done; counter *rlock_runlock_done; nsync_time read_start_time; nsync_mu mu; int value = 0; counter *thread_done; nsync_time start_time; nsync_mu_init (&mu); start_time = nsync_time_now (); /* ------------------------------------ */ /* Acquire lock with nsync_mu_trylock(). This thread will hold a write lock until the next line with =====. */ thread_done = counter_new (1); attempt_trylock (t, "A", verbose, &mu, 1, 0, &value, 0, thread_done); counter_wait_for_zero (thread_done); nsync_mu_assert_held (&mu); nsync_mu_rassert_held (&mu); counter_inc (thread_done, 1); /* Can't get read lock while holding write lock. */ closure_fork (closure_attempt_trylock (&attempt_rtrylock, t, "B", verbose, &mu, 0, 1, &value, -1, thread_done)); counter_wait_for_zero (thread_done); if (nsync_mu_is_reader (&mu)) { TEST_FATAL (t, ("expected mu held in write mode")); } nsync_mu_assert_held (&mu); nsync_mu_rassert_held (&mu); counter_inc (thread_done, 1); /* Can't get write lock while holding write lock. */ closure_fork (closure_attempt_trylock (&attempt_trylock, t, "C", verbose, &mu, 0, 1, &value, -1, thread_done)); counter_wait_for_zero (thread_done); nsync_mu_assert_held (&mu); nsync_mu_rassert_held (&mu); lock_unlock_done = counter_new (1); lock_unlock_sleeping = counter_new (1); closure_fork (closure_lock_unlock (&lock_unlock, t, "D", verbose, &mu, &value, 1, writer_duration, lock_unlock_sleeping, lock_unlock_done)); counter_wait_for_zero (lock_unlock_sleeping); nsync_time_sleep (delay_duration); /* give time for lock_unlock() thread to wait. */ nsync_mu_assert_held (&mu); nsync_mu_rassert_held (&mu); rlock_runlock_done = counter_new (read_threads); rlock_runlock_sleeping = counter_new (read_threads); for (i = 0; i != read_threads; i++) { /* not guaranteed will complete after lock_unlock() above */ closure_fork (closure_lock_unlock (&rlock_runlock, t, "E", verbose, &mu, &value, -1, reader_duration, rlock_runlock_sleeping, rlock_runlock_done)); } nsync_mu_assert_held (&mu); nsync_mu_rassert_held (&mu); counter_wait_for_zero (rlock_runlock_sleeping); nsync_time_sleep (delay_duration); /* time for rlock_runlock() threads to wait. */ nsync_mu_assert_held (&mu); nsync_mu_rassert_held (&mu); if (counter_value (lock_unlock_done) == 0) { TEST_FATAL (t, ("thread was able to acquire write lock " "while other write lock held")); } if (counter_value (rlock_runlock_done) == 0) { TEST_FATAL (t, ("thread was able to acquire read lock " "while write lock held")); } nsync_mu_assert_held (&mu); nsync_mu_rassert_held (&mu); counter_inc (thread_done, 1); /* Still can't get read lock while holding write lock. */ closure_fork (closure_attempt_trylock (&attempt_rtrylock, t, "F", verbose, &mu, 0, 1, &value, -1, thread_done)); counter_wait_for_zero (thread_done); nsync_mu_assert_held (&mu); nsync_mu_rassert_held (&mu); counter_inc (thread_done, 1); /* Still can't get write lock while holding write lock. */ closure_fork (closure_attempt_trylock (&attempt_trylock, t, "G", verbose, &mu, 0, 1, &value, -1, thread_done)); counter_wait_for_zero (thread_done); nsync_mu_assert_held (&mu); nsync_mu_rassert_held (&mu); nsync_mu_unlock (&mu); /* ==================================== */ read_start_time = nsync_time_now (); counter_wait_for_zero (lock_unlock_done); /* Now can get write lock. */ max_write_wait_exceeded += check_times (t, "H", start_time, nsync_time_add (nsync_time_add (delay_duration, delay_duration), writer_duration), slop_duration); counter_wait_for_zero (rlock_runlock_done); /* And now can get read lock again. */ max_read_wait_exceeded += check_times (t, "I", read_start_time, reader_duration, slop_duration); free (thread_done); free (lock_unlock_done); free (rlock_runlock_done); free (lock_unlock_sleeping); free (rlock_runlock_sleeping); } if (verbose) { TEST_LOG (t, ("write lock max_write_wait_exceeded %d " "max_read_wait_exceeded %d\n", max_write_wait_exceeded, max_read_wait_exceeded)); } if (max_write_wait_exceeded > limit) { TEST_ERROR (t, ("lock_unlock() took too long %d (more than %d) " "times out of %d", max_write_wait_exceeded, limit, loop_count)); } if (max_read_wait_exceeded > limit) { TEST_ERROR (t, ("rlock_runlock() took too long %d (more than %d) " "times out of %d", max_read_wait_exceeded, limit, loop_count)); } } /* --------------------------------------- */ /* Measure the performance of an uncontended nsync_mu. */ static void benchmark_mu_uncontended (testing t) { int i; int n = testing_n (t); nsync_mu mu; nsync_mu_init (&mu); for (i = 0; i != n; i++) { nsync_mu_lock (&mu); nsync_mu_unlock (&mu); } } /* Return whether int *value is one. */ static int int_is_1 (const void *value) { return (*(const int *)value == 1); } /* Return whether int *value is two. */ static int int_is_2 (const void *value) { return (*(const int *)value == 2); } /* Return whether int *value is three. */ static int int_is_3 (const void *value) { return (*(const int *)value == 3); } /* Set *value to 1, wait for it to become 2, then set it to 3. *value is under *mu */ static void waiter (nsync_mu *mu, int *value) { nsync_mu_lock (mu); *value = 1; nsync_mu_wait (mu, &int_is_2, value, NULL); *value = 3; nsync_mu_unlock (mu); } CLOSURE_DECL_BODY2 (waiter, nsync_mu *, int *) /* Measure the performance of an uncontended nsync_mu with a blocked waiter. */ static void benchmark_mu_uncontended_waiter (testing t) { int i; int n = testing_n (t); nsync_mu mu; int value = 0; nsync_mu_init (&mu); closure_fork (closure_waiter (&waiter, &mu, &value)); nsync_mu_lock (&mu); nsync_mu_wait (&mu, &int_is_1, &value, NULL); nsync_mu_unlock (&mu); for (i = 0; i != n; i++) { nsync_mu_lock (&mu); nsync_mu_unlock (&mu); } nsync_mu_lock (&mu); value = 2; nsync_mu_wait (&mu, &int_is_3, &value, NULL); nsync_mu_unlock (&mu); } /* Measure the performance of an uncontended nsync_mu with a blocked waiter using nsync_mu_unlock_without_wakeup. */ static void benchmark_mu_uncontended_no_wakeup (testing t) { int i; int n = testing_n (t); nsync_mu mu; int value = 0; nsync_mu_init (&mu); closure_fork (closure_waiter (&waiter, &mu, &value)); nsync_mu_lock (&mu); nsync_mu_wait (&mu, &int_is_1, &value, NULL); nsync_mu_unlock (&mu); for (i = 0; i != n; i++) { nsync_mu_lock (&mu); nsync_mu_unlock_without_wakeup (&mu); } nsync_mu_lock (&mu); value = 2; nsync_mu_wait (&mu, &int_is_3, &value, NULL); nsync_mu_unlock (&mu); } /* Measure the performance of an uncontended nsync_mu in read mode. */ static void benchmark_rmu_uncontended (testing t) { int i; int n = testing_n (t); nsync_mu mu; nsync_mu_init (&mu); for (i = 0; i != n; i++) { nsync_mu_rlock (&mu); nsync_mu_runlock (&mu); } } /* Measure the performance of an uncontended nsync_mu in read mode with a blocked waiter. */ static void benchmark_rmu_uncontended_waiter (testing t) { int i; int n = testing_n (t); nsync_mu mu; int value = 0; nsync_mu_init (&mu); closure_fork (closure_waiter (&waiter, &mu, &value)); nsync_mu_lock (&mu); nsync_mu_wait (&mu, &int_is_1, &value, NULL); nsync_mu_unlock (&mu); for (i = 0; i != n; i++) { nsync_mu_rlock (&mu); nsync_mu_runlock (&mu); } nsync_mu_lock (&mu); value = 2; nsync_mu_wait (&mu, &int_is_3, &value, NULL); nsync_mu_unlock (&mu); } /* Measure the performance of an uncontended pthread_mutex_t. */ static void benchmark_mutex_uncontended (testing t) { int i; int n = testing_n (t); pthread_mutex_t mu; pthread_mutex_init (&mu, NULL); for (i = 0; i != n; i++) { pthread_mutex_lock (&mu); pthread_mutex_unlock (&mu); } pthread_mutex_destroy (&mu); } /* Measure the performance of an uncontended pthread_rwlock_t. */ static void benchmark_wmutex_uncontended (testing t) { int i; int n = testing_n (t); pthread_rwlock_t mu; pthread_rwlock_init (&mu, NULL); for (i = 0; i != n; i++) { pthread_rwlock_wrlock (&mu); pthread_rwlock_unlock (&mu); } pthread_rwlock_destroy (&mu); } /* Measure the performance of an uncontended pthread_rwlock_t in read mode. */ static void benchmark_rmutex_uncontended (testing t) { int i; int n = testing_n (t); pthread_rwlock_t mu; pthread_rwlock_init (&mu, NULL); for (i = 0; i != n; i++) { pthread_rwlock_rdlock (&mu); pthread_rwlock_unlock (&mu); } pthread_rwlock_destroy (&mu); } /* --------------------------------------- Benchmarks for contended locks. */ /* It's hard to write these as benchmark functions, since we wish to measure throughput over an extended period (a second or two), rather than get the latency of a few iterations. */ /* A contended_state represents state shared between threads in the contended benchmarks. */ typedef struct contended_state_s { testing t; /* locks to test */ nsync_mu mu; pthread_mutex_t mutex; pthread_rwlock_t rwmutex; int count; /* counter protected by a lock above */ nsync_mu start_done_mu; int start; /* whether threads should start, under start_done_mu */ int not_yet_done; /* threads not yet complete, under start_done_mu */ } contended_state; static int contended_state_may_start (const void *v) { return (((const contended_state *)v)->start); } static int contended_state_all_done (const void *v) { return (((const contended_state *)v)->not_yet_done == 0); } /* Wait for cs.start to become non-zero, then loop, acquiring and releasing mu on each iteration until cs.deadline is reached, then decrement cs.not_yet_done. */ static void contended_state_contend_loop (contended_state *cs, void *mu, void (*lock) (void *), void (*unlock) (void *)) { int n = testing_n (cs->t); int j; int i; nsync_mu_rlock (&cs->start_done_mu); nsync_mu_wait (&cs->start_done_mu, &contended_state_may_start, cs, NULL); nsync_mu_runlock (&cs->start_done_mu); for (j = 0; j < n; j += 10000) { for (i = 0; i != 10000; i++) { (*lock) (mu); cs->count++; (*unlock) (mu); } } nsync_mu_lock (&cs->start_done_mu); cs->not_yet_done--; nsync_mu_unlock (&cs->start_done_mu); } typedef void (*func_any) (void *); CLOSURE_DECL_BODY4 (contended_state_contend_loop, contended_state *, void *, func_any, func_any) /* Start the threads in a contended test, wait for them to finish, and print the number of iterations achieved. */ static void contended_state_run_test (contended_state *cs, testing t, void *mu, void (*lock) (void *), void (*unlock) (void *)) { int i; cs->t = t; cs->not_yet_done = 4; /* number of threads */ cs->start = 0; cs->count = 0; for (i = 0; i != cs->not_yet_done; i++) { closure_fork (closure_contended_state_contend_loop ( &contended_state_contend_loop, cs, mu, lock, unlock)); } nsync_mu_lock (&cs->start_done_mu); cs->start = 1; nsync_mu_wait (&cs->start_done_mu, &contended_state_all_done, cs, NULL); nsync_mu_unlock (&cs->start_done_mu); } /* Measure the performance of highly contended nsync_mu locks, with small critical sections. */ static void benchmark_mu_contended (testing t) { contended_state cs; memset ((void *) &cs, 0, sizeof (cs)); contended_state_run_test (&cs, t, &cs.mu, (void (*) (void*))&nsync_mu_lock, (void (*) (void*))&nsync_mu_unlock); } /* Measure the performance of highly contended pthread_mutex_t locks, with small critical sections. */ static void benchmark_mutex_contended (testing t) { contended_state cs; memset ((void *) &cs, 0, sizeof (cs)); pthread_mutex_init (&cs.mutex, NULL); contended_state_run_test (&cs, t, &cs.mutex, &void_pthread_mutex_lock, &void_pthread_mutex_unlock); pthread_mutex_destroy (&cs.mutex); } /* Measure the performance of highly contended pthread_rwlock_t locks, with small critical sections. */ static void benchmark_wmutex_contended (testing t) { contended_state cs; memset ((void *) &cs, 0, sizeof (cs)); pthread_rwlock_init (&cs.rwmutex, NULL); contended_state_run_test (&cs, t, &cs.rwmutex, &void_pthread_rwlock_wrlock, &void_pthread_rwlock_unlock); pthread_rwlock_destroy (&cs.rwmutex); } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_rlock); TEST_RUN (tb, test_mu_nthread); TEST_RUN (tb, test_mutex_nthread); TEST_RUN (tb, test_rwmutex_nthread); TEST_RUN (tb, test_try_mu_nthread); BENCHMARK_RUN (tb, benchmark_mu_contended); BENCHMARK_RUN (tb, benchmark_mutex_contended); BENCHMARK_RUN (tb, benchmark_wmutex_contended); BENCHMARK_RUN (tb, benchmark_mu_uncontended); BENCHMARK_RUN (tb, benchmark_rmu_uncontended); BENCHMARK_RUN (tb, benchmark_mutex_uncontended); BENCHMARK_RUN (tb, benchmark_wmutex_uncontended); BENCHMARK_RUN (tb, benchmark_rmutex_uncontended); BENCHMARK_RUN (tb, benchmark_mu_uncontended_waiter); BENCHMARK_RUN (tb, benchmark_mu_uncontended_no_wakeup); BENCHMARK_RUN (tb, benchmark_rmu_uncontended_waiter); return (testing_base_exit (tb)); } nsync-1.24.0/testing/mu_wait_example_test.c000066400000000000000000000131201367521742200207760ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "compiler.h" #include "nsync.h" #include "time_extra.h" #include "smprintf.h" #include "testing.h" #include "closure.h" #include "array.h" #include "heap.h" NSYNC_CPP_USING_ /* Example use of nsync_mu_wait(): A priority queue of strings whose "remove_with_deadline" operation has a deadline. */ /* --------------------------------------- */ /* An array used as a heap of strings. */ typedef A_TYPE (const char *) a_string; static int str_lt (const char *e0, const char *e1) { return (strcmp (e0, e1) < 0); } static void no_set (const char *a UNUSED, int b UNUSED) { } /* --------------------------------------- */ /* A priority queue of strings, which emits the lexicographically least string available. */ typedef struct string_priority_queue_mu_s { nsync_mu mu; /* protects heap */ a_string heap; } string_priority_queue_mu; /* A wait condition for non-empty. */ static int spq_is_non_empty (const void *v) { const string_priority_queue_mu *q = (const string_priority_queue_mu *) v; return (A_LEN (&q->heap) != 0); } /* Adds "s" to the queue *q. */ static void string_priority_queue_mu_add (string_priority_queue_mu *q, const char *s) { int alen; nsync_mu_lock (&q->mu); alen = A_LEN (&q->heap); A_PUSH (&q->heap) = s; heap_add (&A (&q->heap, 0), alen, str_lt, no_set, s); nsync_mu_unlock (&q->mu); } /* Wait until queue *q is non-empty, then remove a string from its beginning, and return it; or if abs_deadline is reached before the queue becomes non-empty, return NULL. */ static const char *string_priority_queue_mu_remove_with_deadline ( string_priority_queue_mu *q, nsync_time abs_deadline) { const char *s = NULL; nsync_mu_lock (&q->mu); if (nsync_mu_wait_with_deadline (&q->mu, &spq_is_non_empty, q, NULL, abs_deadline, NULL) == 0) { int alen = A_LEN (&q->heap); if (alen != 0) { s = A (&q->heap, 0); heap_remove (&A (&q->heap, 0), alen, str_lt, no_set, 0); A_DISCARD (&q->heap, 1); } } nsync_mu_unlock (&q->mu); return (s); } /* Free resources associates with *q */ static void string_priority_queue_mu_destroy (string_priority_queue_mu *q) { A_FREE (&q->heap); } /* --------------------------------------- */ /* Add strings s[0, ..., n-1] to *q, with the specified delay between additions. */ static void add_and_wait_mu (string_priority_queue_mu *q, nsync_time delay, int n, const char *s[]) { int i; for (i = 0; i != n; i++) { string_priority_queue_mu_add (q, s[i]); nsync_time_sleep (delay); } } CLOSURE_DECL_BODY4 (add_and_wait_mu, string_priority_queue_mu *, nsync_time, int, const char **) typedef A_TYPE (char) a_char; static void a_char_append (a_char *a, const char *str) { while (*str != 0) { A_PUSH (a) = *str; str++; } } /* Remove the first item from *q and output it on stdout, or output "timeout: " if no value can be found before "delay" elapses. */ static void remove_and_print_mu (string_priority_queue_mu *q, nsync_time delay, a_char *output) { const char *s; if ((s = string_priority_queue_mu_remove_with_deadline (q, nsync_time_add (nsync_time_now (), delay))) != NULL) { a_char_append (output, s); a_char_append (output, "\n"); } else { char buf[64]; snprintf (buf, sizeof (buf), "timeout %gs\n", nsync_time_to_dbl (delay)); a_char_append (output, buf); } } /* Demonstrate the use of nsync_mu_wait() via a priority queue of strings. See the routine string_priority_queue_mu_remove_with_deadline(), above. */ static void example_mu_wait (testing t) { static const char *input[] = { "one", "two", "three", "four", "five" }; string_priority_queue_mu q; a_char output; static const char *expected = "one\n" "three\n" "two\n" "timeout 0.1s\n" "four\n" "timeout 0.1s\n" "five\n" "timeout 1s\n"; memset ((void *) &q, 0, sizeof (q)); memset (&output, 0, sizeof (output)); closure_fork (closure_add_and_wait_mu (&add_and_wait_mu, &q, nsync_time_ms (500), NELEM (input), input)); /* delay: "one", "two", "three"; not yet "four" */ nsync_time_sleep (nsync_time_ms (1200)); remove_and_print_mu (&q, nsync_time_ms (1000), &output); /* "one" */ remove_and_print_mu (&q, nsync_time_ms (1000), &output); /* "three" (less than "two") */ remove_and_print_mu (&q, nsync_time_ms (1000), &output); /* "two" */ remove_and_print_mu (&q, nsync_time_ms (100), &output); /* time out because 1.3 < 0.5*3 */ remove_and_print_mu (&q, nsync_time_ms (1000), &output); /* "four" */ remove_and_print_mu (&q, nsync_time_ms (100), &output); /* time out because 0.1 < 0.5 */ remove_and_print_mu (&q, nsync_time_ms (1000), &output); /* "five" */ remove_and_print_mu (&q, nsync_time_ms (1000), &output); /* time out: no more to fetch */ A_PUSH (&output) = 0; if (strcmp (&A (&output, 0), expected) != 0) { TEST_ERROR (t, ("expected = %s\ngot = %s\n", expected, &A (&output, 0))); } A_FREE (&output); string_priority_queue_mu_destroy (&q); } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, example_mu_wait); return (testing_base_exit (tb)); } nsync-1.24.0/testing/mu_wait_test.c000066400000000000000000000263771367521742200173050ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "compiler.h" #include "nsync.h" #include "time_extra.h" #include "smprintf.h" #include "testing.h" #include "closure.h" NSYNC_CPP_USING_ /* --------------------------- */ /* A FIFO queue with up to limit elements. The storage for the queue expands as necessary up to limit. */ typedef struct mu_queue_s { int limit; /* max value of count---should not be changed after initialization */ nsync_mu mu; /* protects fields below */ int pos; /* index of first in-use element */ int count; /* number of elements in use */ void *data[1]; /* in use elements are data[pos, ..., (pos+count-1)%limit] */ } mu_queue; /* Return a pointer to new mu_queue. */ static mu_queue *mu_queue_new (int limit) { mu_queue *q; int size = offsetof (struct mu_queue_s, data) + sizeof (q->data[0]) * limit; q = (mu_queue *) malloc (size); memset ((void *) q, 0, size); q->limit = limit; return (q); } static int mu_queue_non_empty (const void *v) { const mu_queue *q = (const mu_queue *) v; return (q->count != 0); } static int mu_queue_non_full (const void *v) { const mu_queue *q = (const mu_queue *) v; return (q->count != q->limit); } /* Add v to the end of the FIFO *q and return non-zero, or if the FIFO already has limit elements and continues to do so until abs_deadline, do nothing and return 0. */ static int mu_queue_put (mu_queue *q, void *v, nsync_time abs_deadline) { int added = 0; nsync_mu_lock (&q->mu); if (nsync_mu_wait_with_deadline (&q->mu, &mu_queue_non_full, q, NULL, abs_deadline, NULL) == 0) { int i = q->pos + q->count; if (q->count == q->limit) { testing_panic ("q->count == q->limit"); } if (q->limit <= i) { i -= q->limit; } q->data[i] = v; q->count++; added = 1; } nsync_mu_unlock (&q->mu); return (added); } /* Remove the first value from the front of the FIFO *q and return it, or if the FIFO is empty and continues to be so until abs_deadline, do nothing and return NULL. */ static void *mu_queue_get (mu_queue *q, nsync_time abs_deadline) { void *v = NULL; nsync_mu_lock (&q->mu); if (nsync_mu_wait_with_deadline (&q->mu, &mu_queue_non_empty, q, NULL, abs_deadline, NULL) == 0) { if (q->count == 0) { testing_panic ("q->count == 0"); } v = q->data[q->pos]; q->data[q->pos] = NULL; q->pos++; q->count--; if (q->pos == q->limit) { q->pos = 0; } } nsync_mu_unlock (&q->mu); return (v); } /* --------------------------- */ static char ptr_to_int_c; #define INT_TO_PTR(x) ((x) + &ptr_to_int_c) #define PTR_TO_INT(p) (((char *) (p)) - &ptr_to_int_c) /* Put count integers on *q, in the sequence start*3, (start+1)*3, (start+2)*3, .... */ static void producer_mu_n (testing t, mu_queue *q, int start, int count) { int i; for (i = 0; i != count; i++) { if (!mu_queue_put (q, INT_TO_PTR ((start+i)*3), nsync_time_no_deadline)) { TEST_FATAL (t, ("mu_queue_put() returned 0 with no deadline")); } } } CLOSURE_DECL_BODY4 (producer_mu_n, testing , mu_queue *, int, int) /* Get count integers from *q, and check that they are in the sequence start*3, (start+1)*3, (start+2)*3, .... */ static void consumer_mu_n (testing t, mu_queue *q, int start, int count) { int i; for (i = 0; i != count; i++) { void *v = mu_queue_get (q, nsync_time_no_deadline); int x; if (v == NULL) { TEST_FATAL (t, ("mu_queue_get() returned 0 with no deadline")); } x = PTR_TO_INT (v); if (x != (start+i)*3) { TEST_FATAL (t, ("mu_queue_get() returned bad value; want %d, got %d", (start+i)*3, x)); } } } /* The number of elements passed from producer to consumer in the test_mu_producer_consumer*() tests below. */ #define MU_PRODUCER_CONSUMER_N (100000) /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**0. */ static void test_mu_producer_consumer0 (testing t) { mu_queue *q = mu_queue_new (1); closure_fork (closure_producer_mu_n (&producer_mu_n, t, q, 0, MU_PRODUCER_CONSUMER_N)); consumer_mu_n (t, q, 0, MU_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**1. */ static void test_mu_producer_consumer1 (testing t) { mu_queue *q = mu_queue_new (10); closure_fork (closure_producer_mu_n (&producer_mu_n, t, q, 0, MU_PRODUCER_CONSUMER_N)); consumer_mu_n (t, q, 0, MU_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**2. */ static void test_mu_producer_consumer2 (testing t) { mu_queue *q = mu_queue_new (100); closure_fork (closure_producer_mu_n (&producer_mu_n, t, q, 0, MU_PRODUCER_CONSUMER_N)); consumer_mu_n (t, q, 0, MU_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**3. */ static void test_mu_producer_consumer3 (testing t) { mu_queue *q = mu_queue_new (1000); closure_fork (closure_producer_mu_n (&producer_mu_n, t, q, 0, MU_PRODUCER_CONSUMER_N)); consumer_mu_n (t, q, 0, MU_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**4. */ static void test_mu_producer_consumer4 (testing t) { mu_queue *q = mu_queue_new (10000); closure_fork (closure_producer_mu_n (&producer_mu_n, t, q, 0, MU_PRODUCER_CONSUMER_N)); consumer_mu_n (t, q, 0, MU_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**5. */ static void test_mu_producer_consumer5 (testing t) { mu_queue *q = mu_queue_new (100000); closure_fork (closure_producer_mu_n (&producer_mu_n, t, q, 0, MU_PRODUCER_CONSUMER_N)); consumer_mu_n (t, q, 0, MU_PRODUCER_CONSUMER_N); free (q); } /* Send a stream of integers from a producer thread to a consumer thread via a queue with limit 10**6. */ static void test_mu_producer_consumer6 (testing t) { mu_queue *q = mu_queue_new (1000000); closure_fork (closure_producer_mu_n (&producer_mu_n, t, q, 0, MU_PRODUCER_CONSUMER_N)); consumer_mu_n (t, q, 0, MU_PRODUCER_CONSUMER_N); free (q); } /* A perpetually false wait condition. */ static int false_condition (const void *v UNUSED) { return (0); } /* The following values control how aggressively we police the timeout. */ #define TOO_EARLY_MS 1 #define TOO_LATE_MS 100 /* longer, to accommodate scheduling delays */ #define TOO_LATE_ALLOWED 25 /* number of iterations permitted to violate too_late */ /* Check timeouts on a mu wait_with_deadline(). */ static void test_mu_deadline (testing t) { int i; int too_late_violations; nsync_mu mu; nsync_time too_early; nsync_time too_late; nsync_mu_init (&mu); too_early = nsync_time_ms (TOO_EARLY_MS); too_late = nsync_time_ms (TOO_LATE_MS); too_late_violations = 0; nsync_mu_lock (&mu);; for (i = 0; i != 50; i++) { nsync_time end_time; nsync_time start_time; nsync_time expected_end_time; start_time = nsync_time_now (); expected_end_time = nsync_time_add (start_time, nsync_time_ms (87)); if (nsync_mu_wait_with_deadline (&mu, &false_condition, NULL, NULL, expected_end_time, NULL) != ETIMEDOUT) { TEST_FATAL (t, ("nsync_mu_wait() returned non-expired for a timeout")); } end_time = nsync_time_now (); if (nsync_time_cmp (end_time, nsync_time_sub (expected_end_time, too_early)) < 0) { char *elapsed_str = nsync_time_str (nsync_time_sub (expected_end_time, end_time), 2); TEST_ERROR (t, ("nsync_mu_wait() returned %s too early", elapsed_str)); free (elapsed_str); } if (nsync_time_cmp (nsync_time_add (expected_end_time, too_late), end_time) < 0) { too_late_violations++; } } nsync_mu_unlock (&mu); if (too_late_violations > TOO_LATE_ALLOWED) { TEST_ERROR (t, ("nsync_mu_wait() returned too late %d (> %d) times", too_late_violations, TOO_LATE_ALLOWED)); } } /* Check cancellations on a mu wait_with_deadline(). */ static void test_mu_cancel (testing t) { int i; nsync_time future_time; int too_late_violations; nsync_mu mu; nsync_time too_early; nsync_time too_late; nsync_mu_init (&mu); too_early = nsync_time_ms (TOO_EARLY_MS); too_late = nsync_time_ms (TOO_LATE_MS); /* The loops below cancel after 87 milliseconds, like the timeout tests above. */ future_time = nsync_time_add (nsync_time_now (), nsync_time_ms (3600000)); /* test cancels with timeout */ too_late_violations = 0; nsync_mu_lock (&mu); for (i = 0; i != 50; i++) { nsync_time end_time; nsync_time start_time; nsync_time expected_end_time; int x; nsync_note cancel; start_time = nsync_time_now (); expected_end_time = nsync_time_add (start_time, nsync_time_ms (87)); cancel = nsync_note_new (NULL, expected_end_time); x = nsync_mu_wait_with_deadline (&mu, &false_condition, NULL, NULL, future_time, cancel); if (x != ECANCELED) { TEST_FATAL (t, ("nsync_mu_wait() return non-cancelled (%d) for " "a cancellation; expected %d", x, ECANCELED)); } end_time = nsync_time_now (); if (nsync_time_cmp (end_time, nsync_time_sub (expected_end_time, too_early)) < 0) { char *elapsed_str = nsync_time_str (nsync_time_sub (expected_end_time, end_time), 2); TEST_ERROR (t, ("nsync_mu_wait() returned %s too early", elapsed_str)); free (elapsed_str); } if (nsync_time_cmp (nsync_time_add (expected_end_time, too_late), end_time) < 0) { too_late_violations++; } /* Check that an already cancelled wait returns immediately. */ start_time = nsync_time_now (); x = nsync_mu_wait_with_deadline (&mu, &false_condition, NULL, NULL, nsync_time_no_deadline, cancel); if (x != ECANCELED) { TEST_FATAL (t, ("nsync_mu_wait() returned non-cancelled for a " "cancellation; expected %d", x, ECANCELED)); } end_time = nsync_time_now (); if (nsync_time_cmp (end_time, start_time) < 0) { char *elapsed_str = nsync_time_str (nsync_time_sub (expected_end_time, end_time), 2); TEST_ERROR (t, ("nsync_mu_wait() returned %s too early", elapsed_str)); free (elapsed_str); } if (nsync_time_cmp (nsync_time_add (start_time, too_late), end_time) < 0) { too_late_violations++; } nsync_note_free (cancel); } nsync_mu_unlock (&mu); if (too_late_violations > TOO_LATE_ALLOWED) { TEST_ERROR (t, ("nsync_mu_wait() returned too late %d (> %d) times", too_late_violations, TOO_LATE_ALLOWED)); } } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_mu_producer_consumer0); TEST_RUN (tb, test_mu_producer_consumer1); TEST_RUN (tb, test_mu_producer_consumer2); TEST_RUN (tb, test_mu_producer_consumer3); TEST_RUN (tb, test_mu_producer_consumer4); TEST_RUN (tb, test_mu_producer_consumer5); TEST_RUN (tb, test_mu_producer_consumer6); TEST_RUN (tb, test_mu_deadline); TEST_RUN (tb, test_mu_cancel); return (testing_base_exit (tb)); } nsync-1.24.0/testing/note_test.c000066400000000000000000000255151367521742200165760ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "nsync.h" #include "time_extra.h" #include "smprintf.h" #include "closure.h" #include "testing.h" NSYNC_CPP_USING_ /* Verify the properties of a prenotified note. */ static void test_note_prenotified (testing t) { int i; nsync_note n = nsync_note_new (NULL, nsync_time_zero /* prenotified */); nsync_time expiry; expiry = nsync_note_expiry (n); if (nsync_time_cmp (expiry, nsync_time_zero) != 0) { TEST_ERROR (t, ("prenotified note time mismatch 0")); } for (i = 0; i != 2; i++) { if (!nsync_note_is_notified (n)) { TEST_ERROR (t, ("prenotified note is not notified (test, %d)", i)); } if (!nsync_note_wait (n, nsync_time_zero)) { TEST_ERROR (t, ("prenotified note is not notified (poll, %d)", i)); } if (!nsync_note_wait (n, nsync_time_no_deadline)) { TEST_ERROR (t, ("prenotified note is not notified (infinite wait, %d)", i)); } nsync_note_notify (n); } expiry = nsync_note_expiry (n); if (nsync_time_cmp (expiry, nsync_time_zero) != 0) { TEST_ERROR (t, ("prenotified note time mismatch 1")); } nsync_note_free (n); } /* Verify the properties of a unnotified note. */ static void test_note_unnotified (testing t) { nsync_time start; nsync_time waited; nsync_time deadline; nsync_note n = nsync_note_new (NULL, nsync_time_no_deadline); nsync_time expiry; expiry = nsync_note_expiry (n); if (nsync_time_cmp (expiry, nsync_time_no_deadline) != 0) { TEST_ERROR (t, ("unnotified note time mismatch 0")); } if (nsync_note_is_notified (n)) { TEST_ERROR (t, ("unnotified note is notified (test)")); } if (nsync_note_wait (n, nsync_time_zero)) { TEST_ERROR (t, ("notified note is notified (poll)")); } start = nsync_time_now (); deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (1000)); if (nsync_note_wait (n, deadline)) { TEST_ERROR (t, ("unnotified note is notified (1s wait)")); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("timed wait on unnotified note returned too quickly (1s wait took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed wait on unnotified note returned too slowly (1s wait took %s)", nsync_time_str (waited, 2))); } nsync_note_notify (n); if (!nsync_note_is_notified (n)) { TEST_ERROR (t, ("notified note is not notified (test)")); } if (!nsync_note_wait (n, nsync_time_zero)) { TEST_ERROR (t, ("notified note is not notified (poll)")); } if (!nsync_note_wait (n, nsync_time_no_deadline)) { TEST_ERROR (t, ("notified note is not notified (infinite wait)")); } expiry = nsync_note_expiry (n); if (nsync_time_cmp (expiry, nsync_time_no_deadline) != 0) { TEST_ERROR (t, ("unnotified note time mismatch 1")); } nsync_note_free (n); } /* Test expiry on a note. */ static void test_note_expiry (testing t) { nsync_time start; nsync_time waited; nsync_time deadline; nsync_note n; deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (1000)); n = nsync_note_new (NULL, deadline); start = nsync_time_now (); if (!nsync_note_wait (n, nsync_time_no_deadline)) { TEST_ERROR (t, ("expired note is not notified")); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("note expired too quickly (1s expiry took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed expired too slowly (1s expiry took %s)", nsync_time_str (waited, 2))); } if (!nsync_note_is_notified (n)) { TEST_ERROR (t, ("expired note note is not notified (test)")); } if (!nsync_note_wait (n, nsync_time_zero)) { TEST_ERROR (t, ("expired note note is not notified (poll)")); } if (!nsync_note_wait (n, nsync_time_no_deadline)) { TEST_ERROR (t, ("expired note note is not notified (infinite wait)")); } nsync_note_free (n); deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (1000)); n = nsync_note_new (NULL, deadline); start = nsync_time_now (); while (!nsync_note_is_notified (n)) { nsync_time_sleep (nsync_time_ms (10)); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("note expired too quickly (1s expiry took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed expired too slowly (1s expiry took %s)", nsync_time_str (waited, 2))); } if (!nsync_note_is_notified (n)) { TEST_ERROR (t, ("expired note note is not notified (test)")); } if (!nsync_note_wait (n, nsync_time_zero)) { TEST_ERROR (t, ("expired note note is not notified (poll)")); } if (!nsync_note_wait (n, nsync_time_no_deadline)) { TEST_ERROR (t, ("expired note note is not notified (infinite wait)")); } nsync_note_free (n); } static void notify_at (nsync_note n, nsync_time abs_deadline) { nsync_time_sleep_until (abs_deadline); nsync_note_notify (n); } CLOSURE_DECL_BODY2 (notify, nsync_note, nsync_time) /* Test notification of a note. */ static void test_note_notify (testing t) { nsync_time start; nsync_time waited; nsync_time deadline; nsync_note n; deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (10000)); n = nsync_note_new (NULL, deadline); closure_fork (closure_notify (¬ify_at, n, nsync_time_add (nsync_time_now (), nsync_time_ms (1000)))); start = nsync_time_now (); if (!nsync_note_wait (n, nsync_time_no_deadline)) { TEST_ERROR (t, ("expired note is not notified")); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("note expired too quickly (1s expiry took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed expired too slowly (1s expiry took %s)", nsync_time_str (waited, 2))); } if (!nsync_note_is_notified (n)) { TEST_ERROR (t, ("expired note note is not notified (test)")); } if (!nsync_note_wait (n, nsync_time_zero)) { TEST_ERROR (t, ("expired note note is not notified (poll)")); } if (!nsync_note_wait (n, nsync_time_no_deadline)) { TEST_ERROR (t, ("expired note note is not notified (infinite wait)")); } nsync_note_free (n); deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (10000)); n = nsync_note_new (NULL, deadline); closure_fork (closure_notify (¬ify_at, n, nsync_time_add (nsync_time_now (), nsync_time_ms (1000)))); start = nsync_time_now (); while (!nsync_note_is_notified (n)) { nsync_time_sleep (nsync_time_ms (10)); } waited = nsync_time_sub (nsync_time_now (), start); if (nsync_time_cmp (waited, nsync_time_ms (900)) < 0) { TEST_ERROR (t, ("note expired too quickly (1s expiry took %s)", nsync_time_str (waited, 2))); } if (nsync_time_cmp (waited, nsync_time_ms (2000)) > 0) { TEST_ERROR (t, ("timed expired too slowly (1s expiry took %s)", nsync_time_str (waited, 2))); } if (!nsync_note_is_notified (n)) { TEST_ERROR (t, ("expired note note is not notified (test)")); } if (!nsync_note_wait (n, nsync_time_zero)) { TEST_ERROR (t, ("expired note note is not notified (poll)")); } if (!nsync_note_wait (n, nsync_time_no_deadline)) { TEST_ERROR (t, ("expired note note is not notified (infinite wait)")); } nsync_note_free (n); } /* Test notification of parent/child note. */ static void test_note_in_tree (testing t) { int i; enum { /* Indexes of nodes that form a heap in the array node[]. */ parent_i = 0, focus_i = 1, sibling_i = 2, child0_i = 3, child1_i = 4, nephew0_i = 5, nephew1_i = 6, grandchild00 = 7, grandchild01 = 8, grandchild10 = 9, grandchild11 = 10, count_i = 11 }; nsync_note node[count_i]; /* Initialize heap structure in the nodes. No deadlines. */ node[0] = nsync_note_new (NULL, nsync_time_no_deadline); for (i = 1; i != count_i; i++) { node[i] = nsync_note_new (node[(i-1)/2], nsync_time_no_deadline); } /* check that the nodes are not yet notified. */ for (i = 0; i != count_i; i++) { if (nsync_note_is_notified (node[i])) { TEST_ERROR (t, ("unnotified note %d is notified", i)); } } /* Notify the focus node */ nsync_note_notify (node[focus_i]); /* Check that the right nodes have been notified. */ for (i = 0; i != count_i; i++) { int is_notified = nsync_note_is_notified (node[i]); if (i == parent_i || i == sibling_i || i == nephew0_i || i == nephew1_i) { /* Parent, sibling, and nephew nodes should not have been notified. */ if (is_notified) { TEST_ERROR (t, ("unnotified note %d is notified", i)); } } else if (!is_notified) { /* But the node and its descendents should be. */ TEST_ERROR (t, ("notified note %d is not notified", i)); } } for (i = 0; i != count_i; i++) { nsync_note_free (node[i]); } /* Initialize heap structure in the nodes. The focus node has a 1s deadline. */ node[0] = nsync_note_new (NULL, nsync_time_no_deadline); for (i = 1; i != count_i; i++) { nsync_time deadline; deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (1000)); if (i != focus_i) { deadline = nsync_time_no_deadline; } node[i] = nsync_note_new (node[(i - 1) / 2], deadline); } /* check that the nodes are not yet notified. */ for (i = 0; i != count_i; i++) { if (nsync_note_is_notified (node[i])) { TEST_ERROR (t, ("unnotified note %d is notified", i)); } } /* Wait for timer to go off. */ nsync_time_sleep (nsync_time_ms (1100)); /* Check that the right nodes have been notified. */ for (i = 0; i != count_i; i++) { int is_notified = nsync_note_is_notified (node[i]); if (i == parent_i || i == sibling_i || i == nephew0_i || i == nephew1_i) { /* Parent, sibling, and nephew nodes should not have been notified. */ if (is_notified) { TEST_ERROR (t, ("unnotified note %d is notified", i)); } } else if (!is_notified) { /* But the node and its descendents should be. */ TEST_ERROR (t, ("notified note %d is not notified", i)); } } for (i = 0; i != count_i; i++) { nsync_note_free (node[i]); } } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_note_prenotified); TEST_RUN (tb, test_note_unnotified); TEST_RUN (tb, test_note_expiry); TEST_RUN (tb, test_note_notify); TEST_RUN (tb, test_note_in_tree); return (testing_base_exit (tb)); } nsync-1.24.0/testing/once_test.c000066400000000000000000000125511367521742200165510ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* This tests nsync_once */ #include "platform.h" #include "nsync.h" #include "testing.h" #include "closure.h" #include "smprintf.h" NSYNC_CPP_USING_ /* Data structure for each test of nsync_once */ struct once_test_s { nsync_once once; /* the nsync_once under test */ int counter; /* a counter that should be incremented once */ nsync_counter done; /* reaches 0 when all threads done */ testing t; /* the test handle */ }; /* Per-thread data structure */ struct once_test_thread_s { int id; /* thread id */ struct once_test_s *s; /* the per-test structure */ }; #define N 4 /* number of threads used per test */ static struct once_test_thread_s ott[N]; /* data structure per thread */ static nsync_mu ott_s_mu = NSYNC_MU_INIT; /* Increment s->counter by a power of two chosen by the thread id. Called via one of the nsync_run_once* calls. */ static void once_arg_func (void *v) { struct once_test_thread_s *lott = (struct once_test_thread_s *) v; struct once_test_s *s; nsync_mu_lock (&ott_s_mu); s = lott->s; nsync_mu_unlock (&ott_s_mu); if (s->counter != 0) { TEST_ERROR (s->t, ("once_arg_func found counter!=0")); } s->counter += 1 << (2 * lott->id); } /* Call once_arg_func() on the first thread structure. */ static void once_func0 (void) { once_arg_func (&ott[0]); } /* Call once_arg_func() on the second thread structure. */ static void once_func1 (void) { once_arg_func (&ott[1]); } /* Pause for a short time, then use one of the nsync_run_once* calls on ott->s->once, chosen using the thread id. This is the body of each test thread. */ static void once_thread (struct once_test_thread_s *lott) { struct once_test_s *s; nsync_mu_lock (&ott_s_mu); s = lott->s; nsync_mu_unlock (&ott_s_mu); nsync_time_sleep (nsync_time_s_ns (0, 1 * 1000 * 1000)); switch (lott->id & 3) { case 0: nsync_run_once (&s->once, &once_func0); break; case 1: nsync_run_once_spin (&s->once, &once_func1); break; case 2: nsync_run_once_arg (&s->once, &once_arg_func, lott); break; case 3: nsync_run_once_arg_spin (&s->once, &once_arg_func, lott); break; } nsync_counter_add (s->done, -1); } CLOSURE_DECL_BODY1 (once_thread, struct once_test_thread_s *) /* Test the functionality of nsync_once */ static void test_once_run (testing t) { int i; int j; for (j = 0; j != N; j++) { ott[j].id = j; } for (i = 0; i != 250; i++) { struct once_test_s *s = (struct once_test_s *) malloc (sizeof (*s)); memset ((void *) s, 0, sizeof (*s)); s->counter = 0; s->done = nsync_counter_new (N); s->t = t; for (j = 0; j != N; j++) { nsync_mu_lock (&ott_s_mu); ott[j].s = s; nsync_mu_unlock (&ott_s_mu); } for (j = 0; j != N; j++) { closure_fork (closure_once_thread (&once_thread, &ott[j])); } if (nsync_counter_wait (s->done, nsync_time_no_deadline) != 0) { TEST_ERROR (t, ("s.done not decremented to 0")); } if (s->counter == 0) { TEST_ERROR (t, ("s.counter wasn't incremented")); } /* The counter is expected to be a power of two, because each counter is incremented only via a single nsync_once (so at most one increment should occur) and always by a power of two. */ if ((s->counter & (s->counter-1)) != 0) { TEST_ERROR (t, ("s.counter incremented repeatedly: %x", s->counter)); } nsync_counter_free (s->done); free (s); } } /* Do nothing. */ static void no_op (void) { } /* Measure the performance of repeated use of nsync_run_once. */ static void benchmark_nsync_once (testing t) { static nsync_once o = NSYNC_ONCE_INIT; int n = testing_n (t); int i; for (i = 0; i != n; i++) { nsync_run_once (&o, &no_op); } } /* Measure the performance of repeated use of pthread_once. */ static void benchmark_native_once (testing t) { static pthread_once_t o = PTHREAD_ONCE_INIT; int n = testing_n (t); int i; for (i = 0; i != n; i++) { pthread_once (&o, &no_op); } } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_once_run); BENCHMARK_RUN (tb, benchmark_nsync_once); BENCHMARK_RUN (tb, benchmark_native_once); return (testing_base_exit (tb)); } nsync-1.24.0/testing/pingpong_test.c000066400000000000000000000275211367521742200174510ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "nsync.h" #include "smprintf.h" #include "testing.h" #include "closure.h" NSYNC_CPP_USING_ /* The benchmarks in this file use various mechanisms to ping-pong back and forth between two threads as they count i from 0 to limit. The data structure contains multiple synchronization primitives, but each benchmark uses only those it needs. The setting of GOMAXPROCS, and the exact choices of the thread scheduler can have great effect on the timings. */ typedef struct ping_pong_s { nsync_mu mu; nsync_cv cv[2]; pthread_mutex_t mutex; pthread_rwlock_t rwmutex; pthread_cond_t cond[2]; pthread_cond_t done_cond; int outstanding; int i; int limit; } ping_pong; static void ping_pong_init (ping_pong *pp, int limit) { memset ((void *) pp, 0, sizeof (*pp)); pthread_mutex_init (&pp->mutex, NULL); pthread_rwlock_init (&pp->rwmutex, NULL); pthread_cond_init (&pp->cond[0], NULL); pthread_cond_init (&pp->cond[1], NULL); pthread_cond_init (&pp->done_cond, NULL); pp->outstanding = 2; pp->limit = limit; } static void ping_pong_done (ping_pong *pp) { pthread_mutex_lock (&pp->mutex); pp->outstanding--; if (pp->outstanding == 0) { pthread_cond_broadcast (&pp->done_cond); } pthread_mutex_unlock (&pp->mutex); } static void ping_pong_destroy (ping_pong *pp) { pthread_mutex_lock (&pp->mutex); while (pp->outstanding != 0) { pthread_cond_wait (&pp->done_cond, &pp->mutex); } pthread_mutex_unlock (&pp->mutex); pthread_mutex_destroy (&pp->mutex); pthread_rwlock_destroy (&pp->rwmutex); pthread_cond_destroy (&pp->cond[0]); pthread_cond_destroy (&pp->cond[1]); pthread_cond_destroy (&pp->done_cond); } /* --------------------------------------- */ CLOSURE_DECL_BODY2 (ping_pong, ping_pong *, int) /* void pthread_mutex_lock */ static void void_pthread_mutex_lock (void *mu) { pthread_mutex_lock ((pthread_mutex_t *) mu); } /* void pthread_mutex_unlock */ static void void_pthread_mutex_unlock (void *mu) { pthread_mutex_unlock ((pthread_mutex_t *) mu); } /* Run by each thread in benchmark_ping_pong_mutex_cv(). */ static void mutex_cv_ping_pong (ping_pong *pp, int parity) { pthread_mutex_lock (&pp->mutex); while (pp->i < pp->limit) { while ((pp->i & 1) == parity) { nsync_cv_wait_with_deadline_generic (&pp->cv[parity], &pp->mutex, &void_pthread_mutex_lock, &void_pthread_mutex_unlock, nsync_time_no_deadline, NULL); } pp->i++; nsync_cv_signal (&pp->cv[1-parity]); } pthread_mutex_unlock (&pp->mutex); ping_pong_done (pp); } /* Measure the wakeup speed of pthread_mutex_t/nsync_cv used to ping-pong back and forth between two threads. */ static void benchmark_ping_pong_mutex_cv (testing t) { ping_pong pp; ping_pong_init (&pp, testing_n (t)); closure_fork (closure_ping_pong (&mutex_cv_ping_pong, &pp, 0)); mutex_cv_ping_pong (&pp, 1); ping_pong_destroy (&pp); } /* --------------------------------------- */ /* Run by each thread in benchmark_ping_pong_mu_cv(). */ static void mu_cv_ping_pong (ping_pong *pp, int parity) { nsync_mu_lock (&pp->mu); while (pp->i < pp->limit) { while ((pp->i & 1) == parity) { nsync_cv_wait (&pp->cv[parity], &pp->mu); } pp->i++; nsync_cv_signal (&pp->cv[1-parity]); } nsync_mu_unlock (&pp->mu); ping_pong_done (pp); } /* Measure the wakeup speed of nsync_mu/nsync_cv used to ping-pong back and forth between two threads. */ static void benchmark_ping_pong_mu_cv (testing t) { ping_pong pp; ping_pong_init (&pp, testing_n (t)); closure_fork (closure_ping_pong (&mu_cv_ping_pong, &pp, 0)); mu_cv_ping_pong (&pp, 1); ping_pong_destroy (&pp); } /* --------------------------------------- */ /* Run by each thread in benchmark_ping_pong_mu_cv_unexpired_deadline(). */ static void mu_cv_unexpired_deadline_ping_pong (ping_pong *pp, int parity) { nsync_time deadline_in1hour; deadline_in1hour = nsync_time_add (nsync_time_now (), nsync_time_ms (3600000)); nsync_mu_lock (&pp->mu); while (pp->i < pp->limit) { while ((pp->i & 1) == parity) { nsync_cv_wait_with_deadline (&pp->cv[parity], &pp->mu, deadline_in1hour, NULL); } pp->i++; nsync_cv_signal (&pp->cv[1 - parity]); } nsync_mu_unlock (&pp->mu); ping_pong_done (pp); } /* Measure the wakeup speed of nsync_mu/nsync_cv used to ping-pong back and forth between two threads, with an unexpired deadline pending. */ static void benchmark_ping_pong_mu_cv_unexpired_deadline (testing t) { ping_pong pp; ping_pong_init (&pp, testing_n (t)); closure_fork (closure_ping_pong (&mu_cv_unexpired_deadline_ping_pong, &pp, 0)); mu_cv_unexpired_deadline_ping_pong (&pp, 1); ping_pong_destroy (&pp); } /* --------------------------------------- */ /* even_ping_pong and odd_ping_pong are wait conditions used by mu_ping_pong. */ static int even_ping_pong (const void *v) { return ((((const ping_pong *) v)->i & 1) == 0); } static int odd_ping_pong (const void *v) { return ((((const ping_pong *) v)->i & 1) == 1); } typedef int (*condition_func) (const void *v); static const condition_func condition[] = { &even_ping_pong, &odd_ping_pong }; /* Run by each thread in benchmark_ping_pong_mu_unexpired_deadline(). */ static void mu_unexpired_deadline_ping_pong (ping_pong *pp, int parity) { nsync_time deadline_in1hour; deadline_in1hour = nsync_time_add (nsync_time_now (), nsync_time_ms (3600000)); nsync_mu_lock (&pp->mu); while (pp->i < pp->limit) { nsync_mu_wait_with_deadline (&pp->mu, condition[parity], pp, NULL, deadline_in1hour, NULL); pp->i++; } nsync_mu_unlock (&pp->mu); ping_pong_done (pp); } /* Measure the wakeup speed of nsync_mu's wait_with_deadline() primitive used to ping-pong back and forth between two threads with an unexpired deadline pending. */ static void benchmark_ping_pong_mu_unexpired_deadline (testing t) { ping_pong pp; ping_pong_init (&pp, testing_n (t)); closure_fork (closure_ping_pong (&mu_unexpired_deadline_ping_pong, &pp, 0)); mu_unexpired_deadline_ping_pong (&pp, 1); ping_pong_destroy (&pp); } /* --------------------------------------- */ /* Run by each thread in benchmark_ping_pong_mutex_cond_unexpired_deadline(). */ static void mutex_cond_unexpired_deadline_ping_pong (ping_pong *pp, int parity) { struct timespec ts; clock_gettime (CLOCK_REALTIME, &ts); ts.tv_sec += 3600; pthread_mutex_lock (&pp->mutex); while (pp->i < pp->limit) { while ((pp->i & 1) == parity) { pthread_cond_timedwait (&pp->cond[parity], &pp->mutex, &ts); } pp->i++; pthread_cond_signal (&pp->cond[1-parity]); } pthread_mutex_unlock (&pp->mutex); ping_pong_done (pp); } /* Measure the wakeup speed of pthread_mutex_t/pthread_cond_t used to ping-pong back and forth between two threads. */ static void benchmark_ping_pong_mutex_cond_unexpired_deadline (testing t) { ping_pong pp; ping_pong_init (&pp, testing_n (t)); closure_fork (closure_ping_pong (&mutex_cond_unexpired_deadline_ping_pong, &pp, 0)); mutex_cond_unexpired_deadline_ping_pong (&pp, 1); ping_pong_destroy (&pp); } /* --------------------------------------- */ /* Run by each thread in benchmark_ping_pong_mutex_cond(). */ static void mutex_cond_ping_pong (ping_pong *pp, int parity) { pthread_mutex_lock (&pp->mutex); while (pp->i < pp->limit) { while ((pp->i & 1) == parity) { pthread_cond_wait (&pp->cond[parity], &pp->mutex); } pp->i++; pthread_cond_signal (&pp->cond[1-parity]); } pthread_mutex_unlock (&pp->mutex); ping_pong_done (pp); } /* Measure the wakeup speed of pthread_mutex_t/pthread_cond_t used to ping-pong back and forth between two threads. */ static void benchmark_ping_pong_mutex_cond (testing t) { ping_pong pp; ping_pong_init (&pp, testing_n (t)); closure_fork (closure_ping_pong (&mutex_cond_ping_pong, &pp, 0)); mutex_cond_ping_pong (&pp, 1); ping_pong_destroy (&pp); } /* --------------------------------------- */ /* Run by each thread in benchmark_ping_pong_mu(). */ static void mu_ping_pong (ping_pong *pp, int parity) { nsync_mu_lock (&pp->mu); while (pp->i < pp->limit) { nsync_mu_wait (&pp->mu, condition[parity], pp, NULL); pp->i++; } nsync_mu_unlock (&pp->mu); ping_pong_done (pp); } /* Measure the wakeup speed of nsync_mu's conditional critical sections, used to ping-pong back and forth between two threads. */ static void benchmark_ping_pong_mu (testing t) { ping_pong pp; ping_pong_init (&pp, testing_n (t)); closure_fork (closure_ping_pong (&mu_ping_pong, &pp, 0)); mu_ping_pong (&pp, 1); ping_pong_destroy (&pp); } /* --------------------------------------- */ /* void pthread_rwlock_wrlock */ static void void_pthread_rwlock_wrlock (void *mu) { pthread_rwlock_wrlock ((pthread_rwlock_t *) mu); } /* void pthread_rwlock_unlock */ static void void_pthread_rwlock_unlock (void *mu) { pthread_rwlock_unlock ((pthread_rwlock_t *) mu); } /* Run by each thread in benchmark_ping_pong_rwmutex_cv(). */ static void rw_mutex_cv_ping_pong (ping_pong *pp, int parity) { pthread_rwlock_wrlock (&pp->rwmutex); while (pp->i < pp->limit) { while ((pp->i & 1) == parity) { nsync_cv_wait_with_deadline_generic (&pp->cv[parity], &pp->rwmutex, &void_pthread_rwlock_wrlock, &void_pthread_rwlock_unlock, nsync_time_no_deadline, NULL); } pp->i++; nsync_cv_signal (&pp->cv[1-parity]); } pthread_rwlock_unlock (&pp->rwmutex); ping_pong_done (pp); } /* Measure the wakeup speed of pthread_rwlock_t/nsync_cv used to ping-pong back and forth between two threads. */ static void benchmark_ping_pong_rwmutex_cv (testing t) { ping_pong pp; ping_pong_init (&pp, testing_n (t)); closure_fork (closure_ping_pong (&rw_mutex_cv_ping_pong, &pp, 0)); rw_mutex_cv_ping_pong (&pp, 1); ping_pong_destroy (&pp); } /* --------------------------------------- */ /* Run by each thread in benchmark_ping_pong_wait_n_cv(). */ static void wait_n_cv_ping_pong (ping_pong *pp, int parity) { struct nsync_waitable_s waitable; struct nsync_waitable_s *pwaitable = &waitable; waitable.v = &pp->cv[parity]; waitable.funcs = &nsync_cv_waitable_funcs; nsync_mu_lock (&pp->mu); while (pp->i < pp->limit) { while ((pp->i & 1) == parity) { nsync_wait_n (&pp->mu, (void (*) (void *)) &nsync_mu_lock, (void (*) (void *)) &nsync_mu_unlock, nsync_time_no_deadline, 1, &pwaitable); } pp->i++; nsync_cv_signal (&pp->cv[1 - parity]); } nsync_mu_unlock (&pp->mu); ping_pong_done (pp); } /* Measure the wakeup speed of nsync_mu/nsync_cv using nsync_wait_n, used to ping-pong back and forth between two threads. */ static void benchmark_ping_pong_wait_n_cv (testing t) { ping_pong pp; ping_pong_init (&pp, testing_n (t)); closure_fork (closure_ping_pong (&wait_n_cv_ping_pong, &pp, 0)); wait_n_cv_ping_pong (&pp, 1); ping_pong_destroy (&pp); } /* --------------------------------------- */ int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); BENCHMARK_RUN (tb, benchmark_ping_pong_mu); BENCHMARK_RUN (tb, benchmark_ping_pong_mu_unexpired_deadline); BENCHMARK_RUN (tb, benchmark_ping_pong_mu_cv); BENCHMARK_RUN (tb, benchmark_ping_pong_mu_cv_unexpired_deadline); BENCHMARK_RUN (tb, benchmark_ping_pong_mutex_cond); BENCHMARK_RUN (tb, benchmark_ping_pong_mutex_cond_unexpired_deadline); BENCHMARK_RUN (tb, benchmark_ping_pong_mutex_cv); BENCHMARK_RUN (tb, benchmark_ping_pong_rwmutex_cv); BENCHMARK_RUN (tb, benchmark_ping_pong_wait_n_cv); return (testing_base_exit (tb)); } nsync-1.24.0/testing/smprintf.c000066400000000000000000000020731367521742200164260ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "smprintf.h" char *smprintf (const char *fmt, ...) { int m = strlen (fmt) * 2 + 1; char *buf = (char *) malloc (m); int didnt_fit; do { va_list ap; int x; va_start (ap, fmt); x = vsnprintf (buf, m, fmt, ap); va_end (ap); if (x >= m) { buf = (char *) realloc (buf, m = x+1); didnt_fit = 1; } else if (x < 0 || x == m-1) { buf = (char *) realloc (buf, m *= 2); didnt_fit = 1; } else { didnt_fit = 0; } } while (didnt_fit); return (buf); } nsync-1.24.0/testing/smprintf.h000066400000000000000000000013211367521742200164260ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_TESTING_SMPRINTF_H_ #define NSYNC_TESTING_SMPRINTF_H_ char *smprintf (const char *fmt, ...); #endif /*NSYNC_TESTING_SMPRINTF_H_*/ nsync-1.24.0/testing/testing.c000066400000000000000000000367051367521742200162520ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "atm_log.h" #include "nsync.h" #include "compiler.h" #include "atomic.h" #include "time_extra.h" #include "smprintf.h" #include "testing.h" #include "dll.h" #include "closure.h" #include "wait_internal.h" #include "common.h" NSYNC_CPP_USING_ struct testing_base_s { int flags; /* flags from testing_new(); r/o after init */ int parallelism; /* max parallelism to use; r/o after init */ FILE *fp; /* where to send output; pointer is r/o after init */ int argn; /* first arg not processed by testing_new(); r/o after init */ int argc; /* argc passed to testing_new(); r/o after init */ char **argv; /* argv passed to testing_new(); r/o after init */ char *prog; /* name of programme, from argv[0] */ int suppress_header; /* supress hreader on benchmarks */ int run_tests; /* whether to run tests */ int run_benchmarks; /* whether to run benchmarks */ int benchmarks_running; /* and benchmarks are now running */ char *include_pat; /* ,- or |-separated substrings of tests to include */ char *exclude_pat; /* ,- or |-separated substrings of tests to exclude */ int longshort; /* 0 normal, -1 short, 1 long */ int verbose; /* 0 normal; 1 verbose output */ nsync_mu testing_mu; /* protects fields below */ int is_uniprocessor; /* whether the system is a uniprocessor */ nsync_dll_list_ children; /* list of testing_s structs whose base is this testing_base_s */ int child_count; /* count of testing_s structs whose base is this testing_base_s */ int exit_status; /* final exit status */ }; struct testing_s { struct testing_base_s *base; /* r/o after init */ int test_status; /* status; merged into common->exit_status */ int n; /* benchmark iteration count */ nsync_atomic_uint32_ partial_line; /* whether partial test banner emitted last*/ FILE *fp; /* where to output; merged into common->fp if != to it */ nsync_time start_time; /* timer start time; for benchmarks */ nsync_time stop_time; /* when the timer was stopped; for benchmarks */ void (*f) (testing); /* test function to run */ const char *name; /* name of test */ nsync_dll_element_ siblings; /* part of list of siblings */ }; /* Output the header for benchmarks. */ static void output_header (FILE *fp, const char *prog) { int i; int hdrlen = fprintf (fp, "%-10s%-40s %9s %8s %8s %8s\n", "Benchmark", prog, "ops", "time", "ops/sec", "time/op"); for (i = 1; i < hdrlen; i++) { putc ('-', fp); } putc ('\n', fp); fflush (fp); } /* Process a single flag. *pargn is main's argn */ static void process_flag (testing_base tb, int *pargn, int argc, char *argv[], int flag, const char *arg) { switch (flag) { case 'b': tb->run_benchmarks = 1; break; case 'B': tb->run_benchmarks = 1; tb->run_tests = 0; break; case 'H': output_header (stdout, ""); exit (0); case 'h': tb->suppress_header = 1; break; case 'l': tb->longshort++; break; case 'm': if (*pargn + 1 == argc) { fprintf (stderr, "%s: -m flag expects ,- or |-separated strings\n", argv[0]); exit (2); } tb->include_pat = argv[++*pargn]; break; case 'n': if (*pargn + 1 == argc || atoi (argv[1 + *pargn]) < 1) { fprintf (stderr, "%s: -n flag expects parallelism value >= 1\n", argv[0]); exit (2); } tb->parallelism = atoi (argv[++*pargn]); break; case 's': tb->longshort--; break; case 'v': tb->verbose = 1; break; case 'x': if (*pargn + 1 == argc) { fprintf (stderr, "%s: -x flag expects ,- or |-separated strings\n", argv[0]); exit (2); } tb->exclude_pat = argv[++*pargn]; break; default: fprintf (stderr, "%s: unrecognized flag '%c' in arg %d: \"%s\"\n", argv[0], flag, *pargn, arg); exit (2); } } testing_base testing_new (int argc, char *argv[], int flags) { static const char sep[] = { '/', '\\' }; int i; int argn; testing_base tb = (testing_base)malloc (sizeof (*tb)); memset ((void *) tb, 0, sizeof (*tb)); tb->flags = flags; tb->fp = stderr; tb->argc = argc; tb->argv = argv; tb->parallelism = 1; tb->run_tests = 1; tb->is_uniprocessor = -1; tb->prog = tb->argv[0]; for (i = 0; i != sizeof (sep) / sizeof (sep[0]); i++) { char *last = strrchr (tb->prog, sep[i]); if (last != NULL) { tb->prog = last + 1; } } for (argn = 1; argn != argc && argv[argn][0] == '-' && strcmp (argv[argn], "--") != 0; argn++) { const char *arg = argv[argn]; const char *f; for (f = &arg[1]; *f != 0; f++) { process_flag (tb, &argn, argc, argv, *f, arg); } } tb->argn = argn + (argn != argc && strcmp (argv[argn], "--") == 0); return (tb); } int testing_verbose (testing t) { return (t->base->verbose); } int testing_longshort (testing t) { return (t->base->longshort); } int testing_n (testing t) { return (t->n); } int testing_base_argn (testing_base tb) { return (tb->argn); } /* Return whether *(int *)v is zero. Used with nsync_mu_wait(). */ static int int_is_zero (const void *v) { return (*(const int *)v == 0); } int testing_base_exit (testing_base tb) { int exit_status; nsync_mu_lock (&tb->testing_mu); nsync_mu_wait (&tb->testing_mu, &int_is_zero, &tb->child_count, NULL); exit_status = tb->exit_status; nsync_mu_unlock (&tb->testing_mu); free (tb); exit (exit_status); return (exit_status); } /* Cleanup code used after running either a test or a benchmark, called at the end of run_test() and run_benchmark(). */ static void finish_run (testing t) { testing_base tb = t->base; fflush (t->fp); nsync_mu_lock (&tb->testing_mu); if (t->fp != tb->fp) { int c; rewind (t->fp); while ((c = getc (t->fp)) != EOF) { putc (c, tb->fp); } fclose (t->fp); fflush (tb->fp); } if (tb->exit_status < t->test_status) { tb->exit_status = t->test_status; } tb->children = nsync_dll_remove_ (tb->children, &t->siblings); tb->child_count--; nsync_mu_unlock (&tb->testing_mu); free (t); } /* Run the test (*t->f)(t), and report on t->fp how long it took and its final status, which is set to non-zero if the test reported errors. */ static void run_test (testing t) { testing_base tb = t->base; char *elapsed_str = 0; fprintf (t->fp, "%-25s %-45s ", tb->prog, t->name); fflush (t->fp); ATM_STORE (&t->partial_line, 1); t->test_status = 0; t->n = 0; t->stop_time = nsync_time_zero; t->start_time = nsync_time_now (); (*t->f) (t); elapsed_str = nsync_time_str (nsync_time_sub (nsync_time_now (), t->start_time), 2); if (!ATM_LOAD (&t->partial_line)) { fprintf (t->fp, "%-25s %-45s %s %8s\n", tb->prog, t->name, t->test_status != 0? "failed": "passed", elapsed_str); } else { fprintf (t->fp, "%s %8s\n", t->test_status != 0? "failed": "passed", elapsed_str); } ATM_STORE (&t->partial_line, 0); fflush (t->fp); free (elapsed_str); finish_run (t); } /* Run the benchmark (*t->f)(t) repeatedly, specifying successively greater numbers of iterations, measuring how long it takes each time. Eventually, it takes long enough to get a reasonable estimate of how long each iteration takes, which is reported on t->fp. */ static void run_benchmark (testing t) { char *elapsed_str = 0; char *time_per_op_str = 0; double elapsed; int n = 1; double target = 2.0; int longshort = testing_longshort (t); if (longshort < 0) { target = 1e-3 * (2000 >> -longshort); } else if (longshort > 0) { target = 1e-3 * (2000 << longshort); } do { int32_t mul; t->test_status = 0; t->n = n; t->stop_time = nsync_time_zero; t->start_time = nsync_time_now (); (*t->f) (t); elapsed = nsync_time_to_dbl (nsync_time_sub (nsync_time_now (), t->start_time)); if (elapsed < 1e-1) { elapsed = 1e-1; } mul = (int32_t) (target / elapsed); while (elapsed * mul * 4 < target * 5) { mul++; } if (mul > 1 && elapsed * mul * 2 < target * 3 && n < INT_MAX / mul) { n *= mul; } else if (n < INT_MAX / 2) { n *= 2; } } while (t->test_status == 0 && elapsed < target && n != t->n); elapsed_str = nsync_time_str (nsync_time_from_dbl (elapsed), 2); time_per_op_str = nsync_time_str (nsync_time_from_dbl (elapsed / t->n), 2); fprintf (t->fp, "%-50s %9d %8s %8.2g %8s%s\n", t->name, t->n, elapsed_str, ((double)t->n) / elapsed, time_per_op_str, t->test_status != 0 ? " *** failed ***" : ""); free (elapsed_str); free (time_per_op_str); finish_run (t); } CLOSURE_DECL_BODY1 (testing, testing) /* Return whether there's a "spare thread"; that is, whether the current count of child threads is less than the allowed parallelism. */ static int spare_thread (const void *v) { const_testing_base tb = (const_testing_base) v; return (tb->child_count < tb->parallelism); } /* Return whether nul-terminated string str[] contains a string listed in comma-separated (or vertical bar-separted) strings in nul-terminated string pat[]. A dollar at the end of a string in pat[] matches the end of string in str[]. */ static int match (const char *pat, const char *str) { static const char seps[] = ",|"; int found = 0; char Xbuf[128]; int m = sizeof (Xbuf) - 1; char *mbuf = NULL; char *buf = Xbuf; int i = 0; while (!found && pat[i] != '\0') { int blen = strcspn (&pat[i], seps); int e = i + blen; if (blen > m) { m = blen + 128; buf = mbuf = (char *) realloc (mbuf, m + 1); } memcpy (buf, &pat[i], blen); buf[blen] = '\0'; if (blen > 0 && buf[blen - 1] == '$') { int slen = strlen (str); buf[--blen] = 0; found = (slen >= blen && strcmp (&str[slen-blen], buf) == 0); } else { found = (strstr (str, buf) != NULL); } i = e + strspn (&pat[e], seps); } free (mbuf); return (found); } void testing_run_ (testing_base tb, void (*f) (testing t), const char *name, int is_benchmark) { int exit_status; nsync_mu_lock (&tb->testing_mu); exit_status = tb->exit_status; nsync_mu_unlock (&tb->testing_mu); if (exit_status < 2 && (!is_benchmark || tb->run_benchmarks) && (is_benchmark || tb->run_tests) && (tb->include_pat == NULL || match (tb->include_pat, name)) && (tb->exclude_pat == NULL || !match (tb->exclude_pat, name))) { testing t = (testing) malloc (sizeof (*t)); memset ((void *) t, 0, sizeof (*t)); nsync_dll_init_ (&t->siblings, t); t->base = tb; t->f = f; t->name = name; if (tb->parallelism == 1) { t->fp = tb->fp; } else { t->fp = tmpfile (); } if (!is_benchmark) { if (tb->benchmarks_running) { nsync_mu_lock (&tb->testing_mu); nsync_mu_wait (&tb->testing_mu, &int_is_zero, &tb->child_count, NULL); nsync_mu_unlock (&tb->testing_mu); tb->benchmarks_running = 0; } nsync_mu_lock (&tb->testing_mu); nsync_mu_wait (&tb->testing_mu, &spare_thread, tb, NULL); tb->child_count++; tb->children = nsync_dll_make_last_in_list_ (tb->children, &t->siblings); nsync_mu_unlock (&tb->testing_mu); closure_fork (closure_testing (&run_test, t)); } else { if (!tb->benchmarks_running) { nsync_mu_lock (&tb->testing_mu); nsync_mu_wait (&tb->testing_mu, &int_is_zero, &tb->child_count, NULL); nsync_mu_unlock (&tb->testing_mu); if (!tb->suppress_header) { output_header (tb->fp, tb->prog); } tb->benchmarks_running = 1; } nsync_mu_lock (&tb->testing_mu); nsync_mu_wait (&tb->testing_mu, &spare_thread, tb, NULL); tb->child_count++; tb->children = nsync_dll_make_last_in_list_ (tb->children, &t->siblings); nsync_mu_unlock (&tb->testing_mu); closure_fork (closure_testing (&run_benchmark, t)); } } } /* Used to decide whether the test is running on a uniprocessor. */ struct is_uniprocessor_s { double count; /* count of iterations while *state==1 */ nsync_atomic_uint32_ done; /* set to 1 when thread finishes */ char dummy[256]; /* so structs don't share cache line */ }; /* An anciliary thread that waits until *state is 1, then increments s->count while *state stays 1, and then sets s->done to 1 before exiting. */ static void uniprocessor_check (nsync_atomic_uint32_ *state, struct is_uniprocessor_s *s) { IGNORE_RACES_START (); while (ATM_LOAD_ACQ (state) != 1) { } while (ATM_LOAD_ACQ (state) == 1) { s->count++; } ATM_STORE_REL (&s->done, 1); IGNORE_RACES_END (); } CLOSURE_DECL_BODY2 (uniprocessor_check, nsync_atomic_uint32_ *, struct is_uniprocessor_s *) /* Return whether the test is running on a uniprocessor. Some of the tests rely on interleaving of actions between threads. Particular interleavings are much less likely on uniprocessors, so the tests do not run, or do not declare an error if the system is a uniprocessor. Operating systems vary significantly in how one may ask how many procerssors are present, so we use a heuristic based on comparing the timing of a single thread, and two concurrent threads. */ int testing_is_uniprocessor (testing t) { int is_uniprocessor; nsync_mu_lock (&t->base->testing_mu); is_uniprocessor = t->base->is_uniprocessor; if (is_uniprocessor == -1) { int i; struct is_uniprocessor_s s[3]; nsync_atomic_uint32_ state; for (i = 0; i != 3; i++) { s[i].count = 0.0; s[i].done = 0; } ATM_STORE_REL (&state, 0); closure_fork (closure_uniprocessor_check (&uniprocessor_check, &state, &s[0])); nsync_time_sleep (nsync_time_ms (100)); ATM_STORE_REL (&state, 1); nsync_time_sleep (nsync_time_ms (400)); ATM_STORE_REL (&state, 2); while (!ATM_LOAD_ACQ (&s[0].done)) { } ATM_STORE_REL (&state, 0); closure_fork (closure_uniprocessor_check (&uniprocessor_check, &state, &s[1])); closure_fork (closure_uniprocessor_check (&uniprocessor_check, &state, &s[2])); nsync_time_sleep (nsync_time_ms (100)); ATM_STORE_REL (&state, 1); nsync_time_sleep (nsync_time_ms (400)); ATM_STORE_REL (&state, 2); while (!ATM_LOAD_ACQ (&s[1].done) || !ATM_LOAD_ACQ (&s[2].done)) { } t->base->is_uniprocessor = ((s[1].count + s[2].count) / s[0].count) < 1.7; is_uniprocessor = t->base->is_uniprocessor; } nsync_mu_unlock (&t->base->testing_mu); return (is_uniprocessor); } void testing_stop_timer (testing t) { if (nsync_time_cmp (t->stop_time, nsync_time_zero) != 0) { abort (); } t->stop_time = nsync_time_now (); } void testing_start_timer (testing t) { if (nsync_time_cmp (t->stop_time, nsync_time_zero) == 0) { abort (); } t->start_time = nsync_time_add (t->start_time, nsync_time_sub (nsync_time_now (), t->stop_time)); t->stop_time = nsync_time_zero; } void testing_error_ (testing t, int test_status, const char *file, int line, char *msg) { int len = strlen (msg); int addnl = (len == 0 || msg[len - 1] != '\n'); if (t->test_status < test_status) { t->test_status = test_status; } if (ATM_LOAD (&t->partial_line)) { ATM_STORE (&t->partial_line, 0); fprintf (t->fp, "\n%s: %s:%d: %s%s", test_status == 2? "fatal": test_status == 1? "error": "info", file, line, msg, addnl? "\n": ""); } else { fprintf (t->fp, "%s: %s:%d: %s%s", test_status == 2? "fatal": test_status == 1? "error": "info", file, line, msg, addnl? "\n": ""); } free (msg); } /* Abort after printing the nul-terminated string s[]. */ void testing_panic (const char *s) { nsync_atm_log_print_ (); nsync_panic_ (s); } nsync-1.24.0/testing/testing.h000066400000000000000000000062001367521742200162420ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_TESTING_TESTING_H_ #define NSYNC_TESTING_TESTING_H_ typedef struct testing_base_s *testing_base; typedef const struct testing_base_s *const_testing_base; typedef struct testing_s *testing; /* Return a newly initialized testing_base. */ testing_base testing_new (int argc, char *argv[], int flags); /* Return the index of the first argument in argv[] not processed by testing_new() */ int testing_base_argn (testing_base tb); /* exit() with the test's exit status */ int testing_base_exit (testing_base tb); /* Stop and start the benchmark timer. */ void testing_stop_timer (testing t); void testing_start_timer (testing t); /* Return whether the machine appears to be a uniprocessor. Some tests get different results on uniprocessors, because the probability of certain interleavings of thread actions is greatly reduced. */ int testing_is_uniprocessor (testing t); /* Given a testing_base, run f (t), where t has type testing. Output will be for a test. */ #define TEST_RUN(tb, f) testing_run_ ((tb), &f, #f, 0) /* Given a testing_base, run f (t), where t has type testing. Output will be for a benchmark, which should iterate testing_n (t) times. */ #define BENCHMARK_RUN(tb, f) testing_run_ ((tb), &f, #f, 1) /* Return the iteration count for a benchmark. */ int testing_n (testing t); /* Output nul-terminated string msg[] to stderr, then abort(). */ void testing_panic (const char *msg); /* Return a value below 0 if tests should run short, 0 if normal, and a value exceeding 0 if tests should run long. */ int testing_longshort (testing t); /* Return non-zero if the user requested verbose output. */ int testing_verbose (testing t); /* Output a printf-formated log message associated with *t. Example: TEST_LOG (t, ("wombat %d", some_int)); The TEST_ERROR() and TEST_FATAL() forms of the call makr the test as failing. The TEST_FATAL() form causes other subtests not to run. */ #define TEST_LOG(t, args) testing_error_ ((t), 0, __FILE__, __LINE__, smprintf args); #define TEST_ERROR(t, args) testing_error_ ((t), 1, __FILE__, __LINE__, smprintf args); #define TEST_FATAL(t, args) testing_error_ ((t), 2, __FILE__, __LINE__, smprintf args); /* ---------------------------------------- */ /* internal details follow */ /* An internal routine used by TEST_RUN() and BENCHMARK_RUN(). */ void testing_run_ (testing_base tb, void (*f) (testing t), const char *name, int is_benchmark); /* Output an error message msg, and record status. */ void testing_error_ (testing t, int status, const char *file, int line, char *msg); #endif /*NSYNC_TESTING_TESTING_H_*/ nsync-1.24.0/testing/time_extra.c000066400000000000000000000034411367521742200167250ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "nsync_time.h" #include "time_extra.h" #include "smprintf.h" #include "nsync_cpp.h" NSYNC_CPP_USING_ char *nsync_time_str (nsync_time t, int decimals) { static const struct { const char *suffix; double multiplier; } scale[] = { { "ns", 1.0e-9, }, { "us", 1e-6, }, { "ms", 1e-3, }, { "s", 1.0, }, { "hr", 3600.0, }, }; double s = nsync_time_to_dbl (t); int i = 0; while (i + 1 != sizeof (scale) / sizeof (scale[0]) && scale[i + 1].multiplier <= s) { i++; } return (smprintf ("%.*f%s", decimals, s/scale[i].multiplier, scale[i].suffix)); } int nsync_time_sleep_until (nsync_time abs_deadline) { int result = 0; nsync_time now; now = nsync_time_now (); if (nsync_time_cmp (abs_deadline, now) > 0) { nsync_time remaining; remaining = nsync_time_sleep (nsync_time_sub (abs_deadline, now)); if (nsync_time_cmp (remaining, nsync_time_zero) > 0) { result = EINTR; } } return (result); } double nsync_time_to_dbl (nsync_time t) { return (((double) NSYNC_TIME_SEC (t)) + ((double) NSYNC_TIME_NSEC (t) * 1e-9)); } nsync_time nsync_time_from_dbl (double d) { time_t s = (time_t) d; if (d < s) { s--; } return (nsync_time_s_ns (s, (unsigned) ((d - (double) s) * 1e9))); } nsync-1.24.0/testing/time_extra.h000066400000000000000000000022641367521742200167340ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #ifndef NSYNC_TESTING_TIME_EXTRA_H_ #define NSYNC_TESTING_TIME_EXTRA_H_ #include "nsync_cpp.h" NSYNC_CPP_USING_ /* Return a malloced nul-terminated string representing time t, using "decimals" decimal places. */ char *nsync_time_str (nsync_time t, int decimals); /* Sleep until the specified time. Returns 0 on success, and EINTR if the call was interrupted. */ int nsync_time_sleep_until (nsync_time abs_deadline); /* Return t as a double. */ double nsync_time_to_dbl (nsync_time t); /* Return a time corresponding to double d. */ nsync_time nsync_time_from_dbl (double d); #endif /*NSYNC_TESTING_TIME_EXTRA_H_*/ nsync-1.24.0/testing/wait_test.c000066400000000000000000000142601367521742200165700ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include "platform.h" #include "nsync.h" #include "time_extra.h" #include "smprintf.h" #include "closure.h" #include "testing.h" #include "array.h" NSYNC_CPP_USING_ static void decrement_at (nsync_counter c, nsync_time abs_deadline, nsync_counter done) { nsync_time_sleep_until (abs_deadline); nsync_counter_add (c, -1); nsync_counter_add (done, -1); } CLOSURE_DECL_BODY3 (decrement, nsync_counter, nsync_time, nsync_counter) static void notify_at (nsync_note n, nsync_time abs_deadline, nsync_counter done) { nsync_time_sleep_until (abs_deadline); nsync_note_notify (n); nsync_counter_add (done, -1); } CLOSURE_DECL_BODY3 (notify, nsync_note, nsync_time, nsync_counter) typedef A_TYPE (struct nsync_waitable_s) a_waitable; typedef A_TYPE (struct nsync_waitable_s *) a_pwaitable; /* Test nsync_wait_n(). */ static void test_wait_n (testing t) { int i; int j; int k; int ncounter = 10; int nnote = 10; int nnote_expire = 10; for (i = 0; i != 30; i++) { nsync_counter done = nsync_counter_new (0); nsync_time now; nsync_time deadline; a_waitable aw; a_pwaitable apw; memset (&aw, 0, sizeof (aw)); memset (&apw, 0, sizeof (apw)); now = nsync_time_now (); deadline = nsync_time_add (now, nsync_time_ms (100)); for (j = A_LEN (&aw); A_LEN (&aw) < j+ncounter;) { nsync_counter c = nsync_counter_new (0); struct nsync_waitable_s *w = &A_PUSH (&aw); w->v = c; w->funcs = &nsync_counter_waitable_funcs; for (k = 0; k != 4 && A_LEN (&aw) < j+ncounter; k++) { nsync_counter_add (c, 1); nsync_counter_add (done, 1); closure_fork (closure_decrement (&decrement_at, c, deadline, done)); } } for (j = A_LEN (&aw); A_LEN (&aw) < j+nnote;) { nsync_note n = nsync_note_new (NULL, nsync_time_no_deadline); struct nsync_waitable_s *w = &A_PUSH (&aw); w->v = n; w->funcs = &nsync_note_waitable_funcs; nsync_counter_add (done, 1); closure_fork (closure_notify (¬ify_at, n, deadline, done)); for (k = 0; k != 4 && A_LEN (&aw) < j+nnote; k++) { nsync_note cn = nsync_note_new (n, nsync_time_no_deadline); struct nsync_waitable_s *lw = &A_PUSH (&aw); lw->v = cn; lw->funcs = &nsync_note_waitable_funcs; } } for (j = A_LEN (&aw); A_LEN (&aw) < j+nnote_expire;) { nsync_note n = nsync_note_new (NULL, deadline); struct nsync_waitable_s *w = &A_PUSH (&aw); w->v = n; w->funcs = &nsync_note_waitable_funcs; nsync_counter_add (done, 1); closure_fork (closure_notify (¬ify_at, n, deadline, done)); for (k = 0; k != 4 && A_LEN (&aw) < j+nnote; k++) { nsync_note cn = nsync_note_new (n, nsync_time_no_deadline); struct nsync_waitable_s *lw = &A_PUSH (&aw); lw->v = cn; lw->funcs = &nsync_note_waitable_funcs; } } if (ncounter + nnote + nnote_expire != A_LEN (&aw)) { TEST_ERROR (t, ("array length not equal to number of counters")); } for (j = 0; j != A_LEN (&aw); j++) { A_PUSH (&apw) = &A (&aw, j); } while (A_LEN (&apw) != 0) { k = nsync_wait_n (NULL, NULL, NULL, nsync_time_no_deadline, A_LEN (&apw), &A (&apw, 0)); if (k == A_LEN (&apw)) { TEST_ERROR (t, ("nsync_wait_n returned with no waiter ready")); } A (&apw, k) = A (&apw, A_LEN (&apw) - 1); A_DISCARD (&apw, 1); } nsync_counter_wait (done, nsync_time_no_deadline); for (k = 0; k != ncounter; k++) { nsync_counter_free ((nsync_counter) A (&aw, k).v); } for (; k < A_LEN (&aw); k++) { nsync_note_free ((nsync_note) A (&aw, k).v); } A_FREE (&apw); A_FREE (&aw); nsync_counter_free (done); } } /* Call *nsync_note_waitable_funcs.ready_time, and return its result, but before returning, notify the nsync_note. This is used by test_wait_n_ready_while_queuing() to wrap nsync_note's normal *ready_time function, so that the behaviour of nsync_wait_n() can be checked when a notification happens while the enqueueing process. */ static nsync_time note_ready_time_wrapper (void *v, struct nsync_waiter_s *nw) { nsync_note n = (nsync_note) v; nsync_time result; result = (*nsync_note_waitable_funcs.ready_time) (v, nw); nsync_note_notify (n); return (result); } /* The following test checks that nsync_wait_n() behaves correctly if some object becomes ready during the enqueuing process. */ static void test_wait_n_ready_while_queuing (testing t) { struct nsync_waitable_s w[2]; struct nsync_waitable_s *pw[2]; int count; int woken; /* This test works by wrapping nsync_note's *ready_time function so that the note is notified just after nsync_wait_n() checks that it if not notified on entry. */ struct nsync_waitable_funcs_s wrapped_note_waitable_funcs; wrapped_note_waitable_funcs = nsync_note_waitable_funcs; wrapped_note_waitable_funcs.ready_time = ¬e_ready_time_wrapper; for (count = 0; count != sizeof (w) / sizeof (w[0]); count++) { nsync_note n = nsync_note_new (NULL, nsync_time_no_deadline); if (nsync_note_is_notified (n)) { TEST_ERROR (t, ("nsync_note is unexpectedly notified")); } w[count].v = n; w[count].funcs = &wrapped_note_waitable_funcs; pw[count] = &w[count]; } woken = nsync_wait_n (NULL, NULL, NULL, nsync_time_no_deadline, count, pw); if (woken != 0) { TEST_ERROR (t, ("nsync_wait_n unexpectedly failed to find pw[0] notified")); } for (count = 0; count != sizeof (w) / sizeof (w[0]); count++) { nsync_note n = (nsync_note) w[count].v; if (!nsync_note_is_notified (n)) { TEST_ERROR (t, ("nsync_note is unexpectedly not notified")); } nsync_note_free (n); } } int main (int argc, char *argv[]) { testing_base tb = testing_new (argc, argv, 0); TEST_RUN (tb, test_wait_n); TEST_RUN (tb, test_wait_n_ready_while_queuing); return (testing_base_exit (tb)); } nsync-1.24.0/tools/000077500000000000000000000000001367521742200141015ustar00rootroot00000000000000nsync-1.24.0/tools/README000066400000000000000000000004061367521742200147610ustar00rootroot00000000000000mkdep is used to create Makefile dependencies with compilers that don't have a working flag to do it. run_tests is used to run tests. It would be a few lines of shell script, except for Windows, which has a very different shell, so it's easier to do it in C. nsync-1.24.0/tools/detect.c000066400000000000000000000063041367521742200155200ustar00rootroot00000000000000/* Copyright 2018 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Define macros detected_cc compiler type (e.g., gcc) detected_os OS type (e.g., netbsd) detected_arch CPU type (e.g., mips) detected_lang language (e.g., c, c11, c++, c++11) Each value is suffixed with an "X" to prevent the strings used conflicting with other predefined macros. */ #if defined(__clang__) detected_cc=clangX #elif defined(__LCC__) detected_cc=lccX #elif defined(__TINYC__) detected_cc=tccX #elif defined(__DECC) detected_cc=deccX #elif defined(__PCC__) detected_cc=pccX #elif defined(__TenDRA__) detected_cc=tendraccX #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) detected_cc=gccX #elif defined(__GNUC__) detected_cc=gcc_oldX #else detected_cc=posixX #endif #if defined(__linux__) detected_os=linuxX #elif defined(__NetBSD__) detected_os=netbsdX #elif defined(__OpenBSD__) detected_os=openbsdX #elif defined(__FreeBSD__) detected_os=freebsdX #elif defined(__osf__) detected_os=osf1X #elif defined(__hpux__) detected_os=hpuxX #elif __ANDROID__ detected_os=androidX #elif __APPLE__ #if TARGET_OS_IPHONE || TARGET_OS_IOS || TARGET_IPHONE_SIMULATOR detected_os=iosX #else detected_os=macosX #endif #elif defined(__CYGWIN__) detected_os=cygwinX #elif defined(_WIN64) detected_os=win32X #elif defined(_WIN32) detected_os=win32X #else /* defined(_POSIX_VERSION) || defined(__unix__) */ detected_os=posixX #endif #if defined(__x86_64__) || defined(__amd64__) detected_arch=x86_64X #elif defined(__x86_32__) || defined(__i686__) || defined(__i586__) || defined(__i486__) || defined(__i386__) detected_arch=x86_32X #elif defined(__alpha__) detected_arch=alphaX #elif defined(__mips64__) || defined(__mips32__) || defined(__mips__) detected_arch=mipsX #elif defined(__ppc64__) || defined(__powerpc64__) || defined(__ppc__) || defined(__powerpc__) detected_arch=ppcX #elif defined(__riscv__) || defined(__riscv) detected_arch=riscvX #elif defined(__pnacl__) detected_arch=pnaclX #elif defined(__sparc64__) detected_arch=sparc64X #elif defined(__sparc__) detected_arch=sparcX #elif defined(__hppa64__) detected_arch=parisc64X #elif defined(__hppa__) detected_arch=pariscX #elif defined(__s390x__) detected_arch=s390xX #elif defined(__s390__) detected_arch=s390X #elif defined(__mc68000__) || defined(__m68k__) detected_arch=m68kX #elif defined(__aarch64__) || defined(__arm64__) detected_arch=aarch64X #elif defined(__arm32__) || defined(__arm__) detected_arch=armX #elif defined(__ia64__) detected_arch=ia64X #else detected_arch=posixX #endif #if __cplusplus >= 201103L detected_lang=c++11X #elif defined(__cplusplus) detected_lang=c++X #elif __STDC_VERSION__ >= 201112L detected_lang=c11X #else detected_lang=cX #endif nsync-1.24.0/tools/detect.sh000077500000000000000000000136761367521742200157250ustar00rootroot00000000000000#!/bin/sh # Copyright 2018 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Detect platform properties based on the cc command given as first argument, # then invoke the make command that follows on the command line with variables # NSYNC_OS, NSYNC_OS_TYPE, NSYNC_CC, and NSYNC_ARCH indicating those # properties. # # This script must use _only_ properties derived from the compiler supplied, # becuase that may be a cross compiler, targeting a platform quite different # from the host. # # detect.sh will work for most Unix-like platforms. Uses the path to the detect.c # header if specified; otherwise it assumes that it is called "detect.c" in the same # directory as the detect.sh script. usage="usage: detect.sh \\ [-target_lang ] \\ [-target_arch ] \\ [-target_cc ] \\ [-target_os ] \\ [-nsync_base ] \\ [-detect_path ] \\ [make_args...] It is not usually necessary to specify options. The target compiler, operating system, language, and architecture types are normally deduced by running the supplied compiler. The paths are normally inferred from the structure of the nsync tree and the fact that this script is usually invoked from a child of the 'builds' directory. " detect_base=detect.c detect_path= nsync_base=../.. target_lang= target_arch= target_cc= target_os= while arg="$1" case "$arg" in -*) found=false for flag in target_lang target_arch target_cc target_os detect_path nsync_base; do case "$arg" in "-$flag") eval $flag='"${2?"$usage"}"'; shift; found=true; break;; -"$flag"=*) s=`expr "$arg" : '^[^=]*=\(.*\)$'`; eval $flag="'$s'"; found=true; break;; esac done case "$found" in false) echo "$usage" >&2; exit 2;; esac ;; *) break;; esac do shift done case $# in [01]) echo "$usage" >&2; exit 2;; esac cc="$1" make="$2" shift shift case "$detect_path" in "") case "$0" in */*) detect_path=`expr "$0" : '^\(.*/\)[^/]*$'`"$detect_base";; *) path="$PATH":. while [ ! -f "$detect_path" -a -n "$path" ]; do detect_path=`expr "$path" : '^\([^:]*\).*$'`"/$detect_base" path=`expr "$path" : '^[^:]*:\(.*\)$'` done;; esac esac if [ ! -f "$detect_path" ]; then echo "$0: can't find $detect_base; maybe use -detect_path flag?" >&2; exit 2 fi # Set variables detected_* from detect.c eval `$cc -E "$detect_path" | sed -n 's,^\(detected_.*=.*\)X,\1,p'` case "$detected_cc.$detected_lang" in pcc.c11) # pcc lies when it claims to implement c11 detected_lang=c;; esac # Allow overrides from the command line. case "$target_lang" in ?*) detected_lang="$target_lang";; esac case "$target_arch" in ?*) detected_arch="$target_arch";; esac case "$target_cc" in ?*) detected_cc="$target_cc";; esac case "$target_os" in ?*) detected_os="$target_os";; esac extra_c="$DETECT_EXTRA_CFLAGS" extra_objs= extra_s= extra_cpp_flags="$DETECT_EXTRA_CPPFLAGS" extra_libs="$DETECT_EXTRA_LIBS" # If we can't get atomics from the OS or the compiler, try to find an assembly # language implementation based on the architecture, or one provided by the # language library. if [ ! -f "$nsync_base/platform/$detected_os/atomic.h" -a ! -f "$nsync_base/platform/$detected_cc/atomic.h" ]; then case "$detected_lang" in c11) extra_cpp_flags="$extra_cpp_flags -DNSYNC_ATOMIC_C11 -I../../platform/c11";; c++11) extra_cpp_flags="$extra_cpp_flags -DNSYNC_USE_CPP11_TIMEPOINT -DNSYNC_ATOMIC_CPP11 -I../../platform/c++11";; *) # Try for assembly language. for x in "$nsync_base/platform/$detected_arch/src/nsync_atm_$detected_arch".[sS]; do if [ -f "$x" ]; then extra_cpp_flags="$extra_cpp_flags -I$nsync_base/platform/atomic_ind" extra_s="$extra_s $x" extra_objs="$extra_objs nsync_atm_$detected_arch.o" break fi done;; esac fi # Some systems are special in various ways. case "$detected_arch.$detected_os.$detected_cc" in *.macos.*) # Some MacOS versions don't provide clock_gettime(). extra_c="$extra_c $nsync_base/platform/posix/src/clock_gettime.c" extra_obj="$extra_objs clock_gettime.o";; *.linux.*) # Some Linux boxes keep clock_gettime() in librt. extra_libs="$extra_libs -lrt";; esac # Some compilers support cc -M, but others do not. case "$detected_cc" in gcc|clang|decc) mkdep="$cc -M";; *) mkdep="$nsync_base/tools/mkdep.sh $cc -E";; esac case "$detected_cc" in lcc) extra_c="$extra_c ../../platform/posix/src/time_rep.c" extra_objs="$extra_objs time_rep.o" pthread= cflags= ldflags=-lpthread opt=OPT=;; tendracc) extra_c="$extra_c ../../platform/posix/src/time_rep.c" extra_objs="$extra_objs time_rep.o" pthread= cflags= ldflags=-lpthread opt=OPT=;; pcc) extra_c="$extra_c ../../platform/num_time/src/time_rep.c" extra_objs="$extra_objs time_rep.o" extra_cpp_flags="$extra_cpp_flags -I../../platform/num_time -DNSYNC_USE_INT_TIME=int64_t" pthread=-pthread cflags= ldflags=-pthread opt=;; *) extra_c="$extra_c ../../platform/posix/src/time_rep.c" extra_objs="$extra_objs time_rep.o" pthread=-pthread cflags= ldflags=-pthread opt=;; esac # Invoke command from command line, with various arguments inserted. "$make" -e \ "MKDEP=$mkdep" \ "NSYNC_EXTRA_INC_DIR=$extra_cpp_flags" "NSYNC_EXTRA_PLATFORM_C=$extra_c" "PLATFORM_S=$extra_s" \ "NSYNC_EXTRA_OBJS=$extra_objs" "NSYNC_OS=$detected_os" \ "NSYNC_OS_TYPE=posix" "NSYNC_CC=$detected_cc" "NSYNC_ARCH=$detected_arch" \ "NSYNC_PTHREAD=$pthread" \ "PLATFORM_CFLAGS=$cflags" \ "PLATFORM_LIBS=$extra_libs" \ "PLATFORM_LDFLAGS=$ldflags" \ $opt \ ${1+"$@"} nsync-1.24.0/tools/mkdep.c000066400000000000000000000207641367521742200153560ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Generate make dependencies using C preprocessor. Usage: mkdep cc cc_args_to_invoke_preprocessor... file.{[csh],cc} ... Output is written to stdout. */ #include #include #include #include #if defined(_WIN32) #define popen _popen #define pclose _pclose #endif /* Comparison routine to sort strings with qsort(). */ static int cmpstr (const void *va, const void *vb) { const char **a = (const char **)va; const char **b = (const char **)vb; return (strcmp (*a, *b)); } /* Return whether nul-terminated string s[] starts with any of the nul-terminated strings given as arguments after s, and termated with a NULL argument. */ static int has_prefix (const char *s, ...) { va_list ap; const char *pref; va_start (ap, s); pref = va_arg (ap, const char *); while (pref != NULL && strncmp (s, pref, strlen (pref)) != 0) { pref = va_arg (ap, const char *); } va_end (ap); return (pref != NULL); } /* Return whether nul-terminated string s[] ends with any of the nul-terminated strings given as arguments after s, and termated with a NULL argument. */ static int has_suffix (const char *s, ...) { va_list ap; int slen = strlen (s); const char *suf; va_start (ap, s); suf = va_arg (ap, const char *); while (suf != NULL && (slen < (int) strlen (suf) || strcmp (&s[slen-strlen (suf)], suf) != 0)) { suf = va_arg (ap, const char *); } va_end (ap); return (suf != NULL); } /* Return whether nul-termainted string s[] ends with a suffix that designates a source file. */ static int has_prog_suffix (const char *s) { return (has_suffix (s, ".c", ".h", ".s", ".cc", ".C", ".H", ".S", ".CC", (char *) NULL)); } /* Return the index in nul-terminated string s[] of the longest suffix that contains none of the bytes in nul-terminated string sep[]. */ static int pos_suffix_not_containing (const char *s, const char *sep) { int pos = strlen (s); while (pos != 0 && strchr (sep, s[pos-1] & 0xff) == NULL) { pos--; } return (pos); } /* Process a source file with nul-terminated file name file[], writing to ofp the source dependencies obtained by running the file through the C preprocessor using the nul-terminated command prefix cmd_prefix[]. */ static void process_file (FILE *ofp, const char *cmd_prefix, const char *file) { char line[2048]; int cmdlen = strlen (cmd_prefix) + strlen (file) + 10; char *cmd = (char *) malloc (cmdlen); FILE *ifp; int status; int i; int n; int basename = pos_suffix_not_containing (file, "/\\"); int ext = pos_suffix_not_containing (file, "."); const char *last; int list_max = 64; char **list = (char **) malloc (sizeof (list[0]) * list_max); snprintf (cmd, cmdlen, "%s %s", cmd_prefix, file); ifp = popen (cmd, "r"); if (ifp == NULL) { fprintf (stderr, "error starting command: \"%s\": ", cmd); perror ("popen"); exit (2); } n = 0; while (fgets (line, sizeof (line), ifp) != NULL) { if (has_prefix (line, "#line 1 \"", "# 1 \"", (char *) NULL)) { char *start = strchr (line, '"'); char *end = strchr (start+1, '"'); if (end != NULL) { end[1] = 0; if (start[0] == '"' && end[0] == '"' && strchr (start, ' ') == NULL) { /* No need for quotes. */ start++; end[0] = 0; } } if (has_prog_suffix (start)) { if (n == list_max) { list_max *= 2; list = (char **) realloc (list, sizeof (list[0]) * list_max); } list[n++] = strdup (start); } } } if (basename < ext) { fprintf (ofp, "%.*so:", ext - basename, &file[basename]); } else { abort (); /* can't happen: file ends in a prog suffix */ } qsort (list, n, sizeof (list[0]), &cmpstr); last = ""; for (i = 0; i != n; i++) { if (strcmp (last, list[i]) != 0) { fprintf (ofp, " \\\n %s", list[i]); last = list[i]; } } fprintf (ofp, "\n"); for (i = 0; i != n; i++) { free (list[i]); } if (ferror (ifp)) { fprintf (stderr, "error reading from command: "); perror (cmd); exit (2); } status = pclose (ifp); if (status != 0) { fprintf (stderr, "mkdep: command \"%s\" returned error %x\n", cmd, status); exit (2); } free (cmd); free (list); } int main (int argc, char *argv[]) { char cmd_prefix[2048]; int cmd_len = 0; char cpp_cmd_prefix[2048]; int cpp_cmd_len = 0; int argn; FILE *ofp = stdout; /* Build up command line using arguments that don't end in .[chs] .cc */ for (argn = 1; argn != argc; argn++) { const char *arg = argv[argn]; if (!has_prog_suffix (arg)) { if (has_prefix (arg, "-c++=", NULL)) { snprintf (&cpp_cmd_prefix[cpp_cmd_len], sizeof (cpp_cmd_prefix) - cpp_cmd_len, "%s ", arg+5); cpp_cmd_len += strlen ( &cpp_cmd_prefix[cpp_cmd_len]); } else { snprintf (&cmd_prefix[cmd_len], sizeof (cmd_prefix) - cmd_len, "%s ", arg); cmd_len += strlen (&cmd_prefix[cmd_len]); snprintf (&cpp_cmd_prefix[cpp_cmd_len], sizeof (cpp_cmd_prefix) - cpp_cmd_len, "%s ", arg); cpp_cmd_len += strlen ( &cpp_cmd_prefix[cpp_cmd_len]); } } } if (cmd_len >= (int) sizeof (cmd_prefix) - 1) { fprintf (stderr, "mkdep: command line is too long\n"); exit (2); } if (cpp_cmd_len >= (int) sizeof (cpp_cmd_prefix) - 1) { fprintf (stderr, "mkdep: command line is too long\n"); exit (2); } cmd_prefix[cmd_len] = 0; cpp_cmd_prefix[cpp_cmd_len] = 0; /* Run the compiler for each non-flag file containing a dot, generating Makefile dependencies for that file by running it through the preprocessor. */ for (argn = 1; argn != argc; argn++) { if (has_prog_suffix (argv[argn])) { if (has_suffix (argv[argn], ".cc", ".CC", NULL)) { process_file (ofp, cpp_cmd_prefix, argv[argn]); } else { process_file (ofp, cmd_prefix, argv[argn]); } } } return (0); } nsync-1.24.0/tools/mkdep.sh000077500000000000000000000032731367521742200155450ustar00rootroot00000000000000#!/bin/sh # Copyright 2018 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Generate make dependencies using C preprocessor. # Usage: # mkdep.sh cc cc_args_to_invoke_preprocessor... file.{[csh],cc} ... # Output is written to stdout. # Implemented with sh, expr, sed, and sort. c_cmd= cpp_cmd= for x in ${1+"$@"}; do case "$x" in *.[chsCHS]|*.cc|*.CC) ;; -c++=*) cpp_cmd="$cpp_cmd '`expr "$x" : '^.....\(.*\)$'`'";; *) c_cmd="$c_cmd '$x'" cpp_cmd="$cpp_cmd '$x'";; esac done # Write to stdout dependencies obtained by running each source file through the # C preprocessor using the command prefix from the command line. for file in ${1+"$@"}; do case "$file" in *.[chsCHS]|*.cc|*.CC) case "$file" in *.cc|*.CC) cmd="$cpp_cmd";; *) cmd="$c_cmd";; esac ext=`expr "$file" : '^.*[.]\([^.]*\)$'` basename=`expr "$file" : '^\(.*\)[.][^.]*$'` # remove extension case "$basename" in */*) basename=`expr "$basename" : '.*/\([^/]*\)$'`;; esac eval "$cmd" "'$file'" | sed ' s/^#line 1 "/# 1 "/ /^# 1 "[^<]/!d s/^# 1 \(".*"\).*$/\1/ / /!s/^"\(.*\)"$/\1/ p ' | sort -u | sed '1i\ '"$basename.o"': \\ s/^/ / $!s/$/ \\/ ' ;; esac done nsync-1.24.0/tools/mkmakefile.sh000066400000000000000000000320041367521742200165410ustar00rootroot00000000000000#!/bin/sh # Copyright 2016 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Attempt to create a subdirectory in builds/ suitable for # building nsync on this machine. Works on many Unix-like systems, # but for some you should create the Makefile by hand. # # Requires a Bourne shell, echo, expr, mkdir, uname, rm, # and, if the -diff option is used, diff. usage="usage: mkmakefile.sh [-diff|-out] [-dir ] [-os ] [-arch ] [-cc ] [-sem futex|sem_t|mutex] [-atomic c++11|c11|asm|os] [-lrt] Create a build directory for the given operating system, machine architecture, and C compiler. Values not given explicitly are guessed. If -sem is given, it forces the use of futex, sem_t, or pthread_{mutex,cond}_t to implement a semaphore. If -atomic is given, it requests the use of C++11, C11, OS-supplied, or assembler-implemented atomics. Otherwise, atomics are usually supplied by compiler intrinsics. The flag -lrt indicates that librt is needed to provide the clock_gettime call. If -out is given, the makefile is written to stdout. If -diff is given, the makefile is compared with the one present in the directory. " # Compilers this script knows about. compilers="gcc clang g++ clang++ tcc lcc decc pcc tendracc" os= arch= cc= dir= action=create sem= libs= atomics= while [ $# -gt 0 ]; do arg="${1-}" case "$arg" in -arch) arch="${2?"$usage"}"; shift;; -atomic) atomics="${2?"$usage"}"; shift;; -cc) cc="${2?"$usage"}"; shift;; -diff) action=diff;; -dir) dir="${2?"$usage"}"; shift;; -lrt) case "$libs" in "") libs="-lrt";; *) libs="$libs -lrt";; esac;; -os) os="${2?"$usage"}"; shift;; -out) action=out;; -sem) sem="${2?"$usage"}"; shift;; *) echo "$usage" >&2; exit 2;; esac shift done # Find the root of the nsync tree. for root_dir in . .. ../.. ../../.. ../../../..; do if [ -f "$root_dir/public/nsync.h" ]; then break fi done if [ ! -f "$root_dir/public/nsync.h" ]; then echo "must be invoked within the nsync tree" >&2 exit 2 fi # Find the normalized operating system name. case "$os" in "") os=`uname -s` case "$os" in [lL][iI][nN][uU][xX]) os=linux;; [nN][eE][tT][bB][sS][dD]) os=netbsd;; [fF][rR][eE][eE][bB][sS][dD]) os=freebsd;; [oO][pP][eE][nN][bB][sS][dD]) os=openbsd;; [dD][aA][rR][wW][iI][nN]) os=macos;; [cC][yY][gG][wW][iI][nN]*) os=cygwin;; [oO][sS][fF]1) os=osf1;; [iI][rR][iI][xX]64) os=irix64;; [uU][lL][tT][rR][iI][xX]) os=ultrix;; esac;; esac # Find the normalized processor architecture name. case "$arch" in "") arch=`uname -m` case "$arch" in [iI][3456]86|[xX]86|[xX]86_32) arch=x86_32;; [aA][mM][dD]64|[xX]86_64) arch=x86_64;; [iI][pP]35) arch=mips;; [rR][iI][sS][cC]) arch=mips;; [vV][aA][xX]) arch=vax;; esac;; esac # Find a C compiler. case "$cc" in "") for x in cc $compilers; do path="$PATH" while [ -n "$path" -a ! -n "$cc" ]; do d=`expr "$path" : '\([^:]*\)'` path=`expr "$path" : '[^:]*:\(.*\)'` if [ -x "$d/$x" ]; then cc="$x" fi done done case "$cc" in "") echo "can't find C compiler: use -cc flag" >&2 exit 2;; esac;; esac # Work out what sort of C compiler it is. cplusplus= case "$cc" in *++*) cplusplus=c++;; esac cc_type2="$cc" cc_type= case "$cc_type2" in *" "*) cc_type2=`expr "$cc_type2" : '\([^ ]*\) .*$'`;; esac case "$cc_type2" in */*) cc_type2=`expr "$cc_type2" : '[^\([^ ]*\) .*$'`;; esac case "$cc_type2" in cc) if version=`cc -v 2>&1 || cc -V 2>&1`; then cc_type2=`echo "$version" | while read line; do case "$line" in "gcc "*) echo gcc; break;; "Apple LLVM "*) echo clang; break;; "clang "*|*" clang "*) echo clang; break;; "tcc "*) echo tcc; break;; "lcc "*) echo lcc; break;; "Compaq C "*|"DEC C "*) echo decc; break;; esac done` fi cc_type="$cc_type2";; g++) cc_type=gcc;; clang++) cc_type=clang;; *) cc_type="$cc_type2";; esac # Find a build directory. case "$dir" in "") dir="$root_dir/builds/$arch.$os.$cc_type2" case "$sem" in ?*) dir="$dir.sem-$sem";; esac case "$atomics" in ?*) dir="$dir.atm-$atomics";; esac case "$libs" in *-lrt*) dir="$dir.lrt";; esac ;; esac case "$action" in create) if [ -d "$dir" ]; then echo "$dir exists" >&2; exit 2; fi;; diff) if [ ! -d "$dir" ]; then echo "$dir doesn't exist" >&2; exit 2; fi;; esac # Get C preprocessor flags. cppflags="-D_POSIX_C_SOURCE=200809L" # Sometimes needed; doesn't hurt. # gcc's TLS doesn't work on OpenBSD or Irix. case "$arch.$os.$cc_type" in *.openbsd.gcc|*.openbsd.clang|*.irix64.gcc) cppflags="$cppflags -I../../platform/gcc_no_tls";; esac first="$cc_type" second="$os" case "$atomics" in c11) cppflags="-DNSYNC_ATOMIC_C11 -I../../platform/c11 $cppflags";; c++11) cppflags="-I../../platform/atomic_ind $cppflags";; os) first="$os" second="$cc_type";; esac for x in "$first" "$second" "$arch" posix; do if [ -d "$root_dir/platform/$x" ]; then cppflags="$cppflags -I../../platform/$x" fi done # If not using gcc/clang, or explcitly requested, attempt to find an assembly # language set of atomic ops. asm_atomics=false case "$cc_type.$atomics.$os" in *.c11.*|*.c++11.*) ;; gcc..irix64) asm_atomics=true;; gcc..*|clang..*) ;; *..*|*.asm.*) asm_atomics=true;; esac atomic_ind= atomic_c= atomic_s= case "$asm_atomics" in true) for x in `cd "$root_dir"; echo "platform/$arch/src/nsync_atm_$arch."[csS]`; do if [ -f "$root_dir/$x" ]; then atomic_ind="-I../../platform/atomic_ind " case "$x" in *.[sS]) atomic_s="../../$x";; *) atomic_c="../../$x";; esac break fi done;; esac # Some platforms take -pthread flag, and others -pthread. ldflags= use_pthread=false case "$cc_type.$os" in *.irix64) ;; gcc.*|clang.*|tcc.*|decc.*|pcc.*) use_pthread=true;; esac case "$use_pthread" in true) cppflags="$cppflags -pthread" case "$ldflags" in "") ldflags="-pthread";; *) ldflags="$ldflags -pthread";; esac;; *) case "$libs" in "") libs="-lpthread";; *) libs="$libs -lpthread";; esac;; esac # Which semaphore implementation to use. case "$os.$sem" in linux.|linux.futex) semfile="../../platform/linux/src/nsync_semaphore_futex.c ";; *.|*.futex) semfile="../../platform/posix/src/nsync_semaphore_mutex.c ";; *) semfile="../../platform/posix/src/nsync_semaphore_$sem.c ";; esac # Some platforms don't have clock_gettime. clock_gettime_src= case "$os" in macos) clock_gettime_src="../../platform/posix/src/clock_gettime.c ";; esac case "$cc_type" in pcc) # Compilers like pcc can't pass/return structs properly. Use an integer for the time. time_rep_src="../../platform/num_time/src/time_rep.c" cppflags="-DNSYNC_USE_INT_TIME=int64_t -I../../platform/num_time $cppflags";; *) time_rep_src="../../platform/posix/src/time_rep.c";; esac # Platform-specific files. platform_c="$atomic_c$clock_gettime_src$semfile../../platform/posix/src/per_thread_waiter.c ../../platform/posix/src/yield.c $time_rep_src ../../platform/posix/src/nsync_panic.c" platform_s="$atomic_s" sp= platform_o= for x in $platform_s $platform_c; do o=`expr "$x" : '.*/\([^/]*\)[.][^/]*$'`.o platform_o="$platform_o$sp$o" sp=" " done test_platform_c="../../platform/posix/src/start_thread.c" sp= test_platform_o= for x in $test_platform_c; do o=`expr "$x" : '.*/\([^/]*\)[.][^/]*$'`.o test_platform_o="$test_platform_o$sp$o" sp=" " done makefile=` case "$cc" in cc) ;; *) echo "CC=$cc";; esac case "$cc_type.$cplusplus" in gcc.) echo "PLATFORM_CPPFLAGS=$atomic_ind$cppflags" echo "PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic" case "$ldflags" in ?*) echo "PLATFORM_LDFLAGS=$ldflags";; esac case "$libs" in ?*) echo "PLATFORM_LIBS=$libs";; esac case "$atomics" in c++11) echo "PLATFORM_CXXFLAGS=-Werror -Wall -Wextra -std=c++11 -pedantic" echo "PLATFORM_CXX=../../platform/c_from_c++11/src/nsync_atm_c++.cc" echo "MKDEP_DEPEND=mkdep" echo 'MKDEP=./mkdep ${CC} -E -c++=-std=c++11' platform_o="nsync_atm_c++.o $platform_o";; *) echo 'MKDEP=${CC} -M';; esac echo "PLATFORM_C=$platform_c" case "$platform_s" in ?*) echo "PLATFORM_S=$platform_s";; esac echo "PLATFORM_OBJS=$platform_o" echo "TEST_PLATFORM_C=$test_platform_c" echo "TEST_PLATFORM_OBJS=$test_platform_o" ;; clang.) echo "PLATFORM_CPPFLAGS=$atomic_ind$cppflags" echo "PLATFORM_CFLAGS=-Werror -Wall -Wextra -ansi -pedantic -Wno-unneeded-internal-declaration" case "$ldflags" in ?*) echo "PLATFORM_LDFLAGS=$ldflags";; esac case "$libs" in ?*) echo "PLATFORM_LIBS=$libs";; esac case "$atomics" in c++11) echo "PLATFORM_CXXFLAGS=-Werror -Wall -Wextra -std=c++11 -pedantic" echo "PLATFORM_CXX=../../platform/c_from_c++11/src/nsync_atm_c++.cc" echo "MKDEP_DEPEND=mkdep" echo 'MKDEP=./mkdep ${CC} -E -c++=-std=c++11' platform_o="nsync_atm_c++.o $platform_o";; *) echo 'MKDEP=${CC} -M';; esac echo "PLATFORM_C=$platform_c" case "$platform_s" in ?*) echo "PLATFORM_S=$platform_s";; esac echo "PLATFORM_OBJS=$platform_o" echo "TEST_PLATFORM_C=$test_platform_c" echo "TEST_PLATFORM_OBJS=$test_platform_o" ;; gcc.c++) echo "PLATFORM_CPPFLAGS=-DNSYNC_ATOMIC_CPP11 -I../../platform/c++11 $cppflags" echo "PLATFORM_CFLAGS=-x c++ -std=c++11 -Werror -Wall -Wextra -pedantic" case "$ldflags" in ?*) echo "PLATFORM_LDFLAGS=$ldflags";; esac case "$libs" in ?*) echo "PLATFORM_LIBS=$libs";; esac echo 'MKDEP=${CC} -M -x c++ -std=c++11' echo "PLATFORM_C=$platform_c" case "$platform_s" in ?*) echo "PLATFORM_S=$platform_s";; esac echo "PLATFORM_OBJS=$platform_o" echo "TEST_PLATFORM_C=$test_platform_c" echo "TEST_PLATFORM_OBJS=$test_platform_o" ;; clang.c++) echo "PLATFORM_CPPFLAGS=-DNSYNC_ATOMIC_CPP11 -I../../platform/c++11 $cppflags" echo "PLATFORM_CFLAGS=-x c++ -std=c++11 -Werror -Wall -Wextra -pedantic -Wno-unneeded-internal-declaration" case "$ldflags" in ?*) echo "PLATFORM_LDFLAGS=$ldflags";; esac case "$libs" in ?*) echo "PLATFORM_LIBS=$libs";; esac echo 'MKDEP=${CC} -M -x c++ -std=c++11' echo "PLATFORM_C=$platform_c" case "$platform_s" in ?*) echo "PLATFORM_S=$platform_s";; esac echo "PLATFORM_OBJS=$platform_o" echo "TEST_PLATFORM_C=$test_platform_c" echo "TEST_PLATFORM_OBJS=$test_platform_o" ;; tcc.) echo "PLATFORM_CPPFLAGS=$atomic_ind$cppflags" echo "PLATFORM_CFLAGS=-Werror -Wall" case "$ldflags" in ?*) echo "PLATFORM_LDFLAGS=$ldflags";; esac case "$libs" in ?*) echo "PLATFORM_LIBS=$libs";; esac echo "MKDEP_DEPEND=mkdep" echo 'MKDEP=./mkdep ${CC} -E' echo "PLATFORM_C=$platform_c" case "$platform_s" in ?*) echo "PLATFORM_S=$platform_s";; esac echo "PLATFORM_OBJS=$platform_o" echo "TEST_PLATFORM_C=$test_platform_c" echo "TEST_PLATFORM_OBJS=$test_platform_o" ;; lcc.) echo "PLATFORM_CPPFLAGS=$atomic_ind$cppflags" case "$libs" in ?*) echo "PLATFORM_LIBS=$libs";; esac echo "MKDEP_DEPEND=mkdep" echo 'MKDEP=./mkdep ${CC} -E' echo "PLATFORM_C=$platform_c" case "$platform_s" in ?*) echo "PLATFORM_S=$platform_s";; esac echo "PLATFORM_OBJS=$platform_o" echo "TEST_PLATFORM_C=$test_platform_c" echo "TEST_PLATFORM_OBJS=$test_platform_o" ;; decc.) echo "PLATFORM_CPPFLAGS=$atomic_ind$cppflags -Duintmax_t=uint64_t" echo "PLATFORM_CFLAGS=-std1" case "$ldflags" in ?*) echo "PLATFORM_LDFLAGS=$ldflags";; esac case "$libs" in ?*) echo "PLATFORM_LIBS=$libs -lrt";; *) echo "PLATFORM_LIBS=-lrt";; esac echo 'MKDEP=${CC} -M' echo "PLATFORM_C=$platform_c" case "$platform_s" in ?*) echo "PLATFORM_S=$platform_s";; esac echo "PLATFORM_OBJS=$platform_o" echo "TEST_PLATFORM_C=$test_platform_c" echo "TEST_PLATFORM_OBJS=$test_platform_o" ;; pcc.) echo "PLATFORM_CPPFLAGS=$atomic_ind$cppflags" case "$ldflags" in ?*) echo "PLATFORM_LDFLAGS=$ldflags";; esac case "$libs" in ?*) echo "PLATFORM_LIBS=$libs";; esac echo 'MKDEP=${CC} -M' echo "PLATFORM_C=$platform_c" case "$platform_s" in ?*) echo "PLATFORM_S=$platform_s";; esac echo "PLATFORM_OBJS=$platform_o" echo "TEST_PLATFORM_C=$test_platform_c" echo "TEST_PLATFORM_OBJS=$test_platform_o" ;; *) echo "PLATFORM_CPPFLAGS=$atomic_ind$cppflags" echo "PLATFORM_LIBS=$libs" echo "MKDEP_DEPEND=mkdep" echo 'MKDEP=./mkdep ${CC} -E' echo "PLATFORM_C=$platform_c" case "$platform_s" in ?*) echo "PLATFORM_S=$platform_s";; esac echo "PLATFORM_OBJS=$platform_o" echo "TEST_PLATFORM_C=$test_platform_c" echo "TEST_PLATFORM_OBJS=$test_platform_o" ;; esac echo echo "include ../../platform/posix/make.common" echo "include dependfile" ` case "$action" in out) echo "$makefile";; diff) echo "$makefile" | diff - "$dir/Makefile";; create) mkdir -p "$dir" || exit 2 > "$dir/dependfile" echo "$makefile" > "$dir/Makefile" echo "Created $dir/Makefile";; esac nsync-1.24.0/tools/run_tests.c000066400000000000000000000261521367521742200163010ustar00rootroot00000000000000/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /* Run the tests listed on the command line. */ #include #include #include #if defined(_WIN32) #include #define popen _popen #define pclose _pclose #define sleep(n) Sleep ((n) * 1000) #define mkstemp(x) (-1) #define TEMP tmpnam (NULL) #define closefd(fd) #else #include #define TEMP templ #define closefd(fd) close (fd) #endif /* If x is non-zero, print a usage message on stderr, and exit with a non-zero status. */ static void usage_if (int x) { if (x) { fprintf (stderr, "usage: run_tests [-p ] [-n ] [-bB] test...\n" " -p runs tests in parallel\n" " -n runs subtests in parallel\n" " -b benchmarks are run if tests pass\n" " -B only benchmarks are run\n" "Benchmarks are not run in parallel.\n"); exit (2); } } /* Describe a run of a test */ struct test_run { char *name; /* test name (execuatble to run) */ char *cmd; /* command line with flags to be passed to popen() */ char *file; /* output file */ int fd; /* output file fd or -1 */ FILE *pfp; /* result of popen(); NULL when run is complete */ int status; /* result of pclose */ }; /* Return whether the file with nul-terminated name file[] can be read, and ends with a newline. Also returns true if file==NULL.*/ static int file_ready (const char *file) { int lastc = '\n'; if (file != NULL) { FILE *fp = fopen (file, "r"); lastc = -1; if (fp != NULL) { int c; lastc = '\n'; while ((c = getc (fp)) != EOF) { lastc = c; } fclose (fp); } } return (lastc == '\n'); } /* If file != NULL, output the contents of file with nul-terminated name file[] to ofp. Return 2 if I/O failed, and 0 otherwise. */ static int output (FILE *ofp, const char *file) { int rc = 0; if (file != NULL) { FILE *fp = fopen (file, "r"); if (fp == NULL) { perror (file); rc = 2; } else { int c; while ((c = getc (fp)) != EOF) { putc (c, ofp); } if (ferror (fp)) { perror (file); rc = 2; } if (fclose (fp) != 0) { perror (file); rc = 2; } } unlink (file); fflush (ofp); } return (rc); } /* Run the tests test[0, .., n-1], running as many as possible in parallel, Assumes that test[*].{name,cmd,file} are filled in, and other fields are uninitialized. On return, all fields are initialized. It is expected that all output has been directed to the file named by test[*].file[] (if parallelism > 1) or test[*].pfp (if parallelism==1). test[*].status is valid, and test[*].pfp == NULL. Any output from the commands is written to *ofp, and test[*].file[] is removed. Returns 0 on success, 2 if any I/O error occurred, and 1 if a test failed, and 3 if a test failed and there was an I/O error. Attempts to run "parallelism" tests in parallel. The parallelism is half-hearted as we avoid threads and non-blocking I/O for portability. */ static int run (FILE *ofp, int n, struct test_run *test, int parallelism) { int running = 0; int started = 0; int flushed = 0; int rc = 0; int i; while (flushed != n) { for (i = 0; i != started; i++) { if (test[i].pfp != NULL && file_ready (test[i].file)) { int c; int err; while ((c = getc (test[i].pfp)) != EOF) { putc (c, ofp); if (c == '\n' || c == ' ') { fflush (ofp); } } err = ferror (test[i].pfp); test[i].status = pclose (test[i].pfp); if (test[i].status != 0) { rc |= 1; } else if (err) { test[i].status = 1; rc |= 1; } test[i].pfp = NULL; running--; } } while (flushed != started && test[flushed].pfp == NULL) { rc |= output (ofp, test[flushed].file); flushed++; } while (running < parallelism && started != n) { test[started].pfp = popen (test[started].cmd, "r"); test[started].status = 2; running += (test[started].pfp != NULL); started++; } if (parallelism > 1) { sleep (1); } } if ((rc & 1) != 0) { fprintf (stderr, "failures:"); for (i = 0; i != n; i++) { if (test[i].status != 0) { fprintf (stderr, " %s\n", test[i].name); } } fprintf (stderr, "\n"); } return (rc); } /* For each test run test[0, .., n-1], test run, free its output file name and cmd string. */ static void cleanup (int n, struct test_run *test) { int i; for (i = 0; i != n; i++) { if (test[i].fd != -1) { closefd (test[i].fd); } if (test[i].file != NULL) { free (test[i].file); } free (test[i].cmd); } } /* Run the tests in test[0, .., n-1] with the deisgnated parallism. Run Benchmarks instead of tests if is_benchmark != 0. On entry, only the test[*].name field is valid. Return a suitable exit code, 0 for success, and non-zero for failure. Output is written to *ofp. */ static int run_tests (FILE *ofp, int n, struct test_run *test, int parallelism, int subparallelism, int is_benchmark) { int i; int rc; for (i = 0; i != n; i++) { int cmd_len; char flags[64]; char *redirect; if (parallelism > 1) { int redirect_len; char templ[64]; snprintf (templ, sizeof (templ), "/tmp/run_tests.XXXXXXXXX"); test[i].fd = mkstemp (templ); test[i].file = strdup (TEMP); redirect_len = strlen (test[i].file) + 10; redirect = (char *) malloc (redirect_len); snprintf (redirect, redirect_len, "> \"%s\"", test[i].file); } else { test[i].file = NULL; test[i].fd = -1; redirect = strdup (""); } if (subparallelism == 1) { snprintf (flags, sizeof (flags), "%s", is_benchmark? "-B" : ""); } else { snprintf (flags, sizeof (flags), "%s -n %d", is_benchmark? "-B" : "", subparallelism); } cmd_len = strlen (test[i].name) + strlen (redirect) + strlen (flags) + 64; test[i].cmd = (char *) malloc (cmd_len); snprintf (test[i].cmd, cmd_len, "%s %s %s 2>&1", test[i].name, flags, redirect); free (redirect); } rc = run (ofp, n, test, parallelism); cleanup (n, test); return (rc); } int main (int argc, char *argv[]) { int do_run_benchmarks = 0; int do_run_tests = 1; int parallelism = 1; int subparallelism = 1; int test_n = 0; int test_max = 16; struct test_run *test = (struct test_run *) malloc (sizeof (test[0]) * test_max); int rc = 0; int argn; for (argn = 1; argn != argc; argn++) { const char *arg = argv[argn]; if (arg[0] == '-') { const char *f; for (f = &arg[1]; *f != 0; f++) { switch (*f) { case 'p': usage_if (argn+1 == argc); parallelism = atoi (argv[++argn]); break; case 'n': usage_if (argn+1 == argc); subparallelism = atoi (argv[++argn]); break; case 'b': do_run_benchmarks = 1; break; case 'B': do_run_benchmarks = 1; do_run_tests = 0; break; default: usage_if (1); } } } else { if (test_n == test_max) { test_max *= 2; test = (struct test_run *) realloc ( test, sizeof (test[0]) * test_max); } test[test_n++].name = argv[argn]; } } if (do_run_tests) { rc |= run_tests (stdout, test_n, test, parallelism, subparallelism, 0); } if (do_run_benchmarks && rc == 0) { rc |= run_tests (stdout, test_n, test, 1, 1, 1); } free (test); return (rc); } nsync-1.24.0/tools/run_tests.sh000077500000000000000000000041641367521742200164730ustar00rootroot00000000000000#!/bin/sh usage="usage: run_tests [-p ] [-n ] [-bB] test... -p runs tests in parallel -n runs subtests in parallel -b benchmarks are run if tests pass -B only benchmarks are run -x runs each test as ... The purpose of the cross-runner is to allow a test cross-compiled for another environment to be run in that environment, perhaps via an interpreter, or remotely. Benchmarks are not run in parallel." parallel=1 subparallel=1 run_tests=true run_benchmarks=false crossrunner= rc=0 tests= while arg="$1" case "$arg" in -*) case "$arg" in -*b*) run_benchmarks=true;; esac case "$arg" in -*B*) run_benchmarks=true; run_tests=false;; esac case "$arg" in -*n*) subparallel="${2?"$usage"}"; shift;; esac case "$arg" in -*p*) parallel="${2?"$usage"}"; shift;; esac case "$arg" in -*x*) crossrunner="${2?"$usage"}"; shift;; esac case "$arg" in -*[!bBnpx]*) echo "$usage" >&2; exit 2;; esac ;; "") break;; *) tests="$tests $arg";; esac do shift done if $run_tests; then case $parallel in 1) for x in $tests; do $crossrunner $x -n $subparallel trc=$? case $rc in 0) rc=$trc;; esac done ;; *) tmp=/tmp/run_tests.$$ w=1000 r=1000 for x in $tests; do while while [ -s $tmp.rc.$r ]; do cat $tmp.o.$r case $rc in 0) rc=`cat $tmp.rc.$r`;; esac rm -f $tmp.o.$r $tmp.rc.$r r=`expr $r + 1` done i=$r p=0 while [ $i -lt $w ]; do i=`expr $i + 1` if [ ! -s $tmp.rc.$i ]; then p=`expr $p + 1`; fi done [ $parallel -le $p ] do sleep 1 done ($crossrunner $x -n $subparallel > $tmp.o.$w 2>&1; echo $? > $tmp.rc.$w) & w=`expr $w + 1` done while while [ -s $tmp.rc.$r ]; do cat $tmp.o.$r case $rc in 0) rc=`cat $tmp.rc.$r`;; esac rm -f $tmp.o.$r $tmp.rc.$r r=`expr $r + 1` done [ $r -lt $w ] do sleep 1 done ;; esac fi case $rc in 0) ;; *) run_benchmarks=false;; esac if $run_benchmarks; then for x in $tests; do $crossrunner $x -B trc=$? case $rc in 0) rc=$trc;; esac done fi exit $rc