Compare commits
3 Commits
a2e918c428
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 30c9c9db45 | |||
| c1e0b38952 | |||
| 8a38d940cc |
@@ -6,6 +6,7 @@
|
|||||||
#include <kernel/vm.h>
|
#include <kernel/vm.h>
|
||||||
|
|
||||||
#define ADDRESS_SPACE_COPY_ALL ((size_t) - 1)
|
#define ADDRESS_SPACE_COPY_ALL ((size_t) - 1)
|
||||||
|
#define ADDRESS_SPACE_F_
|
||||||
|
|
||||||
struct address_space;
|
struct address_space;
|
||||||
struct vm_object;
|
struct vm_object;
|
||||||
@@ -158,6 +159,12 @@ extern kern_status_t address_space_memmove_v(
|
|||||||
size_t bytes_to_move,
|
size_t bytes_to_move,
|
||||||
size_t *nr_bytes_moved);
|
size_t *nr_bytes_moved);
|
||||||
|
|
||||||
|
extern kern_status_t address_space_translate(
|
||||||
|
struct address_space *space,
|
||||||
|
virt_addr_t in,
|
||||||
|
phys_addr_t *out,
|
||||||
|
unsigned long *irq_flags);
|
||||||
|
|
||||||
void address_space_dump(struct address_space *region);
|
void address_space_dump(struct address_space *region);
|
||||||
|
|
||||||
DEFINE_OBJECT_LOCK_FUNCTION(address_space, s_base)
|
DEFINE_OBJECT_LOCK_FUNCTION(address_space, s_base)
|
||||||
|
|||||||
26
include/kernel/futex.h
Normal file
26
include/kernel/futex.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef KERNEL_FUTEX_H_
|
||||||
|
#define KERNEL_FUTEX_H_
|
||||||
|
|
||||||
|
#include <kernel/btree.h>
|
||||||
|
#include <kernel/wait.h>
|
||||||
|
#include <mango/types.h>
|
||||||
|
|
||||||
|
struct address_space;
|
||||||
|
|
||||||
|
typedef phys_addr_t futex_key_t;
|
||||||
|
|
||||||
|
struct futex {
|
||||||
|
struct btree_node f_node;
|
||||||
|
futex_key_t f_key;
|
||||||
|
struct waitqueue f_waiters;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern kern_status_t futex_init(void);
|
||||||
|
extern kern_status_t futex_get(
|
||||||
|
struct address_space *space,
|
||||||
|
kern_futex_t *futex,
|
||||||
|
futex_key_t *out);
|
||||||
|
extern kern_status_t futex_wait(futex_key_t futex, kern_futex_t new_val);
|
||||||
|
extern kern_status_t futex_wake(futex_key_t futex, size_t nwaiters);
|
||||||
|
|
||||||
|
#endif
|
||||||
70
kernel/futex.c
Normal file
70
kernel/futex.c
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#include <kernel/address-space.h>
|
||||||
|
#include <kernel/futex.h>
|
||||||
|
#include <mango/status.h>
|
||||||
|
|
||||||
|
enum futex_flags {
|
||||||
|
FUTEX_CREATE = 0x01u,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct btree futex_list = {0};
|
||||||
|
static spin_lock_t futex_list_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
|
static struct vm_cache futex_cache = {
|
||||||
|
.c_name = "futex",
|
||||||
|
.c_obj_size = sizeof(struct futex),
|
||||||
|
};
|
||||||
|
|
||||||
|
BTREE_DEFINE_SIMPLE_INSERT(struct futex, f_node, f_key, put_futex)
|
||||||
|
BTREE_DEFINE_SIMPLE_GET(struct futex, futex_key_t, f_node, f_key, get_futex)
|
||||||
|
|
||||||
|
kern_status_t futex_init(void)
|
||||||
|
{
|
||||||
|
vm_cache_init(&futex_cache);
|
||||||
|
return KERN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct futex *get_data(futex_key_t key, enum futex_flags flags)
|
||||||
|
{
|
||||||
|
spin_lock(&futex_list_lock);
|
||||||
|
struct futex *futex = get_futex(&futex_list, key);
|
||||||
|
spin_unlock(&futex_list_lock);
|
||||||
|
|
||||||
|
if (!futex && !(flags & FUTEX_CREATE)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
futex = vm_cache_alloc(&futex_cache, VM_NORMAL);
|
||||||
|
futex->f_key = key;
|
||||||
|
|
||||||
|
spin_lock(&futex_list_lock);
|
||||||
|
put_futex(&futex_list, futex);
|
||||||
|
spin_unlock(&futex_list_lock);
|
||||||
|
|
||||||
|
return futex;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t futex_get(
|
||||||
|
struct address_space *space,
|
||||||
|
kern_futex_t *futex,
|
||||||
|
futex_key_t *out)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
address_space_lock_irqsave(space, &flags);
|
||||||
|
kern_status_t status = address_space_translate(
|
||||||
|
space,
|
||||||
|
(virt_addr_t)futex,
|
||||||
|
out,
|
||||||
|
&flags);
|
||||||
|
address_space_unlock_irqrestore(space, flags);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t futex_wait(futex_key_t futex, kern_futex_t new_val)
|
||||||
|
{
|
||||||
|
return KERN_UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
kern_status_t futex_wake(futex_key_t futex, size_t nwaiters)
|
||||||
|
{
|
||||||
|
return KERN_UNIMPLEMENTED;
|
||||||
|
}
|
||||||
0
libmango/include-user/mango/futex.h
Normal file
0
libmango/include-user/mango/futex.h
Normal file
@@ -46,20 +46,16 @@
|
|||||||
|
|
||||||
#define IOVEC(p, len) \
|
#define IOVEC(p, len) \
|
||||||
{ \
|
{ \
|
||||||
.io_base = (virt_addr_t)(p), \
|
.io_base = (virt_addr_t)(p), .io_len = (len), \
|
||||||
.io_len = (len), \
|
|
||||||
}
|
}
|
||||||
#define MSG_HANDLE(mode, value) \
|
#define MSG_HANDLE(mode, value) \
|
||||||
{ \
|
{ \
|
||||||
.hnd_mode = (mode), \
|
.hnd_mode = (mode), .hnd_value = (value), \
|
||||||
.hnd_value = (value), \
|
|
||||||
}
|
}
|
||||||
#define MSG(data, data_count, handles, handles_len) \
|
#define MSG(data, data_count, handles, handles_len) \
|
||||||
{ \
|
{ \
|
||||||
.msg_data = (data), \
|
.msg_data = (data), .msg_data_count = (data_count), \
|
||||||
.msg_data_count = (data_count), \
|
.msg_handles = (handles), .msg_handles_count = (handles_len), \
|
||||||
.msg_handles = (handles), \
|
|
||||||
.msg_handles_count = (handles_len), \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef uintptr_t phys_addr_t;
|
typedef uintptr_t phys_addr_t;
|
||||||
@@ -75,6 +71,7 @@ typedef uint32_t kern_handle_t;
|
|||||||
typedef uint32_t kern_config_key_t;
|
typedef uint32_t kern_config_key_t;
|
||||||
typedef uint32_t vm_prot_t;
|
typedef uint32_t vm_prot_t;
|
||||||
typedef int64_t ssize_t;
|
typedef int64_t ssize_t;
|
||||||
|
typedef uint32_t kern_futex_t;
|
||||||
|
|
||||||
typedef unsigned short equeue_packet_type_t;
|
typedef unsigned short equeue_packet_type_t;
|
||||||
|
|
||||||
|
|||||||
@@ -1413,6 +1413,42 @@ extern kern_status_t address_space_memmove_v(
|
|||||||
return KERN_OK;
|
return KERN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kern_status_t address_space_translate(
|
||||||
|
struct address_space *space,
|
||||||
|
virt_addr_t in,
|
||||||
|
phys_addr_t *out,
|
||||||
|
unsigned long *irq_flags)
|
||||||
|
{
|
||||||
|
if (in >= VM_KERNEL_BASE) {
|
||||||
|
return vm_virt_to_phys((const void *)in);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct vm_area *area = get_entry(space, in, GET_ENTRY_EXACT);
|
||||||
|
if (!area || !area->vma_object) {
|
||||||
|
return KERN_NO_ENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t offset = in - area->vma_base + area->vma_object_offset;
|
||||||
|
struct vm_object *vmo = area->vma_object;
|
||||||
|
vm_object_lock(vmo);
|
||||||
|
address_space_unlock(space);
|
||||||
|
struct vm_page *pg = vm_object_get_page(
|
||||||
|
vmo,
|
||||||
|
offset,
|
||||||
|
VMO_ALLOCATE_MISSING_PAGE | VMO_REQUEST_MISSING_PAGE,
|
||||||
|
irq_flags);
|
||||||
|
if (!pg) {
|
||||||
|
return KERN_NO_ENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
phys_addr_t paddr = vm_page_get_paddr(pg);
|
||||||
|
paddr += (in & VM_PAGE_MASK);
|
||||||
|
vm_object_unlock(vmo);
|
||||||
|
address_space_lock(space);
|
||||||
|
|
||||||
|
return paddr;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
void address_space_dump(struct address_space *region)
|
void address_space_dump(struct address_space *region)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <kernel/address-space.h>
|
#include <kernel/address-space.h>
|
||||||
|
#include <kernel/printk.h>
|
||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <kernel/util.h>
|
#include <kernel/util.h>
|
||||||
#include <kernel/vm-controller.h>
|
#include <kernel/vm-controller.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user