Compare commits
35 Commits
1bd6cf048b
...
563d4beb30
Author | SHA1 | Date | |
---|---|---|---|
563d4beb30 | |||
e5bb07874d | |||
cf341dd82f | |||
5ab83343c6 | |||
b097932482 | |||
665d0e2284 | |||
935e1627af | |||
a9af1736b1 | |||
f44df78f01 | |||
5892ea6d99 | |||
93f0be760b | |||
2419efc513 | |||
7ad2428c1b | |||
05ca64e19a | |||
08ebc4fefe | |||
4831870f78 | |||
948d2af366 | |||
c7d5da540d | |||
4bb1930731 | |||
abaa66232b | |||
5e1153d2b8 | |||
5171e472a0 | |||
449869e81c | |||
d1c41c4fb1 | |||
8442fad197 | |||
a195439111 | |||
68d503186a | |||
41b2fd3b3a | |||
e912501c42 | |||
2fe25f160a | |||
adba7d8f7c | |||
30f86d8070 | |||
66e2db33b6 | |||
0da406e97e | |||
9fffc2def5 |
@ -7,7 +7,6 @@
|
|||||||
#include <luna/Alignment.h>
|
#include <luna/Alignment.h>
|
||||||
#include <luna/Alloc.h>
|
#include <luna/Alloc.h>
|
||||||
#include <luna/CString.h>
|
#include <luna/CString.h>
|
||||||
#include <luna/Common.h>
|
|
||||||
#include <luna/ScopeGuard.h>
|
#include <luna/ScopeGuard.h>
|
||||||
|
|
||||||
static bool can_execute_segment(u32 flags)
|
static bool can_execute_segment(u32 flags)
|
||||||
@ -114,14 +113,14 @@ Result<u64> ELFLoader::load(AddressSpace* space)
|
|||||||
if (can_write_segment(program_header.p_flags)) prot |= PROT_WRITE;
|
if (can_write_segment(program_header.p_flags)) prot |= PROT_WRITE;
|
||||||
if (can_execute_segment(program_header.p_flags)) prot |= PROT_EXEC;
|
if (can_execute_segment(program_header.p_flags)) prot |= PROT_EXEC;
|
||||||
|
|
||||||
if (!TRY(space->test_and_alloc_region(base_vaddr,
|
if (!TRY(space->test_and_alloc_region(
|
||||||
ceil_div(program_header.p_memsz + vaddr_diff, ARCH_PAGE_SIZE), prot,
|
base_vaddr, get_blocks_from_size(program_header.p_memsz + vaddr_diff, ARCH_PAGE_SIZE), prot,
|
||||||
MAP_ANONYMOUS | MAP_PRIVATE, 0, true)))
|
MAP_ANONYMOUS | MAP_PRIVATE, 0, true)))
|
||||||
return err(ENOMEM);
|
return err(ENOMEM);
|
||||||
|
|
||||||
// Allocate physical memory for the segment
|
// Allocate physical memory for the segment
|
||||||
TRY(MemoryManager::alloc_at(base_vaddr, ceil_div(program_header.p_memsz + vaddr_diff, ARCH_PAGE_SIZE),
|
TRY(MemoryManager::alloc_at(
|
||||||
flags));
|
base_vaddr, get_blocks_from_size(program_header.p_memsz + vaddr_diff, ARCH_PAGE_SIZE), flags));
|
||||||
|
|
||||||
// Zero out unused memory (before the start of the segment)
|
// Zero out unused memory (before the start of the segment)
|
||||||
memset((void*)base_vaddr, 0, vaddr_diff);
|
memset((void*)base_vaddr, 0, vaddr_diff);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "memory/MemoryManager.h"
|
#include "memory/MemoryManager.h"
|
||||||
#include "thread/Thread.h"
|
#include "thread/Thread.h"
|
||||||
#include <bits/modes.h>
|
#include <bits/modes.h>
|
||||||
#include <luna/Common.h>
|
#include <luna/Alignment.h>
|
||||||
|
|
||||||
TarStream g_initrd;
|
TarStream g_initrd;
|
||||||
extern const BOOTBOOT bootboot;
|
extern const BOOTBOOT bootboot;
|
||||||
@ -47,7 +47,7 @@ Result<void> InitRD::populate_vfs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now we don't need the original initrd anymore
|
// Now we don't need the original initrd anymore
|
||||||
MemoryManager::free_frames(bootboot.initrd_ptr, ceil_div(bootboot.initrd_size, ARCH_PAGE_SIZE));
|
MemoryManager::free_frames(bootboot.initrd_ptr, get_blocks_from_size(bootboot.initrd_size, ARCH_PAGE_SIZE));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "fs/ext2/FileSystem.h"
|
#include "fs/ext2/FileSystem.h"
|
||||||
#include "fs/ext2/Inode.h"
|
#include "fs/ext2/Inode.h"
|
||||||
#include <luna/Common.h>
|
#include <luna/Alignment.h>
|
||||||
|
|
||||||
static VFS::InodeType vfs_type_from_ext2_type(mode_t mode)
|
static VFS::InodeType vfs_type_from_ext2_type(mode_t mode)
|
||||||
{
|
{
|
||||||
@ -114,7 +114,7 @@ namespace Ext2
|
|||||||
fs->m_host_device = host_device;
|
fs->m_host_device = host_device;
|
||||||
|
|
||||||
fs->m_block_size = 1024 << fs->m_superblock.log_block_size;
|
fs->m_block_size = 1024 << fs->m_superblock.log_block_size;
|
||||||
fs->m_block_groups = ceil_div(fs->m_superblock.nr_blocks, fs->m_superblock.blocks_per_block_group);
|
fs->m_block_groups = get_blocks_from_size(fs->m_superblock.nr_blocks, fs->m_superblock.blocks_per_block_group);
|
||||||
|
|
||||||
#ifdef EXT2_DEBUG
|
#ifdef EXT2_DEBUG
|
||||||
kdbgln("ext2: Mounting new Ext2 file system, block size=%lu, blocks=%u, inodes=%u, block group=(%u blocks, %u "
|
kdbgln("ext2: Mounting new Ext2 file system, block size=%lu, blocks=%u, inodes=%u, block group=(%u blocks, %u "
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "memory/MemoryMap.h"
|
#include "memory/MemoryMap.h"
|
||||||
#include <luna/Alignment.h>
|
#include <luna/Alignment.h>
|
||||||
#include <luna/Bitmap.h>
|
#include <luna/Bitmap.h>
|
||||||
#include <luna/Common.h>
|
|
||||||
#include <luna/ScopeGuard.h>
|
#include <luna/ScopeGuard.h>
|
||||||
#include <luna/Spinlock.h>
|
#include <luna/Spinlock.h>
|
||||||
#include <luna/SystemError.h>
|
#include <luna/SystemError.h>
|
||||||
@ -41,11 +40,11 @@ namespace MemoryManager
|
|||||||
Result<void> protect_kernel_sections()
|
Result<void> protect_kernel_sections()
|
||||||
{
|
{
|
||||||
const usize rodata_size = (usize)(end_of_kernel_rodata - start_of_kernel_rodata);
|
const usize rodata_size = (usize)(end_of_kernel_rodata - start_of_kernel_rodata);
|
||||||
const usize rodata_pages = ceil_div(rodata_size, ARCH_PAGE_SIZE);
|
const usize rodata_pages = get_blocks_from_size(rodata_size, ARCH_PAGE_SIZE);
|
||||||
TRY(remap((u64)start_of_kernel_rodata, rodata_pages, MMU::NoExecute));
|
TRY(remap((u64)start_of_kernel_rodata, rodata_pages, MMU::NoExecute));
|
||||||
|
|
||||||
const usize data_size = (usize)(end_of_kernel_data - start_of_kernel_data);
|
const usize data_size = (usize)(end_of_kernel_data - start_of_kernel_data);
|
||||||
const usize data_pages = ceil_div(data_size, ARCH_PAGE_SIZE);
|
const usize data_pages = get_blocks_from_size(data_size, ARCH_PAGE_SIZE);
|
||||||
TRY(remap((u64)start_of_kernel_data, data_pages, MMU::NoExecute | MMU::ReadWrite));
|
TRY(remap((u64)start_of_kernel_data, data_pages, MMU::NoExecute | MMU::ReadWrite));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@ -68,7 +67,7 @@ namespace MemoryManager
|
|||||||
// We store our frame bitmap at the beginning of the largest free memory block.
|
// We store our frame bitmap at the beginning of the largest free memory block.
|
||||||
char* const frame_bitmap_addr = (char*)largest_free_entry.ptr();
|
char* const frame_bitmap_addr = (char*)largest_free_entry.ptr();
|
||||||
|
|
||||||
const usize frame_bitmap_size = ceil_div(physical_address_space_size / ARCH_PAGE_SIZE, 8UL);
|
const usize frame_bitmap_size = get_blocks_from_size(physical_address_space_size / ARCH_PAGE_SIZE, 8UL);
|
||||||
|
|
||||||
// This should never happen, unless memory is very fragmented. Usually there is always a very big block of
|
// This should never happen, unless memory is very fragmented. Usually there is always a very big block of
|
||||||
// usable memory and then some tiny blocks around it.
|
// usable memory and then some tiny blocks around it.
|
||||||
@ -97,7 +96,7 @@ namespace MemoryManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that the physical frames used by the bitmap aren't handed out to anyone else.
|
// Make sure that the physical frames used by the bitmap aren't handed out to anyone else.
|
||||||
lock_frames(largest_free_entry.address(), ceil_div(frame_bitmap_size, ARCH_PAGE_SIZE));
|
lock_frames(largest_free_entry.address(), get_blocks_from_size(frame_bitmap_size, ARCH_PAGE_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
@ -527,7 +526,7 @@ namespace MemoryManager
|
|||||||
|
|
||||||
uintptr_t diff = address - page;
|
uintptr_t diff = address - page;
|
||||||
|
|
||||||
usize pages = ceil_div(size + diff, ARCH_PAGE_SIZE);
|
usize pages = get_blocks_from_size(size + diff, ARCH_PAGE_SIZE);
|
||||||
|
|
||||||
while (pages--)
|
while (pages--)
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <bits/mmap.h>
|
#include <bits/mmap.h>
|
||||||
#include <bits/open-flags.h>
|
#include <bits/open-flags.h>
|
||||||
#include <luna/Alignment.h>
|
#include <luna/Alignment.h>
|
||||||
#include <luna/Common.h>
|
|
||||||
|
|
||||||
constexpr uintptr_t USERSPACE_HEAP_BASE = 0x3000000;
|
constexpr uintptr_t USERSPACE_HEAP_BASE = 0x3000000;
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ Result<u64> sys_mmap(Registers*, SyscallArgs args)
|
|||||||
|
|
||||||
if (!is_aligned<ARCH_PAGE_SIZE>(params.offset)) return err(EINVAL);
|
if (!is_aligned<ARCH_PAGE_SIZE>(params.offset)) return err(EINVAL);
|
||||||
|
|
||||||
const usize pages = ceil_div(params.len, ARCH_PAGE_SIZE);
|
params.len = align_up<ARCH_PAGE_SIZE>(params.len);
|
||||||
|
|
||||||
SharedMemory* shmem = nullptr;
|
SharedMemory* shmem = nullptr;
|
||||||
u64 shmid = 0;
|
u64 shmid = 0;
|
||||||
@ -42,12 +41,12 @@ Result<u64> sys_mmap(Registers*, SyscallArgs args)
|
|||||||
if (!description)
|
if (!description)
|
||||||
{
|
{
|
||||||
params.offset = 0;
|
params.offset = 0;
|
||||||
shmid = TRY(SharedMemory::create(nullptr, 0, pages));
|
shmid = TRY(SharedMemory::create(nullptr, 0, params.len / ARCH_PAGE_SIZE));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((params.prot & PROT_WRITE) && !(description->flags & O_WRONLY)) return err(EACCES);
|
if ((params.prot & PROT_WRITE) && !(description->flags & O_WRONLY)) return err(EACCES);
|
||||||
shmid = TRY(description->inode->query_shared_memory(params.offset, pages));
|
shmid = TRY(description->inode->query_shared_memory(params.offset, params.len / ARCH_PAGE_SIZE));
|
||||||
}
|
}
|
||||||
shmem = g_shared_memory_map.try_get_ref(shmid);
|
shmem = g_shared_memory_map.try_get_ref(shmid);
|
||||||
shmem->refs++;
|
shmem->refs++;
|
||||||
@ -56,13 +55,15 @@ Result<u64> sys_mmap(Registers*, SyscallArgs args)
|
|||||||
|
|
||||||
u64 address;
|
u64 address;
|
||||||
if (!params.addr)
|
if (!params.addr)
|
||||||
address = TRY(current->address_space->alloc_region(pages, params.prot, params.flags, params.offset, shmid));
|
address = TRY(current->address_space->alloc_region(get_blocks_from_size(params.len, ARCH_PAGE_SIZE),
|
||||||
|
params.prot, params.flags, params.offset, shmid));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// FIXME: We should be more flexible if MAP_FIXED was not specified.
|
// FIXME: We should be more flexible if MAP_FIXED was not specified.
|
||||||
address = align_down<ARCH_PAGE_SIZE>((u64)params.addr);
|
address = align_down<ARCH_PAGE_SIZE>((u64)params.addr);
|
||||||
if (!TRY(current->address_space->test_and_alloc_region(address, pages, params.prot, params.flags, params.offset,
|
if (!TRY(current->address_space->test_and_alloc_region(address,
|
||||||
shmid)))
|
get_blocks_from_size(params.len, ARCH_PAGE_SIZE),
|
||||||
|
params.prot, params.flags, params.offset, shmid)))
|
||||||
return err(ENOMEM);
|
return err(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,10 +76,10 @@ Result<u64> sys_mmap(Registers*, SyscallArgs args)
|
|||||||
kdbgln("mmap: mapping memory at %#lx, size=%zu", address, params.len);
|
kdbgln("mmap: mapping memory at %#lx, size=%zu", address, params.len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (shmem) { TRY(shmem->map(address, mmu_flags, params.offset, pages)); }
|
if (shmem) { TRY(shmem->map(address, mmu_flags, params.offset, params.len / ARCH_PAGE_SIZE)); }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TRY(MemoryManager::alloc_at_zeroed(address, pages, mmu_flags));
|
TRY(MemoryManager::alloc_at_zeroed(address, get_blocks_from_size(params.len, ARCH_PAGE_SIZE), mmu_flags));
|
||||||
if (description) { TRY(description->inode->read((u8*)address, params.offset, params.len)); }
|
if (description) { TRY(description->inode->read((u8*)address, params.offset, params.len)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,11 +92,11 @@ Result<u64> sys_munmap(Registers*, SyscallArgs args)
|
|||||||
usize size = (usize)args[1];
|
usize size = (usize)args[1];
|
||||||
|
|
||||||
if (size == 0) return err(EINVAL);
|
if (size == 0) return err(EINVAL);
|
||||||
if (!is_aligned<ARCH_PAGE_SIZE>(address)) return err(EINVAL);
|
if (!is_aligned<ARCH_PAGE_SIZE>(size)) return err(EINVAL);
|
||||||
|
|
||||||
Thread* current = Scheduler::current();
|
Thread* current = Scheduler::current();
|
||||||
|
|
||||||
bool ok = TRY(current->address_space->free_region(address, ceil_div(size, ARCH_PAGE_SIZE)));
|
bool ok = TRY(current->address_space->free_region(address, get_blocks_from_size(size, ARCH_PAGE_SIZE)));
|
||||||
|
|
||||||
// POSIX says munmap should silently do nothing if the memory was not already mapped.
|
// POSIX says munmap should silently do nothing if the memory was not already mapped.
|
||||||
if (!ok) return 0;
|
if (!ok) return 0;
|
||||||
@ -104,7 +105,7 @@ Result<u64> sys_munmap(Registers*, SyscallArgs args)
|
|||||||
kdbgln("munmap: unmapping memory at %#lx, size=%zu", address, size);
|
kdbgln("munmap: unmapping memory at %#lx, size=%zu", address, size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TRY(MemoryManager::unmap_owned_if_possible(address, ceil_div(size, ARCH_PAGE_SIZE)));
|
TRY(MemoryManager::unmap_owned_if_possible(address, get_blocks_from_size(size, ARCH_PAGE_SIZE)));
|
||||||
|
|
||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
@ -119,7 +120,7 @@ Result<u64> sys_msync(Registers*, SyscallArgs args)
|
|||||||
|
|
||||||
Thread* current = Scheduler::current();
|
Thread* current = Scheduler::current();
|
||||||
|
|
||||||
TRY(current->address_space->sync_regions(address, ceil_div(size, ARCH_PAGE_SIZE)));
|
TRY(current->address_space->sync_regions(address, get_blocks_from_size(size, ARCH_PAGE_SIZE)));
|
||||||
|
|
||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include <bits/errno-return.h>
|
#include <bits/errno-return.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <luna/Common.h>
|
|
||||||
#include <luna/Format.h>
|
#include <luna/Format.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -108,7 +107,7 @@ static ssize_t write_into_buffer(FILE* stream, const u8* data, ssize_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t size_remaining = stream->_buf.capacity - stream->_buf.size;
|
ssize_t size_remaining = stream->_buf.capacity - stream->_buf.size;
|
||||||
nwritten = min(size_remaining, size);
|
nwritten = size > size_remaining ? size_remaining : size;
|
||||||
memcpy(stream->_buf.buffer + stream->_buf.size, data, nwritten);
|
memcpy(stream->_buf.buffer + stream->_buf.size, data, nwritten);
|
||||||
|
|
||||||
stream->_buf.status |= FileStatusFlags::LastWrite;
|
stream->_buf.status |= FileStatusFlags::LastWrite;
|
||||||
@ -121,7 +120,7 @@ static ssize_t write_into_buffer(FILE* stream, const u8* data, ssize_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nwritten = write(stream->_fd, data, min(size, BUFSIZ));
|
nwritten = write(stream->_fd, data, size > BUFSIZ ? BUFSIZ : size);
|
||||||
if (nwritten < 0) return nwritten;
|
if (nwritten < 0) return nwritten;
|
||||||
size -= nwritten;
|
size -= nwritten;
|
||||||
data += nwritten;
|
data += nwritten;
|
||||||
@ -161,13 +160,13 @@ static ssize_t read_from_buffer(FILE* stream, u8* data, ssize_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ssize_t size_remaining = stream->_buf.size - stream->_buf.index;
|
ssize_t size_remaining = stream->_buf.size - stream->_buf.index;
|
||||||
nread = min(size_remaining, size);
|
nread = size > size_remaining ? size_remaining : size;
|
||||||
memcpy(data, stream->_buf.buffer + stream->_buf.index, nread);
|
memcpy(data, stream->_buf.buffer + stream->_buf.index, nread);
|
||||||
|
|
||||||
stream->_buf.index += nread;
|
stream->_buf.index += nread;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nread = read(stream->_fd, data, min(size, BUFSIZ));
|
nread = read(stream->_fd, data, size > BUFSIZ ? BUFSIZ : size);
|
||||||
if (nread < 0) return nread;
|
if (nread < 0) return nread;
|
||||||
if (nread == 0) return total_read;
|
if (nread == 0) return total_read;
|
||||||
size -= nread;
|
size -= nread;
|
||||||
|
@ -30,6 +30,16 @@ static_assert(align_up<512>(598ul) == 1024ul);
|
|||||||
static_assert(align_up<64>(194ul) == 256ul);
|
static_assert(align_up<64>(194ul) == 256ul);
|
||||||
static_assert(align_up<32>(64ul) == 64ul);
|
static_assert(align_up<32>(64ul) == 64ul);
|
||||||
|
|
||||||
|
template <typename T> constexpr T get_blocks_from_size(T value, T block_size)
|
||||||
|
{
|
||||||
|
return (value + (block_size - 1)) / block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(get_blocks_from_size(40960, 4096) == 10);
|
||||||
|
static_assert(get_blocks_from_size(194, 64) == 4);
|
||||||
|
static_assert(get_blocks_from_size(2, 32) == 1);
|
||||||
|
static_assert(get_blocks_from_size(0, 256) == 0);
|
||||||
|
|
||||||
// Offset a pointer by exactly <offset> bytes, no matter the type. Useful to avoid the quirks that come from C pointer
|
// Offset a pointer by exactly <offset> bytes, no matter the type. Useful to avoid the quirks that come from C pointer
|
||||||
// arithmetic.
|
// arithmetic.
|
||||||
template <typename T, typename Offset> constexpr inline T* offset_ptr(T* ptr, Offset offset)
|
template <typename T, typename Offset> constexpr inline T* offset_ptr(T* ptr, Offset offset)
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file Common.h
|
|
||||||
* @author apio (cloudapio.eu)
|
|
||||||
* @brief Common utility functions.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2023, the Luna authors.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Divide a by b, rounding the quotient up to the next multiple of b.
|
|
||||||
*
|
|
||||||
* @tparam T The type of a and b.
|
|
||||||
* @param a The dividend.
|
|
||||||
* @param b The divisor.
|
|
||||||
* @return constexpr T The result of the operation.
|
|
||||||
*/
|
|
||||||
template <typename T> inline constexpr T ceil_div(T a, T b)
|
|
||||||
{
|
|
||||||
return (a + (b - 1)) / b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return the minimum value out of a set of arguments.
|
|
||||||
*
|
|
||||||
* @tparam T The type of the arguments.
|
|
||||||
* @param a The first value of the set of arguments.
|
|
||||||
* @param args The rest of the set of arguments.
|
|
||||||
* @return constexpr T The minimum value.
|
|
||||||
*/
|
|
||||||
template <typename T, class... Args> inline constexpr T min(T a, Args... args)
|
|
||||||
{
|
|
||||||
if constexpr (sizeof...(args) == 0) return a;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
T b = min(args...);
|
|
||||||
return a > b ? b : a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return the maximum value out of a set of arguments.
|
|
||||||
*
|
|
||||||
* @tparam T The type of the arguments.
|
|
||||||
* @param a The first value of the set of arguments.
|
|
||||||
* @param args The rest of the set of arguments.
|
|
||||||
* @return constexpr T The maximum value.
|
|
||||||
*/
|
|
||||||
template <typename T, class... Args> inline constexpr T max(T a, Args... args)
|
|
||||||
{
|
|
||||||
if constexpr (sizeof...(args) == 0) return a;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
T b = max(args...);
|
|
||||||
return a > b ? a : b;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <luna/CString.h>
|
#include <luna/CString.h>
|
||||||
#include <luna/Common.h>
|
|
||||||
#include <luna/StringView.h>
|
#include <luna/StringView.h>
|
||||||
#include <luna/Types.h>
|
#include <luna/Types.h>
|
||||||
|
|
||||||
@ -38,7 +37,8 @@ template <usize Size> class StaticString
|
|||||||
|
|
||||||
void adopt(StringView string)
|
void adopt(StringView string)
|
||||||
{
|
{
|
||||||
usize length = strlcpy(m_buffer, string.chars(), min(sizeof(m_buffer), string.length() + 1));
|
usize length = strlcpy(m_buffer, string.chars(),
|
||||||
|
string.length() > sizeof(m_buffer) ? sizeof(m_buffer) : string.length() + 1);
|
||||||
if (length > Size) { m_length = Size; }
|
if (length > Size) { m_length = Size; }
|
||||||
else
|
else
|
||||||
m_length = length;
|
m_length = length;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <luna/Alignment.h>
|
#include <luna/Alignment.h>
|
||||||
#include <luna/Alloc.h>
|
#include <luna/Alloc.h>
|
||||||
#include <luna/CString.h>
|
#include <luna/CString.h>
|
||||||
#include <luna/Common.h>
|
|
||||||
#include <luna/DebugLog.h>
|
#include <luna/DebugLog.h>
|
||||||
#include <luna/Heap.h>
|
#include <luna/Heap.h>
|
||||||
#include <luna/LinkedList.h>
|
#include <luna/LinkedList.h>
|
||||||
@ -53,7 +52,7 @@ static Spinlock g_heap_lock;
|
|||||||
// of pages.
|
// of pages.
|
||||||
static usize get_pages_for_allocation(usize bytes)
|
static usize get_pages_for_allocation(usize bytes)
|
||||||
{
|
{
|
||||||
usize pages = ceil_div(bytes, PAGE_SIZE);
|
usize pages = get_blocks_from_size(bytes, PAGE_SIZE);
|
||||||
if (pages < MINIMUM_PAGES_PER_ALLOCATION) pages = MINIMUM_PAGES_PER_ALLOCATION;
|
if (pages < MINIMUM_PAGES_PER_ALLOCATION) pages = MINIMUM_PAGES_PER_ALLOCATION;
|
||||||
return pages;
|
return pages;
|
||||||
}
|
}
|
||||||
@ -155,7 +154,7 @@ static Result<void> combine_forward(HeapBlock* block)
|
|||||||
{
|
{
|
||||||
if (next->status & BLOCK_START_MEM)
|
if (next->status & BLOCK_START_MEM)
|
||||||
{
|
{
|
||||||
const usize pages = ceil_div(next->full_size + sizeof(HeapBlock), PAGE_SIZE);
|
const usize pages = get_blocks_from_size(next->full_size + sizeof(HeapBlock), PAGE_SIZE);
|
||||||
TRY(release_pages_impl(next, pages));
|
TRY(release_pages_impl(next, pages));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -184,7 +183,7 @@ static Result<HeapBlock*> combine_backward(HeapBlock* block)
|
|||||||
{
|
{
|
||||||
if (block->status & BLOCK_START_MEM)
|
if (block->status & BLOCK_START_MEM)
|
||||||
{
|
{
|
||||||
const usize pages = ceil_div(block->full_size + sizeof(HeapBlock), PAGE_SIZE);
|
const usize pages = get_blocks_from_size(block->full_size + sizeof(HeapBlock), PAGE_SIZE);
|
||||||
TRY(release_pages_impl(block, pages));
|
TRY(release_pages_impl(block, pages));
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
@ -304,7 +303,7 @@ Result<void> free_impl(void* ptr)
|
|||||||
if ((block->status & BLOCK_START_MEM) && (block->status & BLOCK_END_MEM))
|
if ((block->status & BLOCK_START_MEM) && (block->status & BLOCK_END_MEM))
|
||||||
{
|
{
|
||||||
heap.remove(block);
|
heap.remove(block);
|
||||||
const usize pages = ceil_div(block->full_size + sizeof(HeapBlock), PAGE_SIZE);
|
const usize pages = get_blocks_from_size(block->full_size + sizeof(HeapBlock), PAGE_SIZE);
|
||||||
TRY(release_pages_impl(block, pages));
|
TRY(release_pages_impl(block, pages));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,7 +366,7 @@ Result<void*> realloc_impl(void* ptr, usize size, bool may_realloc_again)
|
|||||||
lock.take_over().unlock();
|
lock.take_over().unlock();
|
||||||
|
|
||||||
void* const new_ptr = TRY(malloc_impl(size, may_realloc_again, false));
|
void* const new_ptr = TRY(malloc_impl(size, may_realloc_again, false));
|
||||||
memcpy(new_ptr, ptr, min(size, old_size));
|
memcpy(new_ptr, ptr, old_size > size ? size : old_size);
|
||||||
TRY(free_impl(ptr));
|
TRY(free_impl(ptr));
|
||||||
|
|
||||||
if (old_size < size) { memset(offset_ptr(new_ptr, old_size), MALLOC_SCRUB_BYTE, size - old_size); }
|
if (old_size < size) { memset(offset_ptr(new_ptr, old_size), MALLOC_SCRUB_BYTE, size - old_size); }
|
||||||
|
Loading…
Reference in New Issue
Block a user