[kernel] Add (wip) futex syscalls
Add the syscalls j6_futex_wait and j6_futex_wake. Currently marking this as WIP as they need more testing. Added to support futexes: - vm_area and vm_space support for looking up physical address for a virtual address - libj6 mutex implementation using futex system calls
This commit is contained in:
@@ -6,6 +6,7 @@ j6 = module("j6",
|
||||
sources = [
|
||||
"init.cpp",
|
||||
"init.s",
|
||||
"mutex.cpp",
|
||||
"protocol_ids.cpp",
|
||||
"syscalls.s.cog",
|
||||
"sysconf.cpp.cog",
|
||||
@@ -17,6 +18,7 @@ j6 = module("j6",
|
||||
"j6/errors.h",
|
||||
"j6/flags.h",
|
||||
"j6/init.h",
|
||||
"j6/mutex.hh",
|
||||
"j6/protocols.h",
|
||||
"j6/protocols/service_locator.h",
|
||||
"j6/syscalls.h.cog",
|
||||
|
||||
42
src/libraries/j6/j6/mutex.hh
Normal file
42
src/libraries/j6/j6/mutex.hh
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
/// \file mutex.hh
|
||||
/// High level mutex interface
|
||||
|
||||
// The kernel depends on libj6 for some shared code,
|
||||
// but should not include the user-specific code.
|
||||
#ifndef __j6kernel
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace j6 {
|
||||
|
||||
class mutex
|
||||
{
|
||||
public:
|
||||
mutex() : m_state(0) {}
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
private:
|
||||
uint32_t m_state;
|
||||
};
|
||||
|
||||
class scoped_lock
|
||||
{
|
||||
public:
|
||||
inline scoped_lock(mutex &m) : m_mutex {m} {
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
inline ~scoped_lock() {
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
mutex &m_mutex;
|
||||
};
|
||||
|
||||
} // namespace j6
|
||||
|
||||
#endif // __j6kernel
|
||||
36
src/libraries/j6/mutex.cpp
Normal file
36
src/libraries/j6/mutex.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// The kernel depends on libj6 for some shared code,
|
||||
// but should not include the user-specific code.
|
||||
#ifndef __j6kernel
|
||||
|
||||
#include <j6/mutex.hh>
|
||||
#include <j6/syscalls.h>
|
||||
|
||||
namespace j6 {
|
||||
|
||||
void
|
||||
mutex::lock()
|
||||
{
|
||||
uint32_t lock = 0;
|
||||
if ((lock = __sync_val_compare_and_swap(&m_state, 0, 1)) != 0) {
|
||||
if (lock != 2)
|
||||
lock = __atomic_exchange_n(&m_state, 2, __ATOMIC_ACQ_REL);
|
||||
while (lock) {
|
||||
j6_futex_wait(&m_state, 2, 0);
|
||||
lock = __atomic_exchange_n(&m_state, 2, __ATOMIC_ACQ_REL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mutex::unlock()
|
||||
{
|
||||
if (__atomic_fetch_sub(&m_state, 1, __ATOMIC_ACQ_REL) != 1) {
|
||||
__atomic_store_n(&m_state, 0, __ATOMIC_RELEASE);
|
||||
j6_futex_wake(&m_state, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace j6
|
||||
|
||||
#endif // __j6kernel
|
||||
Reference in New Issue
Block a user