mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Introduce shims for using UBreakIterators from ICU. Also introduce shims for using thread local storage via pthreads. We will be relying on ICU and UBreakIterators for grapheme breaking. But, UBreakIterators are very expensive to create, especially for the way we do grapheme breaking, which is relatively stateless. Thus, we will stash one or more into thread local storage and reset it as needed. Note: Currently, pthread_key_t is hard coded for a single platform (Darwin), but I have a static_assert alongside directions on how to adapt it to any future platforms who differ in key type.
180 lines
4.9 KiB
C++
180 lines
4.9 KiB
C++
//===--- LibcShims.cpp ----------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include <random>
|
|
#include <type_traits>
|
|
#include <cmath>
|
|
#if defined(_WIN32)
|
|
#include <io.h>
|
|
#else
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "swift/Basic/Lazy.h"
|
|
#include "../SwiftShims/LibcShims.h"
|
|
#include "llvm/Support/DataTypes.h"
|
|
|
|
using namespace swift;
|
|
|
|
static_assert(std::is_same<ssize_t, swift::__swift_ssize_t>::value,
|
|
"__swift_ssize_t must be defined as equivalent to ssize_t");
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
void swift::_swift_stdlib_free(void *ptr) {
|
|
free(ptr);
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
int swift::_swift_stdlib_putchar_unlocked(int c) {
|
|
#if defined(_WIN32)
|
|
return _putc_nolock(c, stdout);
|
|
#else
|
|
return putchar_unlocked(c);
|
|
#endif
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
__swift_size_t swift::_swift_stdlib_fwrite_stdout(const void *ptr,
|
|
__swift_size_t size,
|
|
__swift_size_t nitems) {
|
|
return fwrite(ptr, size, nitems, stdout);
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
__swift_size_t swift::_swift_stdlib_strlen(const char *s) {
|
|
return strlen(s);
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
__swift_size_t swift::_swift_stdlib_strlen_unsigned(const unsigned char *s) {
|
|
return strlen((char *)s);
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
int swift::_swift_stdlib_memcmp(const void *s1, const void *s2,
|
|
__swift_size_t n) {
|
|
return memcmp(s1, s2, n);
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
__swift_ssize_t
|
|
swift::_swift_stdlib_read(int fd, void *buf, __swift_size_t nbyte) {
|
|
#if defined(_WIN32)
|
|
return _read(fd, buf, nbyte);
|
|
#else
|
|
return read(fd, buf, nbyte);
|
|
#endif
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
__swift_ssize_t
|
|
swift::_swift_stdlib_write(int fd, const void *buf, __swift_size_t nbyte) {
|
|
#if defined(_WIN32)
|
|
return _write(fd, buf, nbyte);
|
|
#else
|
|
return write(fd, buf, nbyte);
|
|
#endif
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
int swift::_swift_stdlib_close(int fd) {
|
|
#if defined(_WIN32)
|
|
return _close(fd);
|
|
#else
|
|
return close(fd);
|
|
#endif
|
|
}
|
|
|
|
// Guard compilation on the typedef for __swift_pthread_key_t in LibcShims.h
|
|
// being identical to the platform's pthread_key_t
|
|
static_assert(std::is_same<__swift_pthread_key_t, pthread_key_t>::value,
|
|
"This platform's pthread_key_t differs. If you hit this assert, "
|
|
"fix __swift_pthread_key_t's typedef in LibcShims.h by adding an "
|
|
"#if guard and definition for your platform");
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
int swift::_swift_stdlib_pthread_key_create(
|
|
__swift_pthread_key_t * _Nonnull key,
|
|
void (* _Nullable destructor)(void *)
|
|
) {
|
|
return pthread_key_create(key, destructor);
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
void * _Nullable swift::_swift_stdlib_pthread_getspecific(
|
|
__swift_pthread_key_t key
|
|
) {
|
|
return pthread_getspecific(key);
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
int swift::_swift_stdlib_pthread_setspecific(
|
|
__swift_pthread_key_t key, const void * _Nullable value
|
|
) {
|
|
return pthread_setspecific(key, value);
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
__swift_pthread_key_t _swift_stdlib_PTHREAD_KEYS_MAX(void) {
|
|
return PTHREAD_KEYS_MAX;
|
|
}
|
|
|
|
#if defined(__APPLE__)
|
|
#include <malloc/malloc.h>
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
size_t swift::_swift_stdlib_malloc_size(const void *ptr) {
|
|
return malloc_size(ptr);
|
|
}
|
|
#elif defined(__GNU_LIBRARY__) || defined(__CYGWIN__) || defined(__ANDROID__)
|
|
#include <malloc.h>
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
size_t swift::_swift_stdlib_malloc_size(const void *ptr) {
|
|
return malloc_usable_size(const_cast<void *>(ptr));
|
|
}
|
|
#elif defined(_WIN32)
|
|
#include <malloc.h>
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
size_t swift::_swift_stdlib_malloc_size(const void *ptr) {
|
|
return _msize(const_cast<void *>(ptr));
|
|
}
|
|
#elif defined(__FreeBSD__)
|
|
#include <malloc_np.h>
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
size_t swift::_swift_stdlib_malloc_size(const void *ptr) {
|
|
return malloc_usable_size(const_cast<void *>(ptr));
|
|
}
|
|
#else
|
|
#error No malloc_size analog known for this platform/libc.
|
|
#endif
|
|
|
|
static Lazy<std::mt19937> theGlobalMT19937;
|
|
|
|
static std::mt19937 &getGlobalMT19937() {
|
|
return theGlobalMT19937.get();
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
__swift_uint32_t swift::_swift_stdlib_cxx11_mt19937() {
|
|
return getGlobalMT19937()();
|
|
}
|
|
|
|
SWIFT_RUNTIME_STDLIB_INTERFACE
|
|
__swift_uint32_t
|
|
swift::_swift_stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound) {
|
|
if (upper_bound > 0)
|
|
upper_bound--;
|
|
std::uniform_int_distribution<__swift_uint32_t> RandomUniform(0, upper_bound);
|
|
return RandomUniform(getGlobalMT19937());
|
|
}
|