Skip to content
Merged
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 @@ -119,6 +119,10 @@ function(_get_compile_options_from_config output_var)
list(APPEND config_options "-DLIBC_TRAP_ON_RAISE_FP_EXCEPT")
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
8 changes: 8 additions & 0 deletions libc/src/__support/File/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,15 @@ class File {
return error_unlocked();
}

// TODO: https://github.com/llvm/llvm-project/issues/172302
// MacOS defines clearerr_unlocked as a macro. While pre-processing, the
// identifier below is substituted for the definition in the SDK, which leads
// to compile time errors due to ill-formed statements. This is a workaround
// for the pre-processor.
#pragma push_macro("clearerr_unlocked")
#undef clearerr_unlocked
void clearerr_unlocked() { err = false; }
#pragma pop_macro("clearerr_unlocked")

void clearerr() {
FileLock l(this);
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
// 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
30 changes: 2 additions & 28 deletions libc/src/__support/threads/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.abs_timeout
libc.src.__support.time.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/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 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,28 +1,36 @@
//===--- 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/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/monotonicity.h"
#endif
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
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
//===--- Implementation of a Linux mutex class ------------------*- C++ -*-===//
//===--- Implementation of a Unix mutex 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_MUTEX_H
#define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_MUTEX_H
#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_UNIX_MUTEX_H
#define LLVM_LIBC_SRC___SUPPORT_THREADS_UNIX_MUTEX_H

#include "hdr/types/pid_t.h"
#include "src/__support/CPP/optional.h"
#include "src/__support/libc_assert.h"
#include "src/__support/macros/config.h"
#include "src/__support/threads/linux/futex_utils.h"
#include "src/__support/threads/linux/raw_mutex.h"
#include "src/__support/threads/mutex_common.h"
#include "src/__support/threads/raw_mutex.h"

namespace LIBC_NAMESPACE_DECL {

Expand Down
2 changes: 1 addition & 1 deletion libc/src/threads/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ add_header_library(
libc.src.__support.CPP.mutex
libc.src.__support.OSUtil.osutil
libc.src.__support.threads.mutex
libc.src.__support.threads.linux.raw_mutex
libc.src.__support.threads.raw_mutex
libc.src.__support.threads.linux.futex_utils
)

Expand Down
2 changes: 1 addition & 1 deletion libc/test/integration/src/pthread/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ add_integration_test(
libc.src.pthread.pthread_rwlockattr_destroy
libc.src.pthread.pthread_rwlockattr_setpshared
libc.src.pthread.pthread_rwlockattr_setkind_np
libc.src.__support.threads.linux.raw_mutex
libc.src.__support.threads.raw_mutex
libc.src.stdio.printf
libc.src.stdlib.getenv
libc.src.sys.mman.mmap
Expand Down
Loading
Loading