Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ function(_get_compile_options_from_config output_var)
list(APPEND config_options "-DLIBC_THREAD_MODE=${LIBC_CONF_THREAD_MODE}")
endif()

if(LIBC_CONF_RAW_MUTEX_DEFAULT_SPIN_COUNT)
list(APPEND config_options "-DLIBC_COPT_RAW_MUTEX_DEFAULT_SPIN_COUNT=${LIBC_CONF_RAW_MUTEX_DEFAULT_SPIN_COUNT}")
endif()

set(${output_var} ${config_options} PARENT_SCOPE)
endfunction(_get_compile_options_from_config)

Expand Down
4 changes: 3 additions & 1 deletion libc/hdr/errno_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#include <linux/errno.h>

#include "include/llvm-libc-macros/error-number-macros.h"
#else // __linux__
#elif defined(__APPLE__)
#include <sys/errno.h>
#else // __APPLE__
#include "include/llvm-libc-macros/generic-error-number-macros.h"
#endif

Expand Down
8 changes: 7 additions & 1 deletion libc/include/errno.h.def
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@

#include "llvm-libc-macros/linux/error-number-macros.h"

#else // __linux__
#elif defined(__APPLE__)

#include <sys/errno.h>

#else // __APPLE__

#include "llvm-libc-macros/generic-error-number-macros.h"

#endif

__BEGIN_C_DECLS
Expand Down
41 changes: 32 additions & 9 deletions libc/src/__support/threads/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,54 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${LIBC_TARGET_OS})
endif()

if(TARGET libc.src.__support.threads.${LIBC_TARGET_OS}.mutex)
if(TARGET libc.src.__support.threads.${LIBC_TARGET_OS}.futex_utils)
add_header_library(
raw_mutex
HDRS
raw_mutex.h
COMPILE_OPTIONS
${monotonicity_flags}
DEPENDS
.${LIBC_TARGET_OS}.futex_utils
libc.src.__support.threads.sleep
libc.src.__support.time.abs_timeout
libc.src.__support.time.monotonicity
libc.src.__support.CPP.optional
libc.hdr.types.pid_t
)

add_header_library(
unix_mutex
HDRS
unix_mutex.h
DEPENDS
.raw_mutex
)

add_header_library(
mutex
HDRS
mutex.h
mutex.h
DEPENDS
.${LIBC_TARGET_OS}.mutex
.unix_mutex
)

add_object_library(
fork_callbacks
SRCS
fork_callbacks.cpp
fork_callbacks.cpp
HDRS
fork_callbacks.h
fork_callbacks.h
DEPENDS
.mutex
libc.src.__support.CPP.mutex
.mutex
libc.src.__support.CPP.mutex
)
elseif(NOT (LIBC_CONF_THREAD_MODE STREQUAL LIBC_THREAD_MODE_PLATFORM))
add_header_library(
mutex
HDRS
HDRS
mutex.h
DEPENDS
DEPENDS
.mutex_common
)
endif()
Expand Down
2 changes: 1 addition & 1 deletion libc/src/__support/threads/CndVar.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#include "hdr/stdint_proxy.h" // uint32_t
#include "src/__support/macros/config.h"
#include "src/__support/threads/linux/futex_utils.h" // Futex
#include "src/__support/threads/linux/raw_mutex.h" // RawMutex
#include "src/__support/threads/mutex.h" // Mutex
#include "src/__support/threads/raw_mutex.h" // RawMutex

namespace LIBC_NAMESPACE_DECL {

Expand Down
16 changes: 16 additions & 0 deletions libc/src/__support/threads/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
if(NOT TARGET libc.src.__support.OSUtil.osutil)
return()
endif()

add_header_library(
futex_utils
HDRS
futex_utils.h
DEPENDS
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.__support.CPP.atomic
libc.src.__support.CPP.limits
libc.src.__support.CPP.optional
libc.src.__support.threads.mutex_common
)
79 changes: 79 additions & 0 deletions libc/src/__support/threads/darwin/futex_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//===--- Futex utils for Darwin ----------------------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_DARWIN_FUTEX_UTILS_H
#define LLVM_LIBC_SRC___SUPPORT_THREADS_DARWIN_FUTEX_UTILS_H

#include "src/__support/CPP/atomic.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/time/abs_timeout.h"
#include "src/__support/time/clock_conversion.h"
#include "src/__support/time/units.h"

#include <os/os_sync_wait_on_address.h>

namespace LIBC_NAMESPACE_DECL {

using FutexWordType = uint32_t;

struct Futex : public cpp::Atomic<FutexWordType> {
using cpp::Atomic<FutexWordType>::Atomic;
using Timeout = internal::AbsTimeout;

LIBC_INLINE long wait(FutexWordType val, cpp::optional<Timeout> timeout,
bool /* is_shared */) {
// TODO(bojle): consider using OS_SYNC_WAIT_ON_ADDRESS_SHARED to sync
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the document says:

Use this flag when you pass an address allocated in shared memory to any futex wait function. Shared memory can be used for waits and wakes within a single process, but incur a performance hit.

This extra cost is expected and it is the reason why POSIX API also distinguish shared memory locks and normal private locks.

// betweeen processes. Catch: it is recommended to only be used by shared
// processes, not threads of a same process.

for (;;) {
if (this->load(cpp::MemoryOrder::RELAXED) != val)
return 0;
long ret = 0;
if (timeout) {
// Assuming, OS_CLOCK_MACH_ABSOLUTE_TIME is equivalent to CLOCK_REALTIME
using namespace time_units;
uint64_t tnsec = timeout->get_timespec().tv_sec * 1_s_ns +
timeout->get_timespec().tv_nsec;
ret = os_sync_wait_on_address_with_timeout(
reinterpret_cast<void *>(this), static_cast<uint64_t>(val),
sizeof(FutexWordType), OS_SYNC_WAIT_ON_ADDRESS_NONE,
OS_CLOCK_MACH_ABSOLUTE_TIME, tnsec);
} else {
ret = os_sync_wait_on_address(
reinterpret_cast<void *>(this), static_cast<uint64_t>(val),
sizeof(FutexWordType), OS_SYNC_WAIT_ON_ADDRESS_NONE);
}
if ((ret < 0) && (errno == ETIMEDOUT))
return -ETIMEDOUT;
// case when os_sync returns early with an error. retry.
if ((ret < 0) && ((errno == EINTR) || (errno == EFAULT))) {
continue;
}
return ret;
}
}

LIBC_INLINE long notify_one(bool /* is_shared */) {
// TODO(bojle): deal with is_shared
return os_sync_wake_by_address_any(reinterpret_cast<void *>(this),
sizeof(FutexWordType),
OS_SYNC_WAKE_BY_ADDRESS_NONE);
}

LIBC_INLINE long notify_all(bool /* is_shared */) {
// TODO(bojle): deal with is_shared
return os_sync_wake_by_address_all(reinterpret_cast<void *>(this),
sizeof(FutexWordType),
OS_SYNC_WAKE_BY_ADDRESS_NONE);
}
};

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_DARWIN_FUTEX_UTILS_H
32 changes: 3 additions & 29 deletions libc/src/__support/threads/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ add_header_library(
libc.src.__support.CPP.atomic
libc.src.__support.CPP.limits
libc.src.__support.CPP.optional
libc.src.__support.time.linux.abs_timeout
libc.src.__support.time.abs_timeout
)

set(monotonicity_flags)
Expand All @@ -31,29 +31,13 @@ else()
set(monotonicity_flags -DLIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY=0)
endif()

add_header_library(
raw_mutex
HDRS
mutex.h
DEPENDS
.futex_utils
libc.src.__support.threads.sleep
libc.src.__support.time.linux.abs_timeout
libc.src.__support.time.linux.monotonicity
libc.src.__support.CPP.optional
libc.hdr.types.pid_t
COMPILE_OPTIONS
-DLIBC_COPT_RAW_MUTEX_DEFAULT_SPIN_COUNT=${LIBC_CONF_RAW_MUTEX_DEFAULT_SPIN_COUNT}
${monotonicity_flags}
)

add_header_library(
rwlock
HDRS
rwlock.h
DEPENDS
.futex_utils
.raw_mutex
libc.src.__support.threads.raw_mutex
libc.src.__support.common
libc.src.__support.OSUtil.osutil
libc.src.__support.CPP.limits
Expand All @@ -63,16 +47,6 @@ add_header_library(
${monotonicity_flags}
)

add_header_library(
mutex
HDRS
mutex.h
DEPENDS
.futex_utils
.raw_mutex
libc.src.__support.threads.mutex_common
)

add_object_library(
thread
SRCS
Expand Down Expand Up @@ -119,7 +93,7 @@ add_object_library(
libc.src.__support.OSUtil.osutil
libc.src.__support.threads.linux.futex_word_type
libc.src.__support.threads.mutex
libc.src.__support.threads.linux.raw_mutex
libc.src.__support.threads.raw_mutex
libc.src.__support.CPP.mutex
)

Expand Down
4 changes: 2 additions & 2 deletions libc/src/__support/threads/linux/CndVar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@

#include "src/__support/threads/CndVar.h"
#include "src/__support/CPP/mutex.h"
#include "src/__support/OSUtil/syscall.h" // syscall_impl
#include "src/__support/OSUtil/syscall.h" // syscall_impl
#include "src/__support/macros/config.h"
#include "src/__support/threads/linux/futex_word.h" // FutexWordType
#include "src/__support/threads/linux/raw_mutex.h" // RawMutex
#include "src/__support/threads/mutex.h" // Mutex
#include "src/__support/threads/raw_mutex.h" // RawMutex

#include <sys/syscall.h> // For syscall numbers.

Expand Down
2 changes: 1 addition & 1 deletion libc/src/__support/threads/linux/futex_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
#include "src/__support/threads/linux/futex_word.h"
#include "src/__support/time/linux/abs_timeout.h"
#include "src/__support/time/abs_timeout.h"
#include <linux/errno.h>
#include <linux/futex.h>

Expand Down
4 changes: 2 additions & 2 deletions libc/src/__support/threads/linux/rwlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include "src/__support/threads/identifier.h"
#include "src/__support/threads/linux/futex_utils.h"
#include "src/__support/threads/linux/futex_word.h"
#include "src/__support/threads/linux/raw_mutex.h"
#include "src/__support/threads/raw_mutex.h"
#include "src/__support/threads/sleep.h"

#ifndef LIBC_COPT_RWLOCK_DEFAULT_SPIN_COUNT
Expand All @@ -35,7 +35,7 @@
#endif

#if LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY
#include "src/__support/time/linux/monotonicity.h"
#include "src/__support/time/monotonicity.h"
#endif

namespace LIBC_NAMESPACE_DECL {
Expand Down
6 changes: 3 additions & 3 deletions libc/src/__support/threads/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
// few global locks. So, to avoid static initialization order fiasco, we
// want the constructors of the Mutex classes to be constexprs.

#if defined(__linux__)
#include "src/__support/threads/linux/mutex.h"
#endif // __linux__
#if defined(__linux__) || defined(__APPLE__)
#include "src/__support/threads/unix_mutex.h"
#endif

#elif LIBC_THREAD_MODE == LIBC_THREAD_MODE_SINGLE

Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
//===--- Implementation of a Linux RawMutex class ---------------*- C++ -*-===//
//===--- Implementation of the RawMutex class -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_RAW_MUTEX_H
#define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_RAW_MUTEX_H
#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_RAW_MUTEX_H
#define LLVM_LIBC_SRC___SUPPORT_THREADS_RAW_MUTEX_H

#include "hdr/errno_macros.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/common.h"
#include "src/__support/libc_assert.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
#include "src/__support/threads/linux/futex_utils.h"
#include "src/__support/threads/linux/futex_word.h"
#include "src/__support/threads/sleep.h"
#include "src/__support/time/linux/abs_timeout.h"
#include "src/__support/time/abs_timeout.h"

#include <stdio.h>

#if defined(__linux__)
#include "src/__support/threads/linux/futex_utils.h"
#elif defined(__APPLE__)
#include "src/__support/threads/darwin/futex_utils.h"
#endif

#ifndef LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY
#define LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY 1
#endif

// TODO(bojle): check this for darwin impl
#if LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY
#include "src/__support/time/linux/monotonicity.h"
#include "src/__support/time/monotonicity.h"
#endif

#ifndef LIBC_COPT_RAW_MUTEX_DEFAULT_SPIN_COUNT
Expand Down Expand Up @@ -93,7 +101,9 @@ class RawMutex {
LIBC_INLINE void wake(bool is_pshared) { futex.notify_one(is_pshared); }

public:
LIBC_INLINE static void init(RawMutex *mutex) { mutex->futex = UNLOCKED; }
LIBC_INLINE static void init(RawMutex *mutex) {
mutex->futex.store(UNLOCKED);
}
LIBC_INLINE constexpr RawMutex() : futex(UNLOCKED) {}
[[nodiscard]] LIBC_INLINE bool try_lock() {
FutexWordType expected = UNLOCKED;
Expand Down Expand Up @@ -122,8 +132,8 @@ class RawMutex {
LIBC_ASSERT(lock->futex == UNLOCKED && "Mutex destroyed while used.");
}
LIBC_INLINE Futex &get_raw_futex() { return futex; }
LIBC_INLINE void reset() { futex = UNLOCKED; }
LIBC_INLINE void reset() { futex.store(UNLOCKED); }
};
} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_RAW_MUTEX_H
#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_RAW_MUTEX_H
Loading
Loading