summaryrefslogtreecommitdiff
path: root/includes/rts/OSThreads.h
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2021-07-22 07:26:47 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-08-09 15:11:58 -0400
commitd5de970dafd5876ef30601697576167f56b9c132 (patch)
treecb2ccf4bc4c13e39e211beb60915d7bb4ccc477d /includes/rts/OSThreads.h
parentfc350dba63da7eefbaa2793fe9fe99f8571b75c0 (diff)
downloadhaskell-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.h267
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 */