Compare commits
No commits in common. "5d62fa3f1038757d9de0742aa42165d45dc3a390" and "4af9699b22e68075df2d660bb29f322d67a691e1" have entirely different histories.
5d62fa3f10
...
4af9699b22
|
|
@ -221,7 +221,7 @@ namespace Kernel
|
||||||
ASSERT(!(pt[pte] & Flags::Present));
|
ASSERT(!(pt[pte] & Flags::Present));
|
||||||
pt[pte] = paddr | Flags::ReadWrite | Flags::Present;
|
pt[pte] = paddr | Flags::ReadWrite | Flags::Present;
|
||||||
|
|
||||||
asm volatile("invlpg (%0)" :: "r"(fast_page()) : "memory");
|
invalidate(fast_page(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageTable::unmap_fast_page()
|
void PageTable::unmap_fast_page()
|
||||||
|
|
@ -241,7 +241,7 @@ namespace Kernel
|
||||||
ASSERT(pt[pte] & Flags::Present);
|
ASSERT(pt[pte] & Flags::Present);
|
||||||
pt[pte] = 0;
|
pt[pte] = 0;
|
||||||
|
|
||||||
asm volatile("invlpg (%0)" :: "r"(fast_page()) : "memory");
|
invalidate(fast_page(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<PageTable*> PageTable::create_userspace()
|
BAN::ErrorOr<PageTable*> PageTable::create_userspace()
|
||||||
|
|
@ -314,8 +314,7 @@ namespace Kernel
|
||||||
.type = Processor::SMPMessage::Type::FlushTLB,
|
.type = Processor::SMPMessage::Type::FlushTLB,
|
||||||
.flush_tlb = {
|
.flush_tlb = {
|
||||||
.vaddr = vaddr,
|
.vaddr = vaddr,
|
||||||
.page_count = 1,
|
.page_count = 1
|
||||||
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -344,12 +343,8 @@ namespace Kernel
|
||||||
uint64_t* pd = reinterpret_cast<uint64_t*>(P2V(pdpt[pdpte] & PAGE_ADDR_MASK));
|
uint64_t* pd = reinterpret_cast<uint64_t*>(P2V(pdpt[pdpte] & PAGE_ADDR_MASK));
|
||||||
uint64_t* pt = reinterpret_cast<uint64_t*>(P2V(pd[pde] & PAGE_ADDR_MASK));
|
uint64_t* pt = reinterpret_cast<uint64_t*>(P2V(pd[pde] & PAGE_ADDR_MASK));
|
||||||
|
|
||||||
const paddr_t old_paddr = pt[pte] & PAGE_ADDR_MASK;
|
|
||||||
|
|
||||||
pt[pte] = 0;
|
pt[pte] = 0;
|
||||||
|
invalidate(vaddr, send_smp_message);
|
||||||
if (old_paddr != 0)
|
|
||||||
invalidate(vaddr, send_smp_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageTable::unmap_range(vaddr_t vaddr, size_t size)
|
void PageTable::unmap_range(vaddr_t vaddr, size_t size)
|
||||||
|
|
@ -366,8 +361,7 @@ namespace Kernel
|
||||||
.type = Processor::SMPMessage::Type::FlushTLB,
|
.type = Processor::SMPMessage::Type::FlushTLB,
|
||||||
.flush_tlb = {
|
.flush_tlb = {
|
||||||
.vaddr = vaddr,
|
.vaddr = vaddr,
|
||||||
.page_count = page_count,
|
.page_count = page_count
|
||||||
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -423,13 +417,9 @@ namespace Kernel
|
||||||
uwr_flags &= ~Flags::Present;
|
uwr_flags &= ~Flags::Present;
|
||||||
|
|
||||||
uint64_t* pt = reinterpret_cast<uint64_t*>(P2V(pd[pde] & PAGE_ADDR_MASK));
|
uint64_t* pt = reinterpret_cast<uint64_t*>(P2V(pd[pde] & PAGE_ADDR_MASK));
|
||||||
|
|
||||||
const paddr_t old_paddr = pt[pte] & PAGE_ADDR_MASK;
|
|
||||||
|
|
||||||
pt[pte] = paddr | uwr_flags | extra_flags;
|
pt[pte] = paddr | uwr_flags | extra_flags;
|
||||||
|
|
||||||
if (old_paddr != 0)
|
invalidate(vaddr, send_smp_message);
|
||||||
invalidate(vaddr, send_smp_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageTable::map_range_at(paddr_t paddr, vaddr_t vaddr, size_t size, flags_t flags, MemoryType memory_type)
|
void PageTable::map_range_at(paddr_t paddr, vaddr_t vaddr, size_t size, flags_t flags, MemoryType memory_type)
|
||||||
|
|
@ -448,8 +438,7 @@ namespace Kernel
|
||||||
.type = Processor::SMPMessage::Type::FlushTLB,
|
.type = Processor::SMPMessage::Type::FlushTLB,
|
||||||
.flush_tlb = {
|
.flush_tlb = {
|
||||||
.vaddr = vaddr,
|
.vaddr = vaddr,
|
||||||
.page_count = page_count,
|
.page_count = page_count
|
||||||
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -534,7 +523,6 @@ namespace Kernel
|
||||||
.flush_tlb = {
|
.flush_tlb = {
|
||||||
.vaddr = vaddr,
|
.vaddr = vaddr,
|
||||||
.page_count = bytes / PAGE_SIZE,
|
.page_count = bytes / PAGE_SIZE,
|
||||||
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -521,7 +521,7 @@ namespace Kernel
|
||||||
ASSERT(!(pt[pte] & Flags::Present));
|
ASSERT(!(pt[pte] & Flags::Present));
|
||||||
pt[pte] = paddr | Flags::ReadWrite | Flags::Present;
|
pt[pte] = paddr | Flags::ReadWrite | Flags::Present;
|
||||||
|
|
||||||
asm volatile("invlpg (%0)" :: "r"(fast_page()) : "memory");
|
invalidate(fast_page(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageTable::unmap_fast_page()
|
void PageTable::unmap_fast_page()
|
||||||
|
|
@ -544,7 +544,7 @@ namespace Kernel
|
||||||
ASSERT(pt[pte] & Flags::Present);
|
ASSERT(pt[pte] & Flags::Present);
|
||||||
pt[pte] = 0;
|
pt[pte] = 0;
|
||||||
|
|
||||||
asm volatile("invlpg (%0)" :: "r"(fast_page()) : "memory");
|
invalidate(fast_page(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<PageTable*> PageTable::create_userspace()
|
BAN::ErrorOr<PageTable*> PageTable::create_userspace()
|
||||||
|
|
@ -623,8 +623,7 @@ namespace Kernel
|
||||||
.type = Processor::SMPMessage::Type::FlushTLB,
|
.type = Processor::SMPMessage::Type::FlushTLB,
|
||||||
.flush_tlb = {
|
.flush_tlb = {
|
||||||
.vaddr = vaddr,
|
.vaddr = vaddr,
|
||||||
.page_count = 1,
|
.page_count = 1
|
||||||
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -659,12 +658,8 @@ namespace Kernel
|
||||||
uint64_t* pd = P2V(pdpt[pdpte] & s_page_addr_mask);
|
uint64_t* pd = P2V(pdpt[pdpte] & s_page_addr_mask);
|
||||||
uint64_t* pt = P2V(pd[pde] & s_page_addr_mask);
|
uint64_t* pt = P2V(pd[pde] & s_page_addr_mask);
|
||||||
|
|
||||||
const paddr_t old_paddr = pt[pte] & PAGE_ADDR_MASK;
|
|
||||||
|
|
||||||
pt[pte] = 0;
|
pt[pte] = 0;
|
||||||
|
invalidate(vaddr, send_smp_message);
|
||||||
if (old_paddr != 0)
|
|
||||||
invalidate(vaddr, send_smp_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageTable::unmap_range(vaddr_t vaddr, size_t size)
|
void PageTable::unmap_range(vaddr_t vaddr, size_t size)
|
||||||
|
|
@ -681,8 +676,7 @@ namespace Kernel
|
||||||
.type = Processor::SMPMessage::Type::FlushTLB,
|
.type = Processor::SMPMessage::Type::FlushTLB,
|
||||||
.flush_tlb = {
|
.flush_tlb = {
|
||||||
.vaddr = vaddr,
|
.vaddr = vaddr,
|
||||||
.page_count = page_count,
|
.page_count = page_count
|
||||||
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -748,12 +742,9 @@ namespace Kernel
|
||||||
if (!(flags & Flags::Present))
|
if (!(flags & Flags::Present))
|
||||||
uwr_flags &= ~Flags::Present;
|
uwr_flags &= ~Flags::Present;
|
||||||
|
|
||||||
const paddr_t old_paddr = pt[pte] & PAGE_ADDR_MASK;
|
|
||||||
|
|
||||||
pt[pte] = paddr | uwr_flags | extra_flags;
|
pt[pte] = paddr | uwr_flags | extra_flags;
|
||||||
|
|
||||||
if (old_paddr != 0)
|
invalidate(vaddr, send_smp_message);
|
||||||
invalidate(vaddr, send_smp_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageTable::map_range_at(paddr_t paddr, vaddr_t vaddr, size_t size, flags_t flags, MemoryType memory_type)
|
void PageTable::map_range_at(paddr_t paddr, vaddr_t vaddr, size_t size, flags_t flags, MemoryType memory_type)
|
||||||
|
|
@ -774,8 +765,7 @@ namespace Kernel
|
||||||
.type = Processor::SMPMessage::Type::FlushTLB,
|
.type = Processor::SMPMessage::Type::FlushTLB,
|
||||||
.flush_tlb = {
|
.flush_tlb = {
|
||||||
.vaddr = vaddr,
|
.vaddr = vaddr,
|
||||||
.page_count = page_count,
|
.page_count = page_count
|
||||||
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -850,7 +840,6 @@ namespace Kernel
|
||||||
.flush_tlb = {
|
.flush_tlb = {
|
||||||
.vaddr = vaddr,
|
.vaddr = vaddr,
|
||||||
.page_count = bytes / PAGE_SIZE,
|
.page_count = bytes / PAGE_SIZE,
|
||||||
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@
|
||||||
namespace Debug
|
namespace Debug
|
||||||
{
|
{
|
||||||
void dump_stack_trace();
|
void dump_stack_trace();
|
||||||
void dump_stack_trace(uintptr_t ip, uintptr_t bp);
|
|
||||||
void dump_qr_code();
|
void dump_qr_code();
|
||||||
|
|
||||||
void putchar(char);
|
void putchar(char);
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,6 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> cleanup_indirect_block(uint32_t block, uint32_t depth);
|
BAN::ErrorOr<void> cleanup_indirect_block(uint32_t block, uint32_t depth);
|
||||||
BAN::ErrorOr<void> cleanup_default_links();
|
BAN::ErrorOr<void> cleanup_default_links();
|
||||||
BAN::ErrorOr<void> cleanup_data_blocks();
|
|
||||||
BAN::ErrorOr<void> cleanup_from_fs();
|
BAN::ErrorOr<void> cleanup_from_fs();
|
||||||
|
|
||||||
BAN::ErrorOr<void> sync();
|
BAN::ErrorOr<void> sync();
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ namespace Kernel
|
||||||
void map_kernel_memory();
|
void map_kernel_memory();
|
||||||
void prepare_fast_page();
|
void prepare_fast_page();
|
||||||
|
|
||||||
void invalidate(vaddr_t, bool send_smp_message);
|
static void invalidate(vaddr_t, bool send_smp_message);
|
||||||
|
|
||||||
static void map_fast_page(paddr_t);
|
static void map_fast_page(paddr_t);
|
||||||
static void unmap_fast_page();
|
static void unmap_fast_page();
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
#include <kernel/ELF.h>
|
#include <kernel/ELF.h>
|
||||||
#include <kernel/FS/Inode.h>
|
#include <kernel/FS/Inode.h>
|
||||||
#include <kernel/Lock/Mutex.h>
|
#include <kernel/Lock/Mutex.h>
|
||||||
#include <kernel/Lock/RWLock.h>
|
|
||||||
#include <kernel/Memory/Heap.h>
|
#include <kernel/Memory/Heap.h>
|
||||||
#include <kernel/Memory/MemoryRegion.h>
|
#include <kernel/Memory/MemoryRegion.h>
|
||||||
#include <kernel/Memory/SharedMemoryObject.h>
|
#include <kernel/Memory/SharedMemoryObject.h>
|
||||||
|
|
@ -219,6 +218,8 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_tcgetpgrp(int fd);
|
BAN::ErrorOr<long> sys_tcgetpgrp(int fd);
|
||||||
BAN::ErrorOr<long> sys_tcsetpgrp(int fd, pid_t pgid);
|
BAN::ErrorOr<long> sys_tcsetpgrp(int fd, pid_t pgid);
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> sys_termid(char*);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_clock_gettime(clockid_t, timespec*);
|
BAN::ErrorOr<long> sys_clock_gettime(clockid_t, timespec*);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_load_keymap(const char* path);
|
BAN::ErrorOr<long> sys_load_keymap(const char* path);
|
||||||
|
|
@ -273,20 +274,17 @@ namespace Kernel
|
||||||
};
|
};
|
||||||
|
|
||||||
// Adds new region to the sorted array of mapped regions
|
// Adds new region to the sorted array of mapped regions
|
||||||
// You must hold writer end of m_mapped_region_lock when calling this.
|
|
||||||
BAN::ErrorOr<void> add_mapped_region(BAN::UniqPtr<MemoryRegion>&&);
|
BAN::ErrorOr<void> add_mapped_region(BAN::UniqPtr<MemoryRegion>&&);
|
||||||
// If address is contained by a region, returns the index of that.
|
// If address is contained by a region, returns the index of that.
|
||||||
// Otherwise returns the address of the first region after this address.
|
// Otherwise returns the address of the first region after this address.
|
||||||
// You must hold reader end of m_mapped_region_lock when calling this.
|
|
||||||
size_t find_mapped_region(vaddr_t) const;
|
size_t find_mapped_region(vaddr_t) const;
|
||||||
|
|
||||||
BAN::ErrorOr<VirtualFileSystem::File> find_file(int fd, const char* path, int flags) const;
|
BAN::ErrorOr<VirtualFileSystem::File> find_file(int fd, const char* path, int flags) const;
|
||||||
BAN::ErrorOr<FileParent> find_parent_file(int fd, const char* path, int flags) const;
|
BAN::ErrorOr<FileParent> find_parent_file(int fd, const char* path, int flags) const;
|
||||||
BAN::ErrorOr<VirtualFileSystem::File> find_relative_parent(int fd, const char* path) const;
|
BAN::ErrorOr<VirtualFileSystem::File> find_relative_parent(int fd, const char* path) const;
|
||||||
|
|
||||||
BAN::ErrorOr<void> read_from_user(const void* user_addr, void* out, size_t size);
|
BAN::ErrorOr<void> validate_string_access(const char*);
|
||||||
BAN::ErrorOr<void> read_string_from_user(const char* user_addr, char* out, size_t max_size);
|
BAN::ErrorOr<void> validate_pointer_access(const void*, size_t, bool needs_write);
|
||||||
BAN::ErrorOr<void> write_to_user(void* user_addr, const void* in, size_t size);
|
|
||||||
BAN::ErrorOr<MemoryRegion*> validate_and_pin_pointer_access(const void*, size_t, bool needs_write);
|
BAN::ErrorOr<MemoryRegion*> validate_and_pin_pointer_access(const void*, size_t, bool needs_write);
|
||||||
|
|
||||||
uint64_t signal_pending_mask() const
|
uint64_t signal_pending_mask() const
|
||||||
|
|
@ -331,7 +329,6 @@ namespace Kernel
|
||||||
|
|
||||||
OpenFileDescriptorSet m_open_file_descriptors;
|
OpenFileDescriptorSet m_open_file_descriptors;
|
||||||
|
|
||||||
mutable RWLock m_memory_region_lock;
|
|
||||||
BAN::Vector<BAN::UniqPtr<MemoryRegion>> m_mapped_regions;
|
BAN::Vector<BAN::UniqPtr<MemoryRegion>> m_mapped_regions;
|
||||||
|
|
||||||
pid_t m_sid;
|
pid_t m_sid;
|
||||||
|
|
@ -351,7 +348,6 @@ namespace Kernel
|
||||||
|
|
||||||
struct futex_t
|
struct futex_t
|
||||||
{
|
{
|
||||||
Mutex mutex;
|
|
||||||
ThreadBlocker blocker;
|
ThreadBlocker blocker;
|
||||||
uint32_t waiters { 0 };
|
uint32_t waiters { 0 };
|
||||||
uint32_t to_wakeup { 0 };
|
uint32_t to_wakeup { 0 };
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
uintptr_t vaddr;
|
uintptr_t vaddr;
|
||||||
size_t page_count;
|
size_t page_count;
|
||||||
void* page_table;
|
|
||||||
} flush_tlb;
|
} flush_tlb;
|
||||||
SchedulerQueue::Node* new_thread;
|
SchedulerQueue::Node* new_thread;
|
||||||
SchedulerQueue::Node* unblock_thread;
|
SchedulerQueue::Node* unblock_thread;
|
||||||
|
|
@ -209,7 +208,7 @@ namespace Kernel
|
||||||
static vaddr_t s_shared_page_vaddr;
|
static vaddr_t s_shared_page_vaddr;
|
||||||
|
|
||||||
ProcessorID m_id { 0 };
|
ProcessorID m_id { 0 };
|
||||||
uint8_t m_index { 0 };
|
uint8_t m_index { 0xFF };
|
||||||
|
|
||||||
vaddr_t m_thread_syscall_stack;
|
vaddr_t m_thread_syscall_stack;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
class MemoryBackedRegion;
|
|
||||||
class Process;
|
class Process;
|
||||||
|
|
||||||
class Thread
|
class Thread
|
||||||
|
|
@ -104,7 +103,9 @@ namespace Kernel
|
||||||
vaddr_t kernel_stack_top() const { return m_kernel_stack->vaddr() + m_kernel_stack->size(); }
|
vaddr_t kernel_stack_top() const { return m_kernel_stack->vaddr() + m_kernel_stack->size(); }
|
||||||
VirtualRange& kernel_stack() { return *m_kernel_stack; }
|
VirtualRange& kernel_stack() { return *m_kernel_stack; }
|
||||||
|
|
||||||
MemoryBackedRegion& userspace_stack() { ASSERT(is_userspace() && m_userspace_stack); return *m_userspace_stack; }
|
vaddr_t userspace_stack_bottom() const { return is_userspace() ? m_userspace_stack->vaddr() : UINTPTR_MAX; }
|
||||||
|
vaddr_t userspace_stack_top() const { return is_userspace() ? m_userspace_stack->vaddr() + m_userspace_stack->size() : 0; }
|
||||||
|
VirtualRange& userspace_stack() { ASSERT(is_userspace()); return *m_userspace_stack; }
|
||||||
|
|
||||||
static Thread& current();
|
static Thread& current();
|
||||||
static pid_t current_tid();
|
static pid_t current_tid();
|
||||||
|
|
@ -128,7 +129,7 @@ namespace Kernel
|
||||||
void set_gsbase(vaddr_t base) { m_gsbase = base; }
|
void set_gsbase(vaddr_t base) { m_gsbase = base; }
|
||||||
vaddr_t get_gsbase() const { return m_gsbase; }
|
vaddr_t get_gsbase() const { return m_gsbase; }
|
||||||
|
|
||||||
size_t virtual_page_count() const { return m_kernel_stack ? (m_kernel_stack->size() / PAGE_SIZE) : 0; }
|
size_t virtual_page_count() const { return (m_kernel_stack ? (m_kernel_stack->size() / PAGE_SIZE) : 0) + (m_userspace_stack ? (m_userspace_stack->size() / PAGE_SIZE) : 0); }
|
||||||
size_t physical_page_count() const { return virtual_page_count(); }
|
size_t physical_page_count() const { return virtual_page_count(); }
|
||||||
|
|
||||||
YieldRegisters& yield_registers() { return m_yield_registers; }
|
YieldRegisters& yield_registers() { return m_yield_registers; }
|
||||||
|
|
@ -159,7 +160,7 @@ namespace Kernel
|
||||||
BAN::UniqPtr<PageTable> m_keep_alive_page_table;
|
BAN::UniqPtr<PageTable> m_keep_alive_page_table;
|
||||||
|
|
||||||
BAN::UniqPtr<VirtualRange> m_kernel_stack;
|
BAN::UniqPtr<VirtualRange> m_kernel_stack;
|
||||||
MemoryBackedRegion* m_userspace_stack { nullptr };
|
BAN::UniqPtr<VirtualRange> m_userspace_stack;
|
||||||
const pid_t m_tid { 0 };
|
const pid_t m_tid { 0 };
|
||||||
State m_state { State::NotStarted };
|
State m_state { State::NotStarted };
|
||||||
Process* m_process { nullptr };
|
Process* m_process { nullptr };
|
||||||
|
|
|
||||||
|
|
@ -29,33 +29,28 @@ namespace Debug
|
||||||
static uint8_t s_debug_ansi_state { 0 };
|
static uint8_t s_debug_ansi_state { 0 };
|
||||||
|
|
||||||
void dump_stack_trace()
|
void dump_stack_trace()
|
||||||
{
|
|
||||||
dump_stack_trace(0, reinterpret_cast<uintptr_t>(__builtin_frame_address(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_stack_trace(uintptr_t ip, uintptr_t bp)
|
|
||||||
{
|
{
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
struct stackframe
|
struct stackframe
|
||||||
{
|
{
|
||||||
stackframe* bp;
|
stackframe* bp;
|
||||||
void* ip;
|
uintptr_t ip;
|
||||||
};
|
};
|
||||||
|
|
||||||
SpinLockGuard _(s_debug_lock);
|
SpinLockGuard _(s_debug_lock);
|
||||||
|
|
||||||
const stackframe* frame = reinterpret_cast<const stackframe*>(bp);
|
stackframe* frame = (stackframe*)__builtin_frame_address(0);
|
||||||
|
if (!frame)
|
||||||
void* first_ip = frame->ip;
|
{
|
||||||
void* last_ip = 0;
|
dprintln("Could not get frame address");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uintptr_t first_ip = frame->ip;
|
||||||
|
uintptr_t last_ip = 0;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
BAN::Formatter::print(Debug::putchar, "\e[36mStack trace:\r\n");
|
BAN::Formatter::print(Debug::putchar, "\e[36mStack trace:\r\n");
|
||||||
|
|
||||||
if (ip != 0)
|
|
||||||
BAN::Formatter::print(Debug::putchar, " {}\r\n", reinterpret_cast<void*>(ip));
|
|
||||||
|
|
||||||
while (frame)
|
while (frame)
|
||||||
{
|
{
|
||||||
if (!PageTable::is_valid_pointer((vaddr_t)frame))
|
if (!PageTable::is_valid_pointer((vaddr_t)frame))
|
||||||
|
|
|
||||||
|
|
@ -128,18 +128,16 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
auto& [inode, events] = *it;
|
auto& [inode, events] = *it;
|
||||||
|
|
||||||
#define REMOVE_IT() \
|
#define REMOVE_IT_AND_CONTINUE() \
|
||||||
({ \
|
({ \
|
||||||
m_processing_events.remove(it); \
|
m_processing_events.remove(it); \
|
||||||
if (event_count > 0) \
|
|
||||||
break; \
|
|
||||||
it = m_processing_events.begin(); \
|
it = m_processing_events.begin(); \
|
||||||
continue; \
|
continue; \
|
||||||
})
|
})
|
||||||
|
|
||||||
auto listen_it = m_listening_events.find(inode);
|
auto listen_it = m_listening_events.find(inode);
|
||||||
if (listen_it == m_listening_events.end())
|
if (listen_it == m_listening_events.end())
|
||||||
REMOVE_IT();
|
REMOVE_IT_AND_CONTINUE();
|
||||||
auto& listen = listen_it->value;
|
auto& listen = listen_it->value;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -151,7 +149,7 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events == 0)
|
if (events == 0)
|
||||||
REMOVE_IT();
|
REMOVE_IT_AND_CONTINUE();
|
||||||
|
|
||||||
{
|
{
|
||||||
LockGuard inode_locker(inode->m_mutex);
|
LockGuard inode_locker(inode->m_mutex);
|
||||||
|
|
@ -167,9 +165,9 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events == 0)
|
if (events == 0)
|
||||||
REMOVE_IT();
|
REMOVE_IT_AND_CONTINUE();
|
||||||
|
|
||||||
#undef REMOVE_IT
|
#undef REMOVE_IT_AND_CONTINUE
|
||||||
|
|
||||||
for (size_t fd = 0; fd < listen.events.size() && event_count < event_span.size(); fd++)
|
for (size_t fd = 0; fd < listen.events.size() && event_count < event_span.size(); fd++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#include <BAN/ScopeGuard.h>
|
#include <BAN/ScopeGuard.h>
|
||||||
#include <BAN/Sort.h>
|
|
||||||
#include <kernel/FS/Ext2/FileSystem.h>
|
#include <kernel/FS/Ext2/FileSystem.h>
|
||||||
#include <kernel/Lock/LockGuard.h>
|
#include <kernel/Lock/LockGuard.h>
|
||||||
|
|
||||||
|
|
@ -128,7 +127,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
auto block_buffer = TRY(m_buffer_manager.get_buffer());
|
auto block_buffer = TRY(m_buffer_manager.get_buffer());
|
||||||
|
|
||||||
if ((superblock().rev_level == Ext2::Enum::GOOD_OLD_REV) || !(m_superblock.feature_ro_compat & Ext2::Enum::FEATURE_RO_COMPAT_SPARSE_SUPER))
|
if (superblock().rev_level == Ext2::Enum::GOOD_OLD_REV)
|
||||||
{
|
{
|
||||||
// In revision 0 all blockgroups contain superblock backup
|
// In revision 0 all blockgroups contain superblock backup
|
||||||
TRY(m_superblock_backups.reserve(number_of_block_groups - 1));
|
TRY(m_superblock_backups.reserve(number_of_block_groups - 1));
|
||||||
|
|
@ -149,8 +148,6 @@ namespace Kernel
|
||||||
|
|
||||||
// We don't really care if this succeeds or not
|
// We don't really care if this succeeds or not
|
||||||
(void)m_superblock_backups.shrink_to_fit();
|
(void)m_superblock_backups.shrink_to_fit();
|
||||||
|
|
||||||
BAN::sort::sort(m_superblock_backups.begin(), m_superblock_backups.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t bg : m_superblock_backups)
|
for (uint32_t bg : m_superblock_backups)
|
||||||
|
|
@ -491,7 +488,14 @@ namespace Kernel
|
||||||
|
|
||||||
TRY(read_block(bgd_location.block, bgd_buffer));
|
TRY(read_block(bgd_location.block, bgd_buffer));
|
||||||
|
|
||||||
const auto bgd = bgd_buffer.span().slice(bgd_location.offset).as<Ext2::BlockGroupDescriptor>();
|
auto& bgd = *(Ext2::BlockGroupDescriptor*)(bgd_buffer.data() + bgd_location.offset);
|
||||||
|
|
||||||
|
const uint32_t inode_byte_offset = inode_index * superblock().inode_size;
|
||||||
|
BlockLocation location
|
||||||
|
{
|
||||||
|
.block = inode_byte_offset / block_size + bgd.inode_table,
|
||||||
|
.offset = inode_byte_offset % block_size
|
||||||
|
};
|
||||||
|
|
||||||
#if EXT2_VERIFY_INODE
|
#if EXT2_VERIFY_INODE
|
||||||
const uint32_t inode_bitmap_block = bgd.inode_bitmap;
|
const uint32_t inode_bitmap_block = bgd.inode_bitmap;
|
||||||
|
|
@ -499,18 +503,14 @@ namespace Kernel
|
||||||
// NOTE: we can reuse the bgd_buffer since it is not needed anymore
|
// NOTE: we can reuse the bgd_buffer since it is not needed anymore
|
||||||
auto& inode_bitmap = bgd_buffer;
|
auto& inode_bitmap = bgd_buffer;
|
||||||
|
|
||||||
TRY(read_block(inode_bitmap_block, inode_bitmap));
|
read_block(inode_bitmap_block, inode_bitmap.span());
|
||||||
|
|
||||||
const uint32_t byte = inode_index / 8;
|
const uint32_t byte = inode_index / 8;
|
||||||
const uint32_t bit = inode_index % 8;
|
const uint32_t bit = inode_index % 8;
|
||||||
ASSERT(inode_bitmap[byte] & (1 << bit));
|
ASSERT(inode_bitmap[byte] & (1 << bit));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const uint32_t inode_byte_offset = inode_index * superblock().inode_size;
|
return location;
|
||||||
return BlockLocation {
|
|
||||||
.block = inode_byte_offset / block_size + bgd.inode_table,
|
|
||||||
.offset = inode_byte_offset % block_size
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ext2FS::BlockLocation Ext2FS::locate_block_group_descriptior(uint32_t group_index)
|
Ext2FS::BlockLocation Ext2FS::locate_block_group_descriptior(uint32_t group_index)
|
||||||
|
|
@ -525,7 +525,8 @@ namespace Kernel
|
||||||
// Block Group Descriptor table is in the block after superblock
|
// Block Group Descriptor table is in the block after superblock
|
||||||
const uint32_t bgd_byte_offset = (superblock().first_data_block + 1) * block_size + sizeof(Ext2::BlockGroupDescriptor) * group_index;
|
const uint32_t bgd_byte_offset = (superblock().first_data_block + 1) * block_size + sizeof(Ext2::BlockGroupDescriptor) * group_index;
|
||||||
|
|
||||||
return BlockLocation {
|
return
|
||||||
|
{
|
||||||
.block = bgd_byte_offset / block_size,
|
.block = bgd_byte_offset / block_size,
|
||||||
.offset = bgd_byte_offset % block_size
|
.offset = bgd_byte_offset % block_size
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -61,13 +61,13 @@ namespace Kernel
|
||||||
const uint32_t inode_blocks_per_fs_block = blksize() / 512;
|
const uint32_t inode_blocks_per_fs_block = blksize() / 512;
|
||||||
const uint32_t indices_per_fs_block = blksize() / sizeof(uint32_t);
|
const uint32_t indices_per_fs_block = blksize() / sizeof(uint32_t);
|
||||||
|
|
||||||
if (block == 0 && !allocate)
|
|
||||||
return BAN::Optional<uint32_t>();
|
|
||||||
|
|
||||||
if (depth == 0)
|
if (depth == 0)
|
||||||
{
|
{
|
||||||
if (block == 0)
|
if (block == 0)
|
||||||
{
|
{
|
||||||
|
if (!allocate)
|
||||||
|
return BAN::Optional<uint32_t>();
|
||||||
|
|
||||||
block = TRY(m_fs.reserve_free_block(block_group()));
|
block = TRY(m_fs.reserve_free_block(block_group()));
|
||||||
m_inode.blocks += inode_blocks_per_fs_block;
|
m_inode.blocks += inode_blocks_per_fs_block;
|
||||||
|
|
||||||
|
|
@ -87,6 +87,9 @@ namespace Kernel
|
||||||
TRY(m_fs.read_block(block, block_buffer));
|
TRY(m_fs.read_block(block, block_buffer));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!allocate)
|
||||||
|
return BAN::Optional<uint32_t>();
|
||||||
|
|
||||||
block = TRY(m_fs.reserve_free_block(block_group()));
|
block = TRY(m_fs.reserve_free_block(block_group()));
|
||||||
m_inode.blocks += inode_blocks_per_fs_block;
|
m_inode.blocks += inode_blocks_per_fs_block;
|
||||||
|
|
||||||
|
|
@ -168,10 +171,8 @@ namespace Kernel
|
||||||
BAN::ErrorOr<void> Ext2Inode::set_link_target_impl(BAN::StringView target)
|
BAN::ErrorOr<void> Ext2Inode::set_link_target_impl(BAN::StringView target)
|
||||||
{
|
{
|
||||||
ASSERT(mode().iflnk());
|
ASSERT(mode().iflnk());
|
||||||
if (target.size() < sizeof(m_inode.block))
|
if (m_inode.size < sizeof(m_inode.block) && target.size() < sizeof(m_inode.block))
|
||||||
{
|
{
|
||||||
if (m_inode.size >= sizeof(m_inode.block))
|
|
||||||
TRY(cleanup_data_blocks());
|
|
||||||
memset(m_inode.block, 0, sizeof(m_inode.block));
|
memset(m_inode.block, 0, sizeof(m_inode.block));
|
||||||
memcpy(m_inode.block, target.data(), target.size());
|
memcpy(m_inode.block, target.data(), target.size());
|
||||||
m_inode.size = target.size();
|
m_inode.size = target.size();
|
||||||
|
|
@ -411,8 +412,10 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Ext2Inode::cleanup_data_blocks()
|
BAN::ErrorOr<void> Ext2Inode::cleanup_from_fs()
|
||||||
{
|
{
|
||||||
|
ASSERT(m_inode.links_count == 0);
|
||||||
|
|
||||||
if (mode().iflnk() && (size_t)size() < sizeof(m_inode.block))
|
if (mode().iflnk() && (size_t)size() < sizeof(m_inode.block))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|
@ -433,16 +436,12 @@ done:
|
||||||
// mark blocks as deleted
|
// mark blocks as deleted
|
||||||
memset(m_inode.block, 0x00, sizeof(m_inode.block));
|
memset(m_inode.block, 0x00, sizeof(m_inode.block));
|
||||||
|
|
||||||
|
// FIXME: this is only required since fs does not get
|
||||||
|
// deleting inode from its cache
|
||||||
TRY(sync());
|
TRY(sync());
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::ErrorOr<void> Ext2Inode::cleanup_from_fs()
|
|
||||||
{
|
|
||||||
ASSERT(m_inode.links_count == 0);
|
|
||||||
TRY(cleanup_data_blocks());
|
|
||||||
TRY(m_fs.delete_inode(ino()));
|
TRY(m_fs.delete_inode(ino()));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -277,11 +277,7 @@ namespace Kernel
|
||||||
#endif
|
#endif
|
||||||
if (isr == ISR::PageFault)
|
if (isr == ISR::PageFault)
|
||||||
PageTable::current().debug_dump();
|
PageTable::current().debug_dump();
|
||||||
#if ARCH(x86_64)
|
Debug::dump_stack_trace();
|
||||||
Debug::dump_stack_trace(interrupt_stack->ip, regs->rbp);
|
|
||||||
#elif ARCH(i686)
|
|
||||||
Debug::dump_stack_trace(interrupt_stack->ip, regs->ebp);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Debug::s_debug_lock.unlock(InterruptState::Disabled);
|
Debug::s_debug_lock.unlock(InterruptState::Disabled);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,12 +148,12 @@ namespace Kernel
|
||||||
if (m_preallocated)
|
if (m_preallocated)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SpinLockGuard _(m_lock);
|
|
||||||
|
|
||||||
const size_t index = (vaddr - this->vaddr()) / PAGE_SIZE;
|
const size_t index = (vaddr - this->vaddr()) / PAGE_SIZE;
|
||||||
if (m_paddrs[index])
|
if (m_paddrs[index])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
SpinLockGuard _(m_lock);
|
||||||
|
|
||||||
m_paddrs[index] = Heap::get().take_free_page();
|
m_paddrs[index] = Heap::get().take_free_page();
|
||||||
if (m_paddrs[index] == 0)
|
if (m_paddrs[index] == 0)
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -60,13 +60,8 @@ namespace Kernel
|
||||||
Kernel::panic("Trying to initialize invalid processor {}", id.m_id);
|
Kernel::panic("Trying to initialize invalid processor {}", id.m_id);
|
||||||
|
|
||||||
if (id == s_bsp_id)
|
if (id == s_bsp_id)
|
||||||
{
|
|
||||||
for (auto& processor : s_processors)
|
for (auto& processor : s_processors)
|
||||||
{
|
|
||||||
processor.m_id = PROCESSOR_NONE;
|
processor.m_id = PROCESSOR_NONE;
|
||||||
processor.m_index = 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& processor = s_processors[id.m_id];
|
auto& processor = s_processors[id.m_id];
|
||||||
|
|
||||||
|
|
@ -375,8 +370,6 @@ namespace Kernel
|
||||||
switch (message->type)
|
switch (message->type)
|
||||||
{
|
{
|
||||||
case SMPMessage::Type::FlushTLB:
|
case SMPMessage::Type::FlushTLB:
|
||||||
if (message->flush_tlb.page_table && message->flush_tlb.page_table != processor.m_current_page_table)
|
|
||||||
break;
|
|
||||||
for (size_t i = 0; i < message->flush_tlb.page_count; i++)
|
for (size_t i = 0; i < message->flush_tlb.page_count; i++)
|
||||||
asm volatile("invlpg (%0)" :: "r"(message->flush_tlb.vaddr + i * PAGE_SIZE) : "memory");
|
asm volatile("invlpg (%0)" :: "r"(message->flush_tlb.vaddr + i * PAGE_SIZE) : "memory");
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -256,16 +256,16 @@ namespace Kernel
|
||||||
fis_command.fis_type = FIS_TYPE_REGISTER_H2D;
|
fis_command.fis_type = FIS_TYPE_REGISTER_H2D;
|
||||||
fis_command.c = 1;
|
fis_command.c = 1;
|
||||||
|
|
||||||
const bool needs_extended = lba >= (1 << 24) || sector_count > 0xFF;
|
bool need_extended = lba >= (1 << 28) || sector_count > 0xFF;
|
||||||
ASSERT (!needs_extended || (m_command_set & ATA_COMMANDSET_LBA48_SUPPORTED));
|
ASSERT (!need_extended || (m_command_set & ATA_COMMANDSET_LBA48_SUPPORTED));
|
||||||
|
|
||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case Command::Read:
|
case Command::Read:
|
||||||
fis_command.command = needs_extended ? ATA_COMMAND_READ_DMA_EXT : ATA_COMMAND_READ_DMA;
|
fis_command.command = need_extended ? ATA_COMMAND_READ_DMA_EXT : ATA_COMMAND_READ_DMA;
|
||||||
break;
|
break;
|
||||||
case Command::Write:
|
case Command::Write:
|
||||||
fis_command.command = needs_extended ? ATA_COMMAND_WRITE_DMA_EXT : ATA_COMMAND_WRITE_DMA;
|
fis_command.command = need_extended ? ATA_COMMAND_WRITE_DMA_EXT : ATA_COMMAND_WRITE_DMA;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
#include <kernel/InterruptController.h>
|
#include <kernel/InterruptController.h>
|
||||||
#include <kernel/InterruptStack.h>
|
#include <kernel/InterruptStack.h>
|
||||||
#include <kernel/Memory/kmalloc.h>
|
#include <kernel/Memory/kmalloc.h>
|
||||||
#include <kernel/Memory/MemoryBackedRegion.h>
|
|
||||||
#include <kernel/Process.h>
|
#include <kernel/Process.h>
|
||||||
#include <kernel/Scheduler.h>
|
#include <kernel/Scheduler.h>
|
||||||
#include <kernel/Thread.h>
|
#include <kernel/Thread.h>
|
||||||
|
|
@ -219,16 +218,13 @@ namespace Kernel
|
||||||
true, true
|
true, true
|
||||||
));
|
));
|
||||||
|
|
||||||
auto userspace_stack = TRY(MemoryBackedRegion::create(
|
thread->m_userspace_stack = TRY(VirtualRange::create_to_vaddr_range(
|
||||||
page_table,
|
page_table,
|
||||||
|
stack_addr_start, USERSPACE_END,
|
||||||
userspace_stack_size,
|
userspace_stack_size,
|
||||||
{ stack_addr_start, USERSPACE_END },
|
|
||||||
MemoryRegion::Type::PRIVATE,
|
|
||||||
PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present,
|
||||||
O_RDWR
|
false, true
|
||||||
));
|
));
|
||||||
thread->m_userspace_stack = userspace_stack.ptr();
|
|
||||||
TRY(process->add_mapped_region(BAN::move(userspace_stack)));
|
|
||||||
|
|
||||||
thread_deleter.disable();
|
thread_deleter.disable();
|
||||||
|
|
||||||
|
|
@ -323,18 +319,16 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
auto* thread = TRY(create_userspace(m_process, m_process->page_table()));
|
auto* thread = TRY(create_userspace(m_process, m_process->page_table()));
|
||||||
|
|
||||||
if (Processor::get_current_sse_thread() == this)
|
save_sse();
|
||||||
save_sse();
|
|
||||||
memcpy(thread->m_sse_storage, m_sse_storage, sizeof(m_sse_storage));
|
memcpy(thread->m_sse_storage, m_sse_storage, sizeof(m_sse_storage));
|
||||||
|
|
||||||
TRY(thread->userspace_stack().copy_data_to_region(
|
TRY(thread->userspace_stack().allocate_page_for_demand_paging(thread->userspace_stack_top() - PAGE_SIZE));
|
||||||
thread->m_userspace_stack->size() - sizeof(void*),
|
PageTable::with_fast_page(thread->userspace_stack().paddr_of(thread->userspace_stack_top() - PAGE_SIZE), [=] {
|
||||||
reinterpret_cast<const uint8_t*>(&arg),
|
PageTable::fast_page_as<void*>(PAGE_SIZE - sizeof(uintptr_t)) = arg;
|
||||||
sizeof(void*)
|
});
|
||||||
));
|
|
||||||
|
|
||||||
const vaddr_t entry_addr = reinterpret_cast<vaddr_t>(entry);
|
const vaddr_t entry_addr = reinterpret_cast<vaddr_t>(entry);
|
||||||
thread->setup_exec(entry_addr, thread->userspace_stack().vaddr() + thread->userspace_stack().size() - sizeof(void*));
|
thread->setup_exec(entry_addr, thread->userspace_stack_top() - sizeof(uintptr_t));
|
||||||
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
@ -352,18 +346,14 @@ namespace Kernel
|
||||||
thread->m_is_userspace = true;
|
thread->m_is_userspace = true;
|
||||||
|
|
||||||
thread->m_kernel_stack = TRY(m_kernel_stack->clone(new_process->page_table()));
|
thread->m_kernel_stack = TRY(m_kernel_stack->clone(new_process->page_table()));
|
||||||
|
thread->m_userspace_stack = TRY(m_userspace_stack->clone(new_process->page_table()));
|
||||||
const auto stack_index = new_process->find_mapped_region(m_userspace_stack->vaddr());
|
|
||||||
thread->m_userspace_stack = static_cast<MemoryBackedRegion*>(new_process->m_mapped_regions[stack_index].ptr());
|
|
||||||
ASSERT(thread->m_userspace_stack->vaddr() == m_userspace_stack->vaddr());
|
|
||||||
|
|
||||||
thread->m_fsbase = m_fsbase;
|
thread->m_fsbase = m_fsbase;
|
||||||
thread->m_gsbase = m_gsbase;
|
thread->m_gsbase = m_gsbase;
|
||||||
|
|
||||||
thread->m_state = State::NotStarted;
|
thread->m_state = State::NotStarted;
|
||||||
|
|
||||||
if (Processor::get_current_sse_thread() == this)
|
save_sse();
|
||||||
save_sse();
|
|
||||||
memcpy(thread->m_sse_storage, m_sse_storage, sizeof(m_sse_storage));
|
memcpy(thread->m_sse_storage, m_sse_storage, sizeof(m_sse_storage));
|
||||||
|
|
||||||
thread->m_yield_registers = {};
|
thread->m_yield_registers = {};
|
||||||
|
|
@ -407,18 +397,29 @@ namespace Kernel
|
||||||
if (needed_size > m_userspace_stack->size())
|
if (needed_size > m_userspace_stack->size())
|
||||||
return BAN::Error::from_errno(ENOBUFS);
|
return BAN::Error::from_errno(ENOBUFS);
|
||||||
|
|
||||||
vaddr_t vaddr = userspace_stack().vaddr() + userspace_stack().size() - needed_size;
|
vaddr_t vaddr = userspace_stack_top() - needed_size;
|
||||||
|
|
||||||
const size_t page_count = BAN::Math::div_round_up<size_t>(needed_size, PAGE_SIZE);
|
const size_t page_count = BAN::Math::div_round_up<size_t>(needed_size, PAGE_SIZE);
|
||||||
for (size_t i = 0; i < page_count; i++)
|
for (size_t i = 0; i < page_count; i++)
|
||||||
TRY(m_userspace_stack->allocate_page_containing(vaddr + i * PAGE_SIZE, true));
|
TRY(m_userspace_stack->allocate_page_for_demand_paging(vaddr + i * PAGE_SIZE));
|
||||||
|
|
||||||
const auto stack_copy_buf =
|
const auto stack_copy_buf =
|
||||||
[this](BAN::ConstByteSpan buffer, vaddr_t vaddr) -> void
|
[this](BAN::ConstByteSpan buffer, vaddr_t vaddr) -> void
|
||||||
{
|
{
|
||||||
ASSERT(vaddr >= m_userspace_stack->vaddr());
|
ASSERT(vaddr + buffer.size() <= userspace_stack_top());
|
||||||
ASSERT(vaddr + buffer.size() <= m_userspace_stack->vaddr() + m_userspace_stack->size());
|
|
||||||
MUST(m_userspace_stack->copy_data_to_region(vaddr - m_userspace_stack->vaddr(), buffer.data(), buffer.size()));
|
size_t bytes_copied = 0;
|
||||||
|
while (bytes_copied < buffer.size())
|
||||||
|
{
|
||||||
|
const size_t to_copy = BAN::Math::min<size_t>(buffer.size() - bytes_copied, PAGE_SIZE - (vaddr % PAGE_SIZE));
|
||||||
|
|
||||||
|
PageTable::with_fast_page(userspace_stack().paddr_of(vaddr & PAGE_ADDR_MASK), [=]() {
|
||||||
|
memcpy(PageTable::fast_page_as_ptr(vaddr % PAGE_SIZE), buffer.data() + bytes_copied, to_copy);
|
||||||
|
});
|
||||||
|
|
||||||
|
vaddr += to_copy;
|
||||||
|
bytes_copied += to_copy;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto stack_push_buf =
|
const auto stack_push_buf =
|
||||||
|
|
@ -470,7 +471,7 @@ namespace Kernel
|
||||||
stack_push_str(envp[i]);
|
stack_push_str(envp[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_exec(entry, m_userspace_stack->vaddr() + m_userspace_stack->size() - needed_size);
|
setup_exec(entry, userspace_stack_top() - needed_size);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
From 49d1ca61e6249c3bc3284a6b55578b4ddd7b13ac Mon Sep 17 00:00:00 2001
|
From 2b3a0198640c23a7f8f8247ed1edae309c11e15f Mon Sep 17 00:00:00 2001
|
||||||
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
|
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
|
||||||
Date: Tue, 13 Jan 2026 20:49:19 +0200
|
Date: Thu, 31 Jul 2025 22:15:43 +0300
|
||||||
Subject: [PATCH] add support for banan-os
|
Subject: [PATCH 1/2] add support for banan-os
|
||||||
|
|
||||||
---
|
---
|
||||||
engine/common/net_http.c | 4 +++-
|
engine/common/net_http.c | 4 +++-
|
||||||
engine/common/net_ws.c | 6 ++++++
|
engine/common/net_ws.c | 17 +++++++++++++++++
|
||||||
engine/common/whereami.c | 2 +-
|
engine/common/whereami.c | 16 ++++++++++++++++
|
||||||
engine/platform/posix/net.h | 4 ++++
|
engine/platform/posix/lib_posix.c | 2 ++
|
||||||
public/build.c | 2 ++
|
public/build.c | 2 ++
|
||||||
public/build.h | 3 +++
|
public/build.h | 3 +++
|
||||||
public/buildenums.h | 3 +++
|
public/buildenums.h | 3 +++
|
||||||
7 files changed, 22 insertions(+), 2 deletions(-)
|
7 files changed, 46 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
diff --git a/engine/common/net_http.c b/engine/common/net_http.c
|
diff --git a/engine/common/net_http.c b/engine/common/net_http.c
|
||||||
index ff6fd41b..ebb5bbad 100644
|
index ff6fd41b..ebb5bbad 100644
|
||||||
|
|
@ -36,10 +36,23 @@ index ff6fd41b..ebb5bbad 100644
|
||||||
res = fcntl( file->socket, F_GETFL, 0 );
|
res = fcntl( file->socket, F_GETFL, 0 );
|
||||||
|
|
||||||
diff --git a/engine/common/net_ws.c b/engine/common/net_ws.c
|
diff --git a/engine/common/net_ws.c b/engine/common/net_ws.c
|
||||||
index 7ee4cba0..b44d5cf1 100644
|
index 7ee4cba0..e93a2410 100644
|
||||||
--- a/engine/common/net_ws.c
|
--- a/engine/common/net_ws.c
|
||||||
+++ b/engine/common/net_ws.c
|
+++ b/engine/common/net_ws.c
|
||||||
@@ -1617,7 +1617,11 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
@@ -1364,7 +1364,12 @@ static qboolean NET_QueuePacket( netsrc_t sock, netadr_t *from, byte *data, size
|
||||||
|
byte buf[NET_MAX_FRAGMENT];
|
||||||
|
int ret, protocol;
|
||||||
|
int net_socket;
|
||||||
|
+#ifdef XASH_BANAN_OS
|
||||||
|
+ socklen_t addr_len;
|
||||||
|
+#else
|
||||||
|
WSAsize_t addr_len;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
struct sockaddr_storage addr = { 0 };
|
||||||
|
|
||||||
|
*length = 0;
|
||||||
|
@@ -1617,7 +1622,11 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||||
if( family == AF_INET6 )
|
if( family == AF_INET6 )
|
||||||
pfamily = PF_INET6;
|
pfamily = PF_INET6;
|
||||||
|
|
||||||
|
|
@ -51,7 +64,7 @@ index 7ee4cba0..b44d5cf1 100644
|
||||||
{
|
{
|
||||||
err = WSAGetLastError();
|
err = WSAGetLastError();
|
||||||
if( err != WSAEAFNOSUPPORT )
|
if( err != WSAEAFNOSUPPORT )
|
||||||
@@ -1625,6 +1629,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
@@ -1625,6 +1634,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,7 +72,7 @@ index 7ee4cba0..b44d5cf1 100644
|
||||||
if( NET_IsSocketError( ioctlsocket( net_socket, FIONBIO, (void*)&_true )))
|
if( NET_IsSocketError( ioctlsocket( net_socket, FIONBIO, (void*)&_true )))
|
||||||
{
|
{
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
@@ -1634,6 +1639,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
@@ -1634,6 +1644,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||||
timeout.tv_sec = timeout.tv_usec = 0;
|
timeout.tv_sec = timeout.tv_usec = 0;
|
||||||
setsockopt( net_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
|
setsockopt( net_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
|
||||||
}
|
}
|
||||||
|
|
@ -67,34 +80,81 @@ index 7ee4cba0..b44d5cf1 100644
|
||||||
|
|
||||||
// make it broadcast capable
|
// make it broadcast capable
|
||||||
if( NET_IsSocketError( setsockopt( net_socket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof( _true ))))
|
if( NET_IsSocketError( setsockopt( net_socket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof( _true ))))
|
||||||
|
@@ -1686,6 +1697,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||||
|
optval = 0x10; // IPTOS_LOWDELAY
|
||||||
|
Con_Printf( "Enabling LOWDELAY TOS option\n" );
|
||||||
|
|
||||||
|
+#ifdef IP_TOS
|
||||||
|
if( NET_IsSocketError( setsockopt( net_socket, IPPROTO_IP, IP_TOS, (const char *)&optval, sizeof( optval ))))
|
||||||
|
{
|
||||||
|
err = WSAGetLastError();
|
||||||
|
@@ -1694,6 +1706,7 @@ static int NET_IPSocket( const char *net_iface, int port, int family )
|
||||||
|
closesocket( net_socket );
|
||||||
|
return INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Sys_CheckParm( "-loopback" ))
|
||||||
|
@@ -1801,7 +1814,11 @@ static void NET_DetermineLocalAddress( void )
|
||||||
|
char hostname[512];
|
||||||
|
char buff[512];
|
||||||
|
struct sockaddr_storage address;
|
||||||
|
+#ifdef XASH_BANAN_OS
|
||||||
|
+ socklen_t namelen;
|
||||||
|
+#else
|
||||||
|
WSAsize_t namelen;
|
||||||
|
+#endif
|
||||||
|
const char *net_addr_string;
|
||||||
|
|
||||||
|
memset( &net_local, 0, sizeof( netadr_t ));
|
||||||
diff --git a/engine/common/whereami.c b/engine/common/whereami.c
|
diff --git a/engine/common/whereami.c b/engine/common/whereami.c
|
||||||
index 31726774..69a6cb9f 100644
|
index 31726774..5b7ff504 100644
|
||||||
--- a/engine/common/whereami.c
|
--- a/engine/common/whereami.c
|
||||||
+++ b/engine/common/whereami.c
|
+++ b/engine/common/whereami.c
|
||||||
@@ -175,7 +175,7 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
|
@@ -851,6 +851,22 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
|
||||||
return length;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
-#elif defined(__linux__) || defined(__CYGWIN__) || defined(__sun) || defined(__serenity__) || defined(WAI_USE_PROC_SELF_EXE)
|
+#elif defined(__banan_os__)
|
||||||
+#elif defined(__linux__) || defined(__CYGWIN__) || defined(__sun) || defined(__serenity__) || defined(__banan_os__) || defined(WAI_USE_PROC_SELF_EXE)
|
+
|
||||||
|
+/* Not possible on this platform */
|
||||||
|
+
|
||||||
|
+WAI_FUNCSPEC
|
||||||
|
+int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
|
||||||
|
+{
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+WAI_FUNCSPEC
|
||||||
|
+int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
|
||||||
|
+{
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#else
|
||||||
|
|
||||||
#include <stdio.h>
|
#error unsupported platform
|
||||||
#include <stdlib.h>
|
diff --git a/engine/platform/posix/lib_posix.c b/engine/platform/posix/lib_posix.c
|
||||||
diff --git a/engine/platform/posix/net.h b/engine/platform/posix/net.h
|
index 23d1c3b1..a5a84fe1 100644
|
||||||
index 58532927..6ab3cd1f 100644
|
--- a/engine/platform/posix/lib_posix.c
|
||||||
--- a/engine/platform/posix/net.h
|
+++ b/engine/platform/posix/lib_posix.c
|
||||||
+++ b/engine/platform/posix/net.h
|
@@ -208,6 +208,7 @@ const char *COM_NameForFunction( void *hInstance, void *function )
|
||||||
@@ -90,6 +90,10 @@ static int ioctl_stub( int d, unsigned long r, ... )
|
return Loader_GetFuncName_int(wm, function);
|
||||||
#define closesocket close
|
else
|
||||||
#endif
|
#endif
|
||||||
#define SOCKET int
|
+#ifndef XASH_BANAN_OS
|
||||||
+#if XASH_BANAN_OS
|
// NOTE: dladdr() is a glibc extension
|
||||||
+typedef socklen_t WSAsize_t;
|
{
|
||||||
+#else
|
Dl_info info = {0};
|
||||||
typedef int WSAsize_t;
|
@@ -215,6 +216,7 @@ const char *COM_NameForFunction( void *hInstance, void *function )
|
||||||
|
if( ret && info.dli_sname )
|
||||||
|
return COM_GetPlatformNeutralName( info.dli_sname );
|
||||||
|
}
|
||||||
+#endif
|
+#endif
|
||||||
|
#ifdef XASH_ALLOW_SAVERESTORE_OFFSETS
|
||||||
#endif // NET_H
|
return COM_OffsetNameForFunction( function );
|
||||||
|
#else
|
||||||
diff --git a/public/build.c b/public/build.c
|
diff --git a/public/build.c b/public/build.c
|
||||||
index 6c85bbaf..460b4040 100644
|
index 6c85bbaf..460b4040 100644
|
||||||
--- a/public/build.c
|
--- a/public/build.c
|
||||||
|
|
@ -151,5 +211,5 @@ index 4dc327d3..57585f73 100644
|
||||||
#error
|
#error
|
||||||
#endif
|
#endif
|
||||||
--
|
--
|
||||||
2.52.0
|
2.50.1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
From b8c6ea53b4a8119f299fb6b5e4684c30795037a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
|
||||||
|
Date: Thu, 31 Jul 2025 22:36:28 +0300
|
||||||
|
Subject: [PATCH] Don't export have libbacktrace
|
||||||
|
|
||||||
|
This doesnt work :)
|
||||||
|
---
|
||||||
|
3rdparty/libbacktrace/wscript | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/3rdparty/libbacktrace/wscript b/3rdparty/libbacktrace/wscript
|
||||||
|
index 2e076a56..98aca8d5 100644
|
||||||
|
--- a/3rdparty/libbacktrace/wscript
|
||||||
|
+++ b/3rdparty/libbacktrace/wscript
|
||||||
|
@@ -180,7 +180,6 @@ def build(bld):
|
||||||
|
features = 'frandomseed' if bld.env.HAVE_FRANDOM_SEED else '',
|
||||||
|
use = 'EXTRAFLAGS lzma z zstd',
|
||||||
|
includes = '. libbacktrace/',
|
||||||
|
- export_defines = 'HAVE_LIBBACKTRACE=1',
|
||||||
|
export_includes = 'libbacktrace/'
|
||||||
|
)
|
||||||
|
|
||||||
|
--
|
||||||
|
2.50.1
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
From 1e1fb9caff45f0cb05e89bfe452a7ff2abb558ff Mon Sep 17 00:00:00 2001
|
||||||
|
From: Oskari Alaranta <oskari.alaranta@bananymous.com>
|
||||||
|
Date: Thu, 31 Jul 2025 22:17:48 +0300
|
||||||
|
Subject: [PATCH] include alloca on banan-os
|
||||||
|
|
||||||
|
This detection does not work :(
|
||||||
|
---
|
||||||
|
lib/os.h | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/os.h b/lib/os.h
|
||||||
|
index 9ded7358..66b56704 100644
|
||||||
|
--- a/lib/os.h
|
||||||
|
+++ b/lib/os.h
|
||||||
|
@@ -62,7 +62,7 @@ void *_alloca(size_t size);
|
||||||
|
|
||||||
|
#endif /* _V_IFDEFJAIL_H_ */
|
||||||
|
|
||||||
|
-#ifdef HAVE_ALLOCA_H
|
||||||
|
+#if defined(HAVE_ALLOCA_H) || defined(__banan_os__)
|
||||||
|
# include <alloca.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
--
|
||||||
|
2.50.1
|
||||||
|
|
||||||
|
|
@ -9,6 +9,7 @@ __BEGIN_DECLS
|
||||||
O(SYS_EXIT, exit) \
|
O(SYS_EXIT, exit) \
|
||||||
O(SYS_READ, read) \
|
O(SYS_READ, read) \
|
||||||
O(SYS_WRITE, write) \
|
O(SYS_WRITE, write) \
|
||||||
|
O(SYS_TERMID, termid) \
|
||||||
O(SYS_CLOSE, close) \
|
O(SYS_CLOSE, close) \
|
||||||
O(SYS_OPENAT, openat) \
|
O(SYS_OPENAT, openat) \
|
||||||
O(SYS_SEEK, seek) \
|
O(SYS_SEEK, seek) \
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ char* ctermid(char* buffer)
|
||||||
{
|
{
|
||||||
static char s_buffer[L_ctermid];
|
static char s_buffer[L_ctermid];
|
||||||
char* target = buffer ? buffer : s_buffer;
|
char* target = buffer ? buffer : s_buffer;
|
||||||
strcpy(buffer, "/dev/tty");
|
syscall(SYS_TERMID, target);
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ int clock_gettime(clockid_t clock_id, struct timespec* tp)
|
||||||
if (clock_id == CLOCK_REALTIME)
|
if (clock_id == CLOCK_REALTIME)
|
||||||
tp->tv_sec += sgettime.realtime_seconds;
|
tp->tv_sec += sgettime.realtime_seconds;
|
||||||
|
|
||||||
return 0;
|
return monotonic_ns;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/banan-os.h>
|
#include <sys/banan-os.h>
|
||||||
#include <sys/epoll.h>
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -67,18 +67,6 @@ namespace LibGUI
|
||||||
return BAN::Error::from_errno(errno);
|
return BAN::Error::from_errno(errno);
|
||||||
BAN::ScopeGuard server_closer([server_fd] { close(server_fd); });
|
BAN::ScopeGuard server_closer([server_fd] { close(server_fd); });
|
||||||
|
|
||||||
int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
|
|
||||||
if (epoll_fd == -1)
|
|
||||||
return BAN::Error::from_errno(errno);
|
|
||||||
BAN::ScopeGuard epoll_closer([epoll_fd] { close(epoll_fd); });
|
|
||||||
|
|
||||||
epoll_event epoll_event {
|
|
||||||
.events = EPOLLIN,
|
|
||||||
.data = { .fd = server_fd },
|
|
||||||
};
|
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &epoll_event) == -1)
|
|
||||||
return BAN::Error::from_errno(errno);
|
|
||||||
|
|
||||||
if (fcntl(server_fd, F_SETFD, fcntl(server_fd, F_GETFD) | FD_CLOEXEC) == -1)
|
if (fcntl(server_fd, F_SETFD, fcntl(server_fd, F_GETFD) | FD_CLOEXEC) == -1)
|
||||||
return BAN::Error::from_errno(errno);
|
return BAN::Error::from_errno(errno);
|
||||||
|
|
||||||
|
|
@ -112,7 +100,7 @@ namespace LibGUI
|
||||||
TRY(create_packet.title.append(title));
|
TRY(create_packet.title.append(title));
|
||||||
TRY(create_packet.send_serialized(server_fd));
|
TRY(create_packet.send_serialized(server_fd));
|
||||||
|
|
||||||
auto window = TRY(BAN::UniqPtr<Window>::create(server_fd, epoll_fd, attributes));
|
auto window = TRY(BAN::UniqPtr<Window>::create(server_fd, attributes));
|
||||||
|
|
||||||
bool resized = false;
|
bool resized = false;
|
||||||
window->set_resize_window_event_callback([&]() { resized = true; });
|
window->set_resize_window_event_callback([&]() { resized = true; });
|
||||||
|
|
@ -121,7 +109,6 @@ namespace LibGUI
|
||||||
window->set_resize_window_event_callback({});
|
window->set_resize_window_event_callback({});
|
||||||
|
|
||||||
server_closer.disable();
|
server_closer.disable();
|
||||||
epoll_closer.disable();
|
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
@ -274,7 +261,6 @@ namespace LibGUI
|
||||||
{
|
{
|
||||||
munmap(m_framebuffer_smo, m_width * m_height * 4);
|
munmap(m_framebuffer_smo, m_width * m_height * 4);
|
||||||
close(m_server_fd);
|
close(m_server_fd);
|
||||||
close(m_epoll_fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Window::handle_resize_event(const EventPacket::ResizeWindowEvent& event)
|
BAN::ErrorOr<void> Window::handle_resize_event(const EventPacket::ResizeWindowEvent& event)
|
||||||
|
|
@ -303,8 +289,10 @@ namespace LibGUI
|
||||||
|
|
||||||
void Window::wait_events()
|
void Window::wait_events()
|
||||||
{
|
{
|
||||||
epoll_event dummy;
|
fd_set fds;
|
||||||
epoll_wait(m_epoll_fd, &dummy, 1, -1);
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(m_server_fd, &fds);
|
||||||
|
select(m_server_fd + 1, &fds, nullptr, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::poll_events()
|
void Window::poll_events()
|
||||||
|
|
@ -312,8 +300,13 @@ namespace LibGUI
|
||||||
#define TRY_OR_BREAK(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) break; e.release_value(); })
|
#define TRY_OR_BREAK(...) ({ auto&& e = (__VA_ARGS__); if (e.is_error()) break; e.release_value(); })
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
epoll_event event;
|
fd_set fds;
|
||||||
if (epoll_wait(m_epoll_fd, &event, 1, 0) == 0)
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(m_server_fd, &fds);
|
||||||
|
timeval timeout { .tv_sec = 0, .tv_usec = 0 };
|
||||||
|
select(m_server_fd + 1, &fds, nullptr, nullptr, &timeout);
|
||||||
|
|
||||||
|
if (!FD_ISSET(m_server_fd, &fds))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
auto packet_or_error = recv_packet(m_server_fd);
|
auto packet_or_error = recv_packet(m_server_fd);
|
||||||
|
|
|
||||||
|
|
@ -81,9 +81,8 @@ namespace LibGUI
|
||||||
int server_fd() const { return m_server_fd; }
|
int server_fd() const { return m_server_fd; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Window(int server_fd, int epoll_fd, Attributes attributes)
|
Window(int server_fd, Attributes attributes)
|
||||||
: m_server_fd(server_fd)
|
: m_server_fd(server_fd)
|
||||||
, m_epoll_fd(epoll_fd)
|
|
||||||
, m_attributes(attributes)
|
, m_attributes(attributes)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
@ -94,7 +93,6 @@ namespace LibGUI
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int m_server_fd;
|
const int m_server_fd;
|
||||||
const int m_epoll_fd;
|
|
||||||
|
|
||||||
bool m_handling_socket_error { false };
|
bool m_handling_socket_error { false };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/epoll.h>
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
|
@ -119,24 +119,12 @@ int main()
|
||||||
if (server_fd == -1)
|
if (server_fd == -1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
const int epoll_fd = epoll_create1(0);
|
struct ClientInfo
|
||||||
if (epoll_fd == -1)
|
|
||||||
{
|
{
|
||||||
dwarnln("failed to create epoll: {}", strerror(errno));
|
int fd;
|
||||||
return 1;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
{
|
BAN::Vector<ClientInfo> clients;
|
||||||
epoll_event event {
|
|
||||||
.events = EPOLLIN,
|
|
||||||
.data = { .fd = server_fd },
|
|
||||||
};
|
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event) == -1)
|
|
||||||
{
|
|
||||||
dwarnln("failed to add server socket to epoll: {}", strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintln("AudioServer started");
|
dprintln("AudioServer started");
|
||||||
|
|
||||||
|
|
@ -144,70 +132,67 @@ int main()
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
fd_set fds;
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(server_fd, &fds);
|
||||||
|
|
||||||
|
int max_fd = server_fd;
|
||||||
|
for (const auto& client : clients)
|
||||||
|
{
|
||||||
|
max_fd = BAN::Math::max(max_fd, client.fd);
|
||||||
|
FD_SET(client.fd, &fds);
|
||||||
|
}
|
||||||
|
|
||||||
const uint64_t current_ms = get_current_ms();
|
const uint64_t current_ms = get_current_ms();
|
||||||
next_update_ms = current_ms + audio_server->update();
|
next_update_ms = current_ms + audio_server->update();
|
||||||
|
|
||||||
const uint64_t timeout_ms = next_update_ms - current_ms;
|
const uint64_t timeout_ms = next_update_ms - current_ms;
|
||||||
|
|
||||||
epoll_event events[16];
|
timeval timeout {
|
||||||
int event_count = epoll_wait(epoll_fd, events, 16, timeout_ms);
|
.tv_sec = static_cast<time_t>(timeout_ms / 1000),
|
||||||
if (event_count == -1 && errno != EINTR)
|
.tv_usec = static_cast<suseconds_t>((timeout_ms % 1000) * 1000)
|
||||||
|
};
|
||||||
|
if (select(max_fd + 1, &fds, nullptr, nullptr, &timeout) == -1)
|
||||||
{
|
{
|
||||||
dwarnln("epoll_wait: {}", strerror(errno));
|
dwarnln("select: {}", strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < event_count; i++)
|
if (FD_ISSET(server_fd, &fds))
|
||||||
{
|
{
|
||||||
if (events[i].data.fd == server_fd)
|
const int client_fd = accept(server_fd, nullptr, nullptr);
|
||||||
|
if (client_fd == -1)
|
||||||
{
|
{
|
||||||
ASSERT(events[i].events & EPOLLIN);
|
dwarnln("accept: {}", strerror(errno));
|
||||||
|
|
||||||
const int client_fd = accept(server_fd, nullptr, nullptr);
|
|
||||||
if (client_fd == -1)
|
|
||||||
{
|
|
||||||
dwarnln("accept: {}", strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
epoll_event event {
|
|
||||||
.events = EPOLLIN,
|
|
||||||
.data = { .fd = client_fd },
|
|
||||||
};
|
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event) == -1)
|
|
||||||
{
|
|
||||||
dwarnln("Failed to add client to epoll: {}", strerror(errno));
|
|
||||||
close(client_fd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto ret = audio_server->on_new_client(client_fd); ret.is_error())
|
|
||||||
{
|
|
||||||
dwarnln("Failed to initialize client: {}", ret.error());
|
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
|
|
||||||
close(client_fd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int client_fd = events[i].data.fd;
|
if (auto ret = clients.emplace_back(client_fd); ret.is_error())
|
||||||
|
|
||||||
if (events[i].events & EPOLLHUP)
|
|
||||||
{
|
{
|
||||||
audio_server->on_client_disconnect(client_fd);
|
dwarnln("Failed to add client: {}", ret.error());
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
|
|
||||||
close(client_fd);
|
close(client_fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(events[i].events & EPOLLIN);
|
if (auto ret = audio_server->on_new_client(client_fd); ret.is_error())
|
||||||
|
{
|
||||||
|
dwarnln("Failed to initialize client: {}", ret.error());
|
||||||
|
clients.pop_back();
|
||||||
|
close(client_fd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < clients.size(); i++)
|
||||||
|
{
|
||||||
|
auto& client = clients[i];
|
||||||
|
if (!FD_ISSET(client.fd, &fds))
|
||||||
|
continue;
|
||||||
|
|
||||||
LibAudio::Packet packet;
|
LibAudio::Packet packet;
|
||||||
const ssize_t nrecv = recv(client_fd, &packet, sizeof(packet), 0);
|
const ssize_t nrecv = recv(client.fd, &packet, sizeof(packet), 0);
|
||||||
|
|
||||||
if (nrecv < static_cast<ssize_t>(sizeof(packet)) || !audio_server->on_client_packet(client_fd, packet))
|
if (nrecv < static_cast<ssize_t>(sizeof(packet)) || !audio_server->on_client_packet(client.fd, packet))
|
||||||
{
|
{
|
||||||
if (nrecv == 0)
|
if (nrecv == 0)
|
||||||
;
|
;
|
||||||
|
|
@ -216,9 +201,10 @@ int main()
|
||||||
else if (nrecv < static_cast<ssize_t>(sizeof(packet)))
|
else if (nrecv < static_cast<ssize_t>(sizeof(packet)))
|
||||||
dwarnln("client sent only {} bytes, {} expected", nrecv, sizeof(packet));
|
dwarnln("client sent only {} bytes, {} expected", nrecv, sizeof(packet));
|
||||||
|
|
||||||
audio_server->on_client_disconnect(client_fd);
|
audio_server->on_client_disconnect(client.fd);
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
|
close(client.fd);
|
||||||
close(client_fd);
|
clients.remove(i--);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1460,17 +1460,28 @@ void WindowServer::remove_client_fd(int fd)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_deleted_window = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowServer::ClientData& WindowServer::get_client_data(int fd)
|
int WindowServer::get_client_fds(fd_set& fds) const
|
||||||
{
|
{
|
||||||
auto it = m_client_data.find(fd);
|
int max_fd = 0;
|
||||||
if (it != m_client_data.end())
|
for (const auto& [fd, _] : m_client_data)
|
||||||
return it->value;
|
{
|
||||||
|
FD_SET(fd, &fds);
|
||||||
dwarnln("could not find client {}", fd);
|
max_fd = BAN::Math::max(max_fd, fd);
|
||||||
for (auto& [client_fd, _] : m_client_data)
|
}
|
||||||
dwarnln(" {}", client_fd);
|
return max_fd;
|
||||||
|
}
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
|
void WindowServer::for_each_client_fd(const BAN::Function<BAN::Iteration(int, ClientData&)>& callback)
|
||||||
|
{
|
||||||
|
m_deleted_window = false;
|
||||||
|
for (auto& [fd, cliend_data] : m_client_data)
|
||||||
|
{
|
||||||
|
if (m_deleted_window)
|
||||||
|
break;
|
||||||
|
callback(fd, cliend_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@
|
||||||
#include <LibInput/KeyEvent.h>
|
#include <LibInput/KeyEvent.h>
|
||||||
#include <LibInput/MouseEvent.h>
|
#include <LibInput/MouseEvent.h>
|
||||||
|
|
||||||
|
#include <sys/select.h>
|
||||||
|
|
||||||
class WindowServer
|
class WindowServer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -56,7 +58,8 @@ public:
|
||||||
|
|
||||||
void add_client_fd(int fd);
|
void add_client_fd(int fd);
|
||||||
void remove_client_fd(int fd);
|
void remove_client_fd(int fd);
|
||||||
ClientData& get_client_data(int fd);
|
int get_client_fds(fd_set& fds) const;
|
||||||
|
void for_each_client_fd(const BAN::Function<BAN::Iteration(int, ClientData&)>& callback);
|
||||||
|
|
||||||
bool is_stopped() const { return m_is_stopped; }
|
bool is_stopped() const { return m_is_stopped; }
|
||||||
|
|
||||||
|
|
@ -111,6 +114,7 @@ private:
|
||||||
|
|
||||||
bool m_is_mouse_relative { false };
|
bool m_is_mouse_relative { false };
|
||||||
|
|
||||||
|
bool m_deleted_window { false };
|
||||||
bool m_is_stopped { false };
|
bool m_is_stopped { false };
|
||||||
bool m_is_bouncing_window = false;
|
bool m_is_bouncing_window = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,9 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/banan-os.h>
|
#include <sys/banan-os.h>
|
||||||
#include <sys/epoll.h>
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/select.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
@ -157,29 +157,10 @@ int main()
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
|
|
||||||
if (epoll_fd == -1)
|
|
||||||
{
|
|
||||||
dwarnln("epoll_create1: {}", strerror(errno));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
epoll_event event {
|
|
||||||
.events = EPOLLIN,
|
|
||||||
.data = { .fd = server_fd },
|
|
||||||
};
|
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event) == -1)
|
|
||||||
{
|
|
||||||
dwarnln("epoll_ctl server: {}", strerror(errno));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tty_ctrl(STDIN_FILENO, TTY_CMD_UNSET, TTY_FLAG_ENABLE_INPUT) == -1)
|
if (tty_ctrl(STDIN_FILENO, TTY_CMD_UNSET, TTY_FLAG_ENABLE_INPUT) == -1)
|
||||||
{
|
{
|
||||||
dwarnln("tty_ctrl: {}", strerror(errno));
|
perror("tty_ctrl");
|
||||||
return 1;
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
atexit([]() { tty_ctrl(STDIN_FILENO, TTY_CMD_SET, TTY_FLAG_ENABLE_INPUT); });
|
atexit([]() { tty_ctrl(STDIN_FILENO, TTY_CMD_SET, TTY_FLAG_ENABLE_INPUT); });
|
||||||
|
|
@ -207,37 +188,11 @@ int main()
|
||||||
|
|
||||||
int keyboard_fd = open("/dev/keyboard", O_RDONLY | O_CLOEXEC);
|
int keyboard_fd = open("/dev/keyboard", O_RDONLY | O_CLOEXEC);
|
||||||
if (keyboard_fd == -1)
|
if (keyboard_fd == -1)
|
||||||
dwarnln("open keyboard: {}", strerror(errno));
|
perror("open");
|
||||||
else
|
|
||||||
{
|
|
||||||
epoll_event event {
|
|
||||||
.events = EPOLLIN,
|
|
||||||
.data = { .fd = keyboard_fd },
|
|
||||||
};
|
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, keyboard_fd, &event) == -1)
|
|
||||||
{
|
|
||||||
dwarnln("epoll_ctl keyboard: {}", strerror(errno));
|
|
||||||
close(keyboard_fd);
|
|
||||||
keyboard_fd = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int mouse_fd = open("/dev/mouse", O_RDONLY | O_CLOEXEC);
|
int mouse_fd = open("/dev/mouse", O_RDONLY | O_CLOEXEC);
|
||||||
if (mouse_fd == -1)
|
if (mouse_fd == -1)
|
||||||
dwarnln("open mouse: {}", strerror(errno));
|
perror("open");
|
||||||
else
|
|
||||||
{
|
|
||||||
epoll_event event {
|
|
||||||
.events = EPOLLIN,
|
|
||||||
.data = { .fd = mouse_fd },
|
|
||||||
};
|
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mouse_fd, &event) == -1)
|
|
||||||
{
|
|
||||||
dwarnln("epoll_ctl mouse: {}", strerror(errno));
|
|
||||||
close(mouse_fd);
|
|
||||||
mouse_fd = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintln("Window server started");
|
dprintln("Window server started");
|
||||||
|
|
||||||
|
|
@ -253,11 +208,11 @@ int main()
|
||||||
{
|
{
|
||||||
timespec current_ts;
|
timespec current_ts;
|
||||||
clock_gettime(CLOCK_MONOTONIC, ¤t_ts);
|
clock_gettime(CLOCK_MONOTONIC, ¤t_ts);
|
||||||
return (current_ts.tv_sec * 1'000'000) + (current_ts.tv_nsec / 1000);
|
return (current_ts.tv_sec * 1'000'000) + (current_ts.tv_nsec / 1'000);
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint64_t sync_interval_us = 1'000'000 / 60;
|
constexpr uint64_t sync_interval_us = 1'000'000 / 60;
|
||||||
uint64_t last_sync_us = get_current_us() - sync_interval_us;
|
uint64_t last_sync_us = 0;
|
||||||
while (!window_server.is_stopped())
|
while (!window_server.is_stopped())
|
||||||
{
|
{
|
||||||
const auto current_us = get_current_us();
|
const auto current_us = get_current_us();
|
||||||
|
|
@ -267,182 +222,168 @@ int main()
|
||||||
last_sync_us += sync_interval_us;
|
last_sync_us += sync_interval_us;
|
||||||
}
|
}
|
||||||
|
|
||||||
timespec timeout = {};
|
int max_fd = server_fd;
|
||||||
if (auto current_us = get_current_us(); current_us - last_sync_us < sync_interval_us)
|
|
||||||
timeout.tv_nsec = (sync_interval_us - (current_us - last_sync_us)) * 1000;
|
|
||||||
|
|
||||||
epoll_event events[16];
|
fd_set fds;
|
||||||
int epoll_events = epoll_pwait2(epoll_fd, events, 16, &timeout, nullptr);
|
FD_ZERO(&fds);
|
||||||
if (epoll_events == -1 && errno != EINTR)
|
FD_SET(server_fd, &fds);
|
||||||
|
if (keyboard_fd != -1)
|
||||||
{
|
{
|
||||||
dwarnln("epoll_pwait2: {}", strerror(errno));
|
FD_SET(keyboard_fd, &fds);
|
||||||
|
max_fd = BAN::Math::max(max_fd, keyboard_fd);
|
||||||
|
}
|
||||||
|
if (mouse_fd != -1)
|
||||||
|
{
|
||||||
|
FD_SET(mouse_fd, &fds);
|
||||||
|
max_fd = BAN::Math::max(max_fd, mouse_fd);
|
||||||
|
}
|
||||||
|
max_fd = BAN::Math::max(max_fd, window_server.get_client_fds(fds));
|
||||||
|
|
||||||
|
timeval select_timeout {};
|
||||||
|
if (auto current_us = get_current_us(); current_us - last_sync_us < sync_interval_us)
|
||||||
|
select_timeout.tv_usec = sync_interval_us - (current_us - last_sync_us);
|
||||||
|
|
||||||
|
int nselect = select(max_fd + 1, &fds, nullptr, nullptr, &select_timeout);
|
||||||
|
if (nselect == 0)
|
||||||
|
continue;
|
||||||
|
if (nselect == -1)
|
||||||
|
{
|
||||||
|
dwarnln("select: {}", strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < epoll_events; i++)
|
if (FD_ISSET(server_fd, &fds))
|
||||||
{
|
{
|
||||||
if (events[i].data.fd == server_fd)
|
int window_fd = accept4(server_fd, nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC);
|
||||||
|
if (window_fd == -1)
|
||||||
{
|
{
|
||||||
ASSERT(events[i].events & EPOLLIN);
|
dwarnln("accept: {}", strerror(errno));
|
||||||
|
|
||||||
int window_fd = accept4(server_fd, nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC);
|
|
||||||
if (window_fd == -1)
|
|
||||||
{
|
|
||||||
dwarnln("accept: {}", strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
epoll_event event {
|
|
||||||
.events = EPOLLIN,
|
|
||||||
.data = { .fd = window_fd },
|
|
||||||
};
|
|
||||||
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, window_fd, &event) == -1)
|
|
||||||
{
|
|
||||||
dwarnln("epoll_ctl: {}", strerror(errno));
|
|
||||||
close(window_fd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
window_server.add_client_fd(window_fd);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
window_server.add_client_fd(window_fd);
|
||||||
if (events[i].data.fd == keyboard_fd)
|
|
||||||
{
|
|
||||||
ASSERT(events[i].events & EPOLLIN);
|
|
||||||
|
|
||||||
LibInput::RawKeyEvent event;
|
|
||||||
if (read(keyboard_fd, &event, sizeof(event)) == -1)
|
|
||||||
{
|
|
||||||
dwarnln("read keyboard: {}", strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
window_server.on_key_event(LibInput::KeyboardLayout::get().key_event_from_raw(event));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (events[i].data.fd == mouse_fd)
|
|
||||||
{
|
|
||||||
ASSERT(events[i].events & EPOLLIN);
|
|
||||||
|
|
||||||
LibInput::MouseEvent event;
|
|
||||||
if (read(mouse_fd, &event, sizeof(event)) == -1)
|
|
||||||
{
|
|
||||||
dwarnln("read mouse: {}", strerror(errno));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch (event.type)
|
|
||||||
{
|
|
||||||
case LibInput::MouseEventType::MouseButtonEvent:
|
|
||||||
window_server.on_mouse_button(event.button_event);
|
|
||||||
break;
|
|
||||||
case LibInput::MouseEventType::MouseMoveEvent:
|
|
||||||
window_server.on_mouse_move(event.move_event);
|
|
||||||
break;
|
|
||||||
case LibInput::MouseEventType::MouseMoveAbsEvent:
|
|
||||||
window_server.on_mouse_move_abs(event.move_abs_event);
|
|
||||||
break;
|
|
||||||
case LibInput::MouseEventType::MouseScrollEvent:
|
|
||||||
window_server.on_mouse_scroll(event.scroll_event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int client_fd = events[i].data.fd;
|
|
||||||
if (events[i].events & EPOLLHUP)
|
|
||||||
{
|
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
|
|
||||||
window_server.remove_client_fd(client_fd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(events[i].events & EPOLLIN);
|
|
||||||
|
|
||||||
auto& client_data = window_server.get_client_data(client_fd);
|
|
||||||
|
|
||||||
if (client_data.packet_buffer.empty())
|
|
||||||
{
|
|
||||||
uint32_t packet_size;
|
|
||||||
const ssize_t nrecv = recv(client_fd, &packet_size, sizeof(uint32_t), 0);
|
|
||||||
if (nrecv < 0)
|
|
||||||
dwarnln("recv 1: {}", strerror(errno));
|
|
||||||
if (nrecv > 0 && nrecv != sizeof(uint32_t))
|
|
||||||
dwarnln("could not read packet size with a single recv call, closing connection...");
|
|
||||||
if (nrecv != sizeof(uint32_t))
|
|
||||||
{
|
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
|
|
||||||
window_server.remove_client_fd(client_fd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packet_size < 4)
|
|
||||||
{
|
|
||||||
dwarnln("client sent invalid packet, closing connection...");
|
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
|
|
||||||
window_server.remove_client_fd(client_fd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is a bit harsh, but i don't want to work on skipping streaming packets
|
|
||||||
if (client_data.packet_buffer.resize(packet_size).is_error())
|
|
||||||
{
|
|
||||||
dwarnln("could not allocate memory for client packet, closing connection...");
|
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
|
|
||||||
window_server.remove_client_fd(client_fd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
client_data.packet_buffer_nread = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ssize_t nrecv = recv(
|
|
||||||
client_fd,
|
|
||||||
client_data.packet_buffer.data() + client_data.packet_buffer_nread,
|
|
||||||
client_data.packet_buffer.size() - client_data.packet_buffer_nread,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
if (nrecv < 0)
|
|
||||||
dwarnln("recv 2: {}", strerror(errno));
|
|
||||||
if (nrecv <= 0)
|
|
||||||
{
|
|
||||||
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, nullptr);
|
|
||||||
window_server.remove_client_fd(client_fd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
client_data.packet_buffer_nread += nrecv;
|
|
||||||
if (client_data.packet_buffer_nread < client_data.packet_buffer.size())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ASSERT(client_data.packet_buffer.size() >= sizeof(uint32_t));
|
|
||||||
|
|
||||||
switch (*reinterpret_cast<LibGUI::PacketType*>(client_data.packet_buffer.data()))
|
|
||||||
{
|
|
||||||
#define WINDOW_PACKET_CASE(enum, function) \
|
|
||||||
case LibGUI::PacketType::enum: \
|
|
||||||
if (auto ret = LibGUI::WindowPacket::enum::deserialize(client_data.packet_buffer.span()); !ret.is_error()) \
|
|
||||||
window_server.function(client_fd, ret.release_value()); \
|
|
||||||
break
|
|
||||||
WINDOW_PACKET_CASE(WindowCreate, on_window_create);
|
|
||||||
WINDOW_PACKET_CASE(WindowInvalidate, on_window_invalidate);
|
|
||||||
WINDOW_PACKET_CASE(WindowSetPosition, on_window_set_position);
|
|
||||||
WINDOW_PACKET_CASE(WindowSetAttributes, on_window_set_attributes);
|
|
||||||
WINDOW_PACKET_CASE(WindowSetMouseRelative, on_window_set_mouse_relative);
|
|
||||||
WINDOW_PACKET_CASE(WindowSetSize, on_window_set_size);
|
|
||||||
WINDOW_PACKET_CASE(WindowSetMinSize, on_window_set_min_size);
|
|
||||||
WINDOW_PACKET_CASE(WindowSetMaxSize, on_window_set_max_size);
|
|
||||||
WINDOW_PACKET_CASE(WindowSetFullscreen, on_window_set_fullscreen);
|
|
||||||
WINDOW_PACKET_CASE(WindowSetTitle, on_window_set_title);
|
|
||||||
WINDOW_PACKET_CASE(WindowSetCursor, on_window_set_cursor);
|
|
||||||
#undef WINDOW_PACKET_CASE
|
|
||||||
default:
|
|
||||||
dprintln("unhandled packet type: {}", *reinterpret_cast<uint32_t*>(client_data.packet_buffer.data()));
|
|
||||||
}
|
|
||||||
|
|
||||||
client_data.packet_buffer.clear();
|
|
||||||
client_data.packet_buffer_nread = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keyboard_fd != -1 && FD_ISSET(keyboard_fd, &fds))
|
||||||
|
{
|
||||||
|
LibInput::RawKeyEvent event;
|
||||||
|
if (read(keyboard_fd, &event, sizeof(event)) == -1)
|
||||||
|
{
|
||||||
|
perror("read");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
window_server.on_key_event(LibInput::KeyboardLayout::get().key_event_from_raw(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mouse_fd != -1 && FD_ISSET(mouse_fd, &fds))
|
||||||
|
{
|
||||||
|
LibInput::MouseEvent event;
|
||||||
|
if (read(mouse_fd, &event, sizeof(event)) == -1)
|
||||||
|
{
|
||||||
|
perror("read");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case LibInput::MouseEventType::MouseButtonEvent:
|
||||||
|
window_server.on_mouse_button(event.button_event);
|
||||||
|
break;
|
||||||
|
case LibInput::MouseEventType::MouseMoveEvent:
|
||||||
|
window_server.on_mouse_move(event.move_event);
|
||||||
|
break;
|
||||||
|
case LibInput::MouseEventType::MouseMoveAbsEvent:
|
||||||
|
window_server.on_mouse_move_abs(event.move_abs_event);
|
||||||
|
break;
|
||||||
|
case LibInput::MouseEventType::MouseScrollEvent:
|
||||||
|
window_server.on_mouse_scroll(event.scroll_event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window_server.for_each_client_fd(
|
||||||
|
[&](int fd, WindowServer::ClientData& client_data) -> BAN::Iteration
|
||||||
|
{
|
||||||
|
if (!FD_ISSET(fd, &fds))
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
|
||||||
|
if (client_data.packet_buffer.empty())
|
||||||
|
{
|
||||||
|
uint32_t packet_size;
|
||||||
|
const ssize_t nrecv = recv(fd, &packet_size, sizeof(uint32_t), 0);
|
||||||
|
if (nrecv < 0)
|
||||||
|
dwarnln("recv: {}", strerror(errno));
|
||||||
|
if (nrecv > 0 && nrecv != sizeof(uint32_t))
|
||||||
|
dwarnln("could not read packet size with a single recv call, closing connection...");
|
||||||
|
if (nrecv != sizeof(uint32_t))
|
||||||
|
{
|
||||||
|
window_server.remove_client_fd(fd);
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet_size < 4)
|
||||||
|
{
|
||||||
|
dwarnln("client sent invalid packet, closing connection...");
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is a bit harsh, but i don't want to work on skipping streaming packets
|
||||||
|
if (client_data.packet_buffer.resize(packet_size).is_error())
|
||||||
|
{
|
||||||
|
dwarnln("could not allocate memory for client packet, closing connection...");
|
||||||
|
window_server.remove_client_fd(fd);
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
client_data.packet_buffer_nread = 0;
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ssize_t nrecv = recv(
|
||||||
|
fd,
|
||||||
|
client_data.packet_buffer.data() + client_data.packet_buffer_nread,
|
||||||
|
client_data.packet_buffer.size() - client_data.packet_buffer_nread,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (nrecv < 0)
|
||||||
|
dwarnln("recv: {}", strerror(errno));
|
||||||
|
if (nrecv <= 0)
|
||||||
|
{
|
||||||
|
window_server.remove_client_fd(fd);
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
client_data.packet_buffer_nread += nrecv;
|
||||||
|
if (client_data.packet_buffer_nread < client_data.packet_buffer.size())
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
|
||||||
|
ASSERT(client_data.packet_buffer.size() >= sizeof(uint32_t));
|
||||||
|
|
||||||
|
switch (*reinterpret_cast<LibGUI::PacketType*>(client_data.packet_buffer.data()))
|
||||||
|
{
|
||||||
|
#define WINDOW_PACKET_CASE(enum, function) \
|
||||||
|
case LibGUI::PacketType::enum: \
|
||||||
|
if (auto ret = LibGUI::WindowPacket::enum::deserialize(client_data.packet_buffer.span()); !ret.is_error()) \
|
||||||
|
window_server.function(fd, ret.release_value()); \
|
||||||
|
break
|
||||||
|
WINDOW_PACKET_CASE(WindowCreate, on_window_create);
|
||||||
|
WINDOW_PACKET_CASE(WindowInvalidate, on_window_invalidate);
|
||||||
|
WINDOW_PACKET_CASE(WindowSetPosition, on_window_set_position);
|
||||||
|
WINDOW_PACKET_CASE(WindowSetAttributes, on_window_set_attributes);
|
||||||
|
WINDOW_PACKET_CASE(WindowSetMouseRelative, on_window_set_mouse_relative);
|
||||||
|
WINDOW_PACKET_CASE(WindowSetSize, on_window_set_size);
|
||||||
|
WINDOW_PACKET_CASE(WindowSetMinSize, on_window_set_min_size);
|
||||||
|
WINDOW_PACKET_CASE(WindowSetMaxSize, on_window_set_max_size);
|
||||||
|
WINDOW_PACKET_CASE(WindowSetFullscreen, on_window_set_fullscreen);
|
||||||
|
WINDOW_PACKET_CASE(WindowSetTitle, on_window_set_title);
|
||||||
|
WINDOW_PACKET_CASE(WindowSetCursor, on_window_set_cursor);
|
||||||
|
#undef WINDOW_PACKET_CASE
|
||||||
|
default:
|
||||||
|
dprintln("unhandled packet type: {}", *reinterpret_cast<uint32_t*>(client_data.packet_buffer.data()));
|
||||||
|
}
|
||||||
|
|
||||||
|
client_data.packet_buffer.clear();
|
||||||
|
client_data.packet_buffer_nread = 0;
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue