20 #include "PosixSubsystem.h" 21 #include "pedigree/kernel/errors.h" 22 #include "pedigree/kernel/process/PerProcessorScheduler.h" 23 #include "pedigree/kernel/process/Process.h" 24 #include "pedigree/kernel/process/Scheduler.h" 25 #include "pedigree/kernel/syscallError.h" 26 #include "pedigree/kernel/utilities/List.h" 27 #include "pedigree/kernel/utilities/Tree.h" 28 #include <pthread-syscalls.h> 34 #define FUTEX_REQUEUE 3 35 #define FUTEX_CMP_REQUEUE 4 36 #define FUTEX_WAKE_OP 5 37 #define FUTEX_LOCK_PI 6 38 #define FUTEX_UNLOCK_PI 7 39 #define FUTEX_TRYLOCK_PI 8 40 #define FUTEX_WAIT_BITSET 9 41 #define FUTEX_PRIVATE 128 42 #define FUTEX_CLOCK_REALTIME 256 45 extern void pthread_stub();
46 extern char pthread_stub_end;
52 int *uaddr,
int futex_op,
int val,
const struct timespec *timeout)
60 ERROR(
"No subsystem for this process!");
65 "futex(" <<
Hex << uaddr <<
", " << futex_op <<
", " << val <<
", " 68 if (!(futex_op & FUTEX_PRIVATE))
70 PT_NOTICE(
" -> warning: public futexes are not yet supported");
73 if (futex_op & FUTEX_CLOCK_REALTIME)
75 PT_NOTICE(
" -> warning: clock choice (monotonic vs realtime) is not " 77 futex_op &= ~FUTEX_CLOCK_REALTIME;
80 futex_op &= ~FUTEX_PRIVATE;
89 PT_NOTICE(
" -> FUTEX_WAIT");
94 PT_NOTICE(
" -> value changed");
95 SYSCALL_ERROR(NoMoreProcesses);
100 bool newLock =
false;
107 g_futexes.
insert(uaddr, threads);
112 PT_NOTICE(
" -> waiting...");
114 PT_NOTICE(
" -> waiting complete!");
121 PT_NOTICE(
" -> FUTEX_WAKE");
127 for (
int i = 0; i < val && threads->
count() > 0; ++i)
130 PT_NOTICE(
" -> waking " << pWakeThread);
134 PT_NOTICE(
" -> woken!");
138 PT_NOTICE(
" -> woke " <<
Dec << woken <<
" threads.");
145 PT_NOTICE(
" -> unsupported futex operation");
146 SYSCALL_ERROR(Unimplemented);
150 PT_NOTICE(
" -> " <<
Dec << r);
157 void pedigree_copy_posix_thread(
163 if (!pOldPosixThread)
171 pNewPosixThread->pThread = newThread;
172 pNewPosixThread->returnValue = 0;
179 size_t key = it.key();
183 pNewPosixThread->m_ThreadKeys.
set(key);
199 void pedigree_init_pthreads()
201 PT_NOTICE(
"init_pthreads");
208 reinterpret_cast<void *>(pthread_stub),
209 (reinterpret_cast<uintptr_t>(&pthread_stub_end) -
210 reinterpret_cast<uintptr_t>(pthread_stub)));
222 ERROR(
"No subsystem for this process!");
227 pPosixThread->pThread = pThread;
228 pPosixThread->returnValue = 0;
232 void *posix_pedigree_create_waiter()
234 PT_NOTICE(
"posix_pedigree_create_waiter");
242 ERROR(
"No subsystem for this process!");
256 int posix_pedigree_thread_wait_for(
void *waiter)
258 PT_NOTICE(
"posix_pedigree_thread_wait_for");
266 ERROR(
"No subsystem for this process!");
281 SYSCALL_ERROR(Deadlock);
291 int posix_pedigree_thread_trigger(
void *waiter)
293 PT_NOTICE(
"posix_pedigree_thread_trigger");
301 ERROR(
"No subsystem for this process!");
316 void posix_pedigree_destroy_waiter(
void *waiter)
318 PT_NOTICE(
"posix_pedigree_destroy_waiter");
326 ERROR(
"No subsystem for this process!");
346 return pProcess->
getId();
350 return pThread->
getId();
void pushBack(const T &value)
Tree< size_t, PosixThreadKey * > m_ThreadData
static uintptr_t getTrampoline()
bool acquire(size_t n=1, size_t timeoutSecs=0, size_t timeoutUsecs=0)
void removeThreadWaiter(void *n)
void * insertThreadWaiter(Semaphore *waiter)
static const size_t Execute
bool acquire(bool recurse=false, bool safe=true)
static ProcessorInformation & information()
static const size_t Write
void insert(const K &key, const E &value)
static const size_t Shared
bool addThreadData(size_t key, PosixThreadKey *info)
PosixThread * getThread(size_t n)
Process * getParent() const
Semaphore * getThreadWaiter(void *n)
size_t lastDataKey
Last data key that was allocated (for the bitmap)
void insertThread(size_t n, PosixThread *thread)
size_t nextDataKey
Next data key available.
static uintptr_t getSecondaryTrampoline()
E lookup(const K &key) const