//////////////////////// \brief SysFutexWait(futex, expected) Wait on a futex. Will wait on the futex if the value is equal to expected \param futex (void*) Futex pointer \param expected (int) Expected futex value \return 0 on success, error code on failure ////////////////////////
| 1976 | /// \return 0 on success, error code on failure |
| 1977 | ///////////////////////////// |
| 1978 | long SysFutexWait(regs64_t* r){ |
| 1979 | int* futex = reinterpret_cast<int*>(SC_ARG0(r)); |
| 1980 | |
| 1981 | if(!Memory::CheckUsermodePointer(SC_ARG0(r), sizeof(int), Scheduler::GetCurrentProcess()->addressSpace)){ |
| 1982 | return EFAULT; |
| 1983 | } |
| 1984 | |
| 1985 | int expected = static_cast<int>(SC_ARG1(r)); |
| 1986 | |
| 1987 | if(*futex != expected){ |
| 1988 | return 0; |
| 1989 | } |
| 1990 | |
| 1991 | process_t* currentProcess = Scheduler::GetCurrentProcess(); |
| 1992 | |
| 1993 | Scheduler::FutexThreadBlocker* blocker = currentProcess->futexWaitQueue.get(reinterpret_cast<uintptr_t>(futex)); |
| 1994 | |
| 1995 | if(!blocker){ |
| 1996 | blocker = new Scheduler::FutexThreadBlocker(); |
| 1997 | |
| 1998 | currentProcess->futexWaitQueue.insert(reinterpret_cast<uintptr_t>(futex), blocker); |
| 1999 | } |
| 2000 | |
| 2001 | releaseLock(&GetCPULocal()->currentThread->lock); |
| 2002 | |
| 2003 | lock_t temp = 0; |
| 2004 | Scheduler::BlockCurrentThread(*blocker, temp); |
| 2005 | |
| 2006 | return 0; |
| 2007 | } |
| 2008 | |
| 2009 | ///////////////////////////// |
| 2010 | /// \brief SysDup(fd) Duplicate a file descriptor |
nothing calls this directly
no test coverage detected