diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2021-07-22 07:26:47 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-08-09 15:11:58 -0400 |
commit | d5de970dafd5876ef30601697576167f56b9c132 (patch) | |
tree | cb2ccf4bc4c13e39e211beb60915d7bb4ccc477d /includes/rts/OSThreads.h | |
parent | fc350dba63da7eefbaa2793fe9fe99f8571b75c0 (diff) | |
download | haskell-d5de970dafd5876ef30601697576167f56b9c132.tar.gz |
Move `/includes` to `/rts/include`, sort per package better
In order to make the packages in this repo "reinstallable", we need to
associate source code with a specific packages. Having a top level
`/includes` dir that mixes concerns (which packages' includes?) gets in
the way of this.
To start, I have moved everything to `rts/`, which is mostly correct.
There are a few things however that really don't belong in the rts (like
the generated constants haskell type, `CodeGen.Platform.h`). Those
needed to be manually adjusted.
Things of note:
- No symlinking for sake of windows, so we hard-link at configure time.
- `CodeGen.Platform.h` no longer as `.hs` extension (in addition to
being moved to `compiler/`) so as not to confuse anyone, since it is
next to Haskell files.
- Blanket `-Iincludes` is gone in both build systems, include paths now
more strictly respect per-package dependencies.
- `deriveConstants` has been taught to not require a `--target-os` flag
when generating the platform-agnostic Haskell type. Make takes
advantage of this, but Hadrian has yet to.
Diffstat (limited to 'includes/rts/OSThreads.h')
-rw-r--r-- | includes/rts/OSThreads.h | 267 |
1 files changed, 0 insertions, 267 deletions
diff --git a/includes/rts/OSThreads.h b/includes/rts/OSThreads.h deleted file mode 100644 index d24a1313a6..0000000000 --- a/includes/rts/OSThreads.h +++ /dev/null @@ -1,267 +0,0 @@ -/* --------------------------------------------------------------------------- - * - * (c) The GHC Team, 2001-2009 - * - * Accessing OS threads functionality in a (mostly) OS-independent - * manner. - * - * Do not #include this file directly: #include "Rts.h" instead. - * - * To understand the structure of the RTS headers, see the wiki: - * https://gitlab.haskell.org/ghc/ghc/wikis/commentary/source-tree/includes - * - * --------------------------------------------------------------------------*/ - -#pragma once - -#if defined(HAVE_PTHREAD_H) && !defined(mingw32_HOST_OS) - -#if defined(CMINUSMINUS) - -#define OS_ACQUIRE_LOCK(mutex) foreign "C" pthread_mutex_lock(mutex) -#define OS_RELEASE_LOCK(mutex) foreign "C" pthread_mutex_unlock(mutex) -#define OS_ASSERT_LOCK_HELD(mutex) /* nothing */ - -#else - -#include <pthread.h> -#include <errno.h> - -typedef struct { - pthread_cond_t cond; - - // Which clock are pthread_cond_timedwait calls referenced against? - // N.B. Some older Darwin releases don't support clock_gettime. However, we - // do want to reference to CLOCK_MONOTONIC whenever possible as it is more - // robust against system time changes and is likely cheaper to query. -#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) - clockid_t timeout_clk; -#endif -} Condition; -typedef pthread_mutex_t Mutex; -typedef pthread_t OSThreadId; -typedef pthread_key_t ThreadLocalKey; - -#define OSThreadProcAttr /* nothing */ - -#define INIT_COND_VAR PTHREAD_COND_INITIALIZER - -#if defined(LOCK_DEBUG) -#define LOCK_DEBUG_BELCH(what, mutex) \ - debugBelch("%s(0x%p) %s %d\n", what, mutex, __FILE__, __LINE__) -#else -#define LOCK_DEBUG_BELCH(what, mutex) /* nothing */ -#endif - -/* Always check the result of lock and unlock. */ -#define OS_ACQUIRE_LOCK(mutex) { \ - LOCK_DEBUG_BELCH("ACQUIRE_LOCK", mutex); \ - int __r = pthread_mutex_lock(mutex); \ - if (__r != 0) { \ - barf("ACQUIRE_LOCK failed (%s:%d): %d", __FILE__, __LINE__, __r); \ - } } - -// Returns zero if the lock was acquired. -EXTERN_INLINE int OS_TRY_ACQUIRE_LOCK(pthread_mutex_t *mutex); -EXTERN_INLINE int OS_TRY_ACQUIRE_LOCK(pthread_mutex_t *mutex) -{ - LOCK_DEBUG_BELCH("TRY_ACQUIRE_LOCK", mutex); - return pthread_mutex_trylock(mutex); -} - -#define OS_RELEASE_LOCK(mutex) \ - LOCK_DEBUG_BELCH("RELEASE_LOCK", mutex); \ - if (pthread_mutex_unlock(mutex) != 0) { \ - barf("RELEASE_LOCK: I do not own this lock: %s %d", __FILE__,__LINE__); \ - } - -// Note: this assertion calls pthread_mutex_lock() on a mutex that -// is already held by the calling thread. The mutex should therefore -// have been created with PTHREAD_MUTEX_ERRORCHECK, otherwise this -// assertion will hang. We always initialise mutexes with -// PTHREAD_MUTEX_ERRORCHECK when DEBUG is on (see rts/posix/OSThreads.h). -#define OS_ASSERT_LOCK_HELD(mutex) ASSERT(pthread_mutex_lock(mutex) == EDEADLK) - -#endif // CMINUSMINUS - -# elif defined(HAVE_WINDOWS_H) - -#if defined(CMINUSMINUS) - -/* We jump through a hoop here to get a CCall AcquireSRWLockExclusive - and ReleaseSRWLockExclusive, as that's what C-- wants. */ - -#define OS_ACQUIRE_LOCK(mutex) foreign "stdcall" AcquireSRWLockExclusive(mutex) -#define OS_RELEASE_LOCK(mutex) foreign "stdcall" ReleaseSRWLockExclusive(mutex) -#define OS_ASSERT_LOCK_HELD(mutex) /* nothing */ - -#else // CMINUSMINUS - -#include <windows.h> -#include <synchapi.h> - -/* Use native conditional variables coupled with SRW locks, these are more - efficient and occur a smaller overhead then emulating them with events. - See Note [SRW locks]. */ -typedef CONDITION_VARIABLE Condition; -typedef DWORD OSThreadId; -// don't be tempted to use HANDLE as the OSThreadId: there can be -// many HANDLES to a given thread, so comparison would not work. -typedef DWORD ThreadLocalKey; - -#define OSThreadProcAttr __stdcall - -#define INIT_COND_VAR 0 - -/* Note [SRW locks] - We have a choice for implementing Mutexes on Windows. Standard - Mutexes are kernel objects that require kernel calls to - acquire/release, whereas CriticalSections are spin-locks that block - in the kernel after spinning for a configurable number of times. - CriticalSections are *much* faster than Mutexes, however not as fast as - slim reader/writer locks. CriticalSections also require a 48 byte structure - to provide lock re-entrancy. We don't need that because the other primitives - used for other platforms don't have this, as such locks are used defensively - in the RTS in a way that we don't need re-entrancy. This means that SRW's - 8 byte size is much more appropriate. With an 8 byte payload there's a - higher chance of it being in your cache line. They're also a lot faster than - CriticalSections when multiple threads are involved. CS requires setup and - teardown via kernel calls while SRWL is zero-initialized via - SRWLOCK_INIT assignment. */ - -typedef SRWLOCK Mutex; - -#if defined(LOCK_DEBUG) - -#define OS_ACQUIRE_LOCK(mutex) \ - debugBelch("ACQUIRE_LOCK(0x%p) %s %d\n", mutex,__FILE__,__LINE__); \ - AcquireSRWLockExclusive(mutex) -#define OS_RELEASE_LOCK(mutex) \ - debugBelch("RELEASE_LOCK(0x%p) %s %d\n", mutex,__FILE__,__LINE__); \ - ReleaseSRWLockExclusive(mutex) -#define OS_ASSERT_LOCK_HELD(mutex) /* nothing */ - -#else - -#define OS_ACQUIRE_LOCK(mutex) AcquireSRWLockExclusive(mutex) -#define OS_TRY_ACQUIRE_LOCK(mutex) (TryAcquireSRWLockExclusive(mutex) == 0) -#define OS_RELEASE_LOCK(mutex) ReleaseSRWLockExclusive(mutex) -#define OS_INIT_LOCK(mutex) InitializeSRWLock(mutex) -#define OS_CLOSE_LOCK(mutex) - -// I don't know how to do this. TryEnterCriticalSection() doesn't do -// the right thing. -#define OS_ASSERT_LOCK_HELD(mutex) /* nothing */ - -#endif // LOCK_DEBUG - -#endif // CMINUSMINUS - -# elif defined(THREADED_RTS) -# error "Threads not supported" -# endif - - -#if !defined(CMINUSMINUS) -// -// General thread operations -// -extern OSThreadId osThreadId ( void ); -extern void shutdownThread ( void ) GNUC3_ATTRIBUTE(__noreturn__); -extern void yieldThread ( void ); - -typedef void* OSThreadProcAttr OSThreadProc(void *); - -extern int createOSThread ( OSThreadId* tid, char *name, - OSThreadProc *startProc, void *param); -extern bool osThreadIsAlive ( OSThreadId id ); -extern void interruptOSThread ( OSThreadId id ); -extern void joinOSThread ( OSThreadId id ); - -// -// Condition Variables -// -extern void initCondition ( Condition* pCond ); -extern void closeCondition ( Condition* pCond ); -extern void broadcastCondition ( Condition* pCond ); -extern void signalCondition ( Condition* pCond ); -extern void waitCondition ( Condition* pCond, Mutex* pMut ); -// Returns false on timeout, true otherwise. -extern bool timedWaitCondition ( Condition* pCond, Mutex* pMut, Time timeout); - -// -// Mutexes -// -extern void initMutex ( Mutex* pMut ); -extern void closeMutex ( Mutex* pMut ); - -// -// Thread-local storage -// -void newThreadLocalKey (ThreadLocalKey *key); -void *getThreadLocalVar (ThreadLocalKey *key); -void setThreadLocalVar (ThreadLocalKey *key, void *value); -void freeThreadLocalKey (ThreadLocalKey *key); - -// Processors and affinity -void setThreadAffinity (uint32_t n, uint32_t m); -void setThreadNode (uint32_t node); -void releaseThreadNode (void); -#endif // !CMINUSMINUS - -#if defined(THREADED_RTS) - -#define ACQUIRE_LOCK(l) OS_ACQUIRE_LOCK(l) -#define TRY_ACQUIRE_LOCK(l) OS_TRY_ACQUIRE_LOCK(l) -#define RELEASE_LOCK(l) OS_RELEASE_LOCK(l) -#define ASSERT_LOCK_HELD(l) OS_ASSERT_LOCK_HELD(l) - -#else - -#define ACQUIRE_LOCK(l) -#define TRY_ACQUIRE_LOCK(l) 0 -#define RELEASE_LOCK(l) -#define ASSERT_LOCK_HELD(l) - -#endif /* defined(THREADED_RTS) */ - -#if !defined(CMINUSMINUS) -// -// Support for forkOS (defined regardless of THREADED_RTS, but does -// nothing when !THREADED_RTS). -// -int forkOS_createThread ( HsStablePtr entry ); - -// -// Free any global resources created in OSThreads. -// -void freeThreadingResources(void); - -// -// Returns the number of processor cores in the machine -// -uint32_t getNumberOfProcessors (void); - -// -// Support for getting at the kernel thread Id for tracing/profiling. -// -// This stuff is optional and only used for tracing/profiling purposes, to -// match up thread ids recorded by other tools. For example, on Linux and OSX -// the pthread_t type is not the same as the kernel thread id, and system -// profiling tools like Linux perf, and OSX's DTrace use the kernel thread Id. -// So if we want to match up RTS tasks with kernel threads recorded by these -// tools then we need to know the kernel thread Id, and this must be a separate -// type from the OSThreadId. -// -// If the feature cannot be supported on an OS, it is OK to always return 0. -// In particular it would almost certainly be meaningless on systems not using -// a 1:1 threading model. - -// We use a common serialisable representation on all OSs -// This is ok for Windows, OSX and Linux. -typedef StgWord64 KernelThreadId; - -// Get the current kernel thread id -KernelThreadId kernelThreadId (void); - -#endif /* CMINUSMINUS */ |