mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-01 18:39:16 +00:00
Merge remote-tracking branch 'Kernel/master'
This commit is contained in:
98
Kernel/tests/cpuid.cpp
Normal file
98
Kernel/tests/cpuid.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <types.h>
|
||||
#include <memory.hpp>
|
||||
#include <debug.h>
|
||||
|
||||
extern bool DebuggerIsAttached;
|
||||
|
||||
__constructor void TestCPUIDStructs()
|
||||
{
|
||||
if (!DebuggerIsAttached)
|
||||
return;
|
||||
|
||||
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
|
||||
{
|
||||
CPU::x86::AMD::CPUID0x00000000 cpuid0;
|
||||
CPU::x86::AMD::CPUID0x00000001 cpuid1;
|
||||
CPU::x86::AMD::CPUID0x00000005 cpuid5;
|
||||
CPU::x86::AMD::CPUID0x00000006 cpuid6;
|
||||
CPU::x86::AMD::CPUID0x00000007_ECX_0 cpuid7_C_0;
|
||||
CPU::x86::AMD::CPUID0x0000000B_ECX_0 cpuidB_C_0;
|
||||
CPU::x86::AMD::CPUID0x0000000B_ECX_1 cpuidB_C_1;
|
||||
CPU::x86::AMD::CPUID0x0000000D_ECX_0 cpuidD_C_0;
|
||||
CPU::x86::AMD::CPUID0x0000000D_ECX_1 cpuidD_C_1;
|
||||
CPU::x86::AMD::CPUID0x0000000D_ECX_2 cpuidD_C_2;
|
||||
CPU::x86::AMD::CPUID0x0000000D_ECX_11 cpuidD_C_11;
|
||||
CPU::x86::AMD::CPUID0x0000000D_ECX_12 cpuidD_C_12;
|
||||
CPU::x86::AMD::CPUID0x0000000D_ECX_3E cpuidD_C_3E;
|
||||
CPU::x86::AMD::CPUID0x80000000 cpuid80000000;
|
||||
CPU::x86::AMD::CPUID0x80000001 cpuid80000001;
|
||||
CPU::x86::AMD::CPUID0x80000002 cpuid80000002;
|
||||
CPU::x86::AMD::CPUID0x80000003 cpuid80000003;
|
||||
CPU::x86::AMD::CPUID0x80000004 cpuid80000004;
|
||||
CPU::x86::AMD::CPUID0x80000005 cpuid80000005;
|
||||
CPU::x86::AMD::CPUID0x80000006 cpuid80000006;
|
||||
CPU::x86::AMD::CPUID0x80000007 cpuid80000007;
|
||||
CPU::x86::AMD::CPUID0x80000008 cpuid80000008;
|
||||
CPU::x86::AMD::CPUID0x8000000A cpuid8000000A;
|
||||
CPU::x86::AMD::CPUID0x80000019 cpuid80000019;
|
||||
CPU::x86::AMD::CPUID0x8000001A cpuid8000001A;
|
||||
CPU::x86::AMD::CPUID0x8000001B cpuid8000001B;
|
||||
CPU::x86::AMD::CPUID0x8000001C cpuid8000001C;
|
||||
CPU::x86::AMD::CPUID0x8000001D cpuid8000001D;
|
||||
CPU::x86::AMD::CPUID0x8000001E cpuid8000001E;
|
||||
CPU::x86::AMD::CPUID0x8000001F cpuid8000001F;
|
||||
CPU::x86::AMD::CPUID0x80000020 cpuid80000020;
|
||||
CPU::x86::AMD::CPUID0x80000021 cpuid80000021;
|
||||
CPU::x86::AMD::CPUID0x80000022 cpuid80000022;
|
||||
CPU::x86::AMD::CPUID0x80000023 cpuid80000023;
|
||||
CPU::x86::AMD::CPUID0x80000026 cpuid80000026;
|
||||
|
||||
// asmv("int3");
|
||||
}
|
||||
else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0)
|
||||
{
|
||||
CPU::x86::Intel::CPUID0x00000000 cpuid0;
|
||||
CPU::x86::Intel::CPUID0x00000001 cpuid1;
|
||||
CPU::x86::Intel::CPUID0x00000002 cpuid2;
|
||||
CPU::x86::Intel::CPUID0x00000003 cpuid3;
|
||||
CPU::x86::Intel::CPUID0x00000004_1 cpuid4_1;
|
||||
CPU::x86::Intel::CPUID0x00000005 cpuid5;
|
||||
CPU::x86::Intel::CPUID0x00000006 cpuid6;
|
||||
CPU::x86::Intel::CPUID0x00000007_0 cpuid7_0;
|
||||
CPU::x86::Intel::CPUID0x00000007_1 cpuid7_1;
|
||||
CPU::x86::Intel::CPUID0x0000000A cpuidA;
|
||||
CPU::x86::Intel::CPUID0x00000015 cpuid15;
|
||||
CPU::x86::Intel::CPUID0x00000016 cpuid16;
|
||||
CPU::x86::Intel::CPUID0x80000000 cpuid80000000;
|
||||
CPU::x86::Intel::CPUID0x80000001 cpuid80000001;
|
||||
CPU::x86::Intel::CPUID0x80000002 cpuid80000002;
|
||||
CPU::x86::Intel::CPUID0x80000003 cpuid80000003;
|
||||
CPU::x86::Intel::CPUID0x80000004 cpuid80000004;
|
||||
CPU::x86::Intel::CPUID0x80000006 cpuid80000006;
|
||||
CPU::x86::Intel::CPUID0x80000008 cpuid80000008;
|
||||
CPU::x86::Intel::CPUID0x8000000A cpuid8000000A;
|
||||
|
||||
// asmv("int3");
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
170
Kernel/tests/macros.cpp
Normal file
170
Kernel/tests/macros.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <types.h>
|
||||
#include <filesystem/ioctl.hpp>
|
||||
#include <interface/syscalls.h>
|
||||
#include <memory/macro.hpp>
|
||||
#include <memory/vma.hpp>
|
||||
#include <filesystem.hpp>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
/* static assert, no constructor needed */
|
||||
|
||||
#ifdef a64
|
||||
#if UINTPTR_MAX != UINT64_MAX
|
||||
#error "uintptr_t is not 64-bit!"
|
||||
#endif // UINTPTR_MAX != UINT64_MAX
|
||||
#endif // a64
|
||||
|
||||
#ifdef a32
|
||||
#if UINTPTR_MAX != UINT32_MAX
|
||||
#error "uintptr_t is not 32-bit!"
|
||||
#endif // UINTPTR_MAX != UINT32_MAX
|
||||
#endif // a32
|
||||
|
||||
#ifdef aa64
|
||||
#if UINTPTR_MAX != UINT64_MAX
|
||||
#error "uintptr_t is not 64-bit!"
|
||||
#endif // UINTPTR_MAX != UINT64_MAX
|
||||
#endif // aa64
|
||||
|
||||
#ifndef __fennix__
|
||||
#error "This compiler is not supported!"
|
||||
#endif // __fennix__
|
||||
|
||||
static_assert(TIOCGPTN == 0x80045430);
|
||||
static_assert(TIOCSPTLCK == 0x40045431);
|
||||
|
||||
__constructor void TestMacros()
|
||||
{
|
||||
{
|
||||
int a = TO_PAGES(4096);
|
||||
int b = FROM_PAGES(1);
|
||||
|
||||
debug("a: 4096 -> %d", a);
|
||||
debug("b: a -> %d", b);
|
||||
|
||||
if (a != 1)
|
||||
{
|
||||
error("t1: TO_PAGES is not equal to 1");
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
if (b != 4096)
|
||||
{
|
||||
error("t1: FROM_PAGES is not equal to 4096");
|
||||
inf_loop;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int a = TO_PAGES(4097);
|
||||
int b = FROM_PAGES(2);
|
||||
|
||||
debug("a: 4097 -> %d", a);
|
||||
debug("b: a -> %d", b);
|
||||
|
||||
if (a != 2)
|
||||
{
|
||||
error("t2: TO_PAGES is not equal to 2");
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
if (b != 8192)
|
||||
{
|
||||
error("t2: FROM_PAGES is not equal to 8192");
|
||||
inf_loop;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int a = 10;
|
||||
assert(a == 10);
|
||||
|
||||
const char *str = "Hello";
|
||||
assert(str != nullptr && str[0] == 'H');
|
||||
|
||||
bool flag = false;
|
||||
assert(!flag);
|
||||
}
|
||||
|
||||
debug("-------------------------");
|
||||
|
||||
{
|
||||
uint64_t bytes = PAGE_SIZE;
|
||||
uint64_t pgs = 1;
|
||||
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
uint64_t cnv_to_pgs = TO_PAGES(bytes);
|
||||
uint64_t cnv_from_pgs = FROM_PAGES(pgs);
|
||||
|
||||
if (cnv_to_pgs != pgs)
|
||||
{
|
||||
error("TO_PAGES is not equal to %d (pages: %d)", pgs, cnv_to_pgs);
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
if (cnv_from_pgs != bytes)
|
||||
{
|
||||
error("FROM_PAGES is not equal to %d (bytes: %d)", bytes, cnv_from_pgs);
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
bytes += PAGE_SIZE;
|
||||
pgs++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
debug("Testing ROUND_UP and ROUND_DOWN");
|
||||
int x = 0x101;
|
||||
int y = 0x100;
|
||||
int result;
|
||||
|
||||
result = ROUND_UP(x, y);
|
||||
if (result != 0x200)
|
||||
{
|
||||
error("ERROR: ROUND_UP failed: %d != 0x200", result);
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
result = ROUND_DOWN(x, y);
|
||||
if (result != 0x100)
|
||||
{
|
||||
error("ERROR: ROUND_DOWN failed: %d != 0x100", result);
|
||||
inf_loop;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
constexpr int x = 5;
|
||||
constexpr int y = 10;
|
||||
|
||||
constexpr int max_result = MAX(x, y);
|
||||
constexpr int min_result = MIN(x, y);
|
||||
|
||||
static_assert(max_result == 10);
|
||||
static_assert(min_result == 5);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
347
Kernel/tests/mem_allocs.cpp
Normal file
347
Kernel/tests/mem_allocs.cpp
Normal file
@ -0,0 +1,347 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <memory.hpp>
|
||||
#include <debug.h>
|
||||
#include <string>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
/* Originally from: https://github.com/EnderIce2/FennixProject/blob/main/kernel/test.cpp */
|
||||
|
||||
#define MEMTEST_ITERATIONS 1024
|
||||
#define MAX_SIZE 1024
|
||||
|
||||
void testMemoryIntegrity()
|
||||
{
|
||||
debug("Testing memory integrity...");
|
||||
|
||||
for (size_t i = 1; i <= MAX_SIZE; i *= 2)
|
||||
{
|
||||
void *ptr1 = malloc(i);
|
||||
if (ptr1 == NULL)
|
||||
{
|
||||
error("malloc failed for size %zu", i);
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
memset(ptr1, 0xAA, i);
|
||||
|
||||
for (size_t j = 0; j < i; ++j)
|
||||
{
|
||||
if (*((unsigned char *)ptr1 + j) != 0xAA)
|
||||
{
|
||||
error("Memory corruption detected before free (size %zu)", i);
|
||||
inf_loop;
|
||||
}
|
||||
}
|
||||
|
||||
void *ptr2 = malloc(i * 2);
|
||||
if (ptr2 == NULL)
|
||||
{
|
||||
error("malloc failed for size %zu", i * 2);
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
memset(ptr2, 0xBB, i * 2);
|
||||
|
||||
for (size_t j = 0; j < i; ++j)
|
||||
{
|
||||
if (*((unsigned char *)ptr1 + j) != 0xAA)
|
||||
{
|
||||
error("Memory corruption detected in previous allocation (size %zu)", i);
|
||||
inf_loop;
|
||||
}
|
||||
}
|
||||
|
||||
free(ptr1);
|
||||
|
||||
for (size_t j = 0; j < i; ++j)
|
||||
{
|
||||
if (*((unsigned char *)ptr2 + j) != 0xBB)
|
||||
{
|
||||
error("Memory corruption detected in current allocation (size %zu)", i * 2);
|
||||
inf_loop;
|
||||
}
|
||||
}
|
||||
|
||||
void *ptr3 = realloc(ptr2, i * 3);
|
||||
if (ptr3 == NULL)
|
||||
{
|
||||
error("realloc failed for size %zu", i * 3);
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
memset(ptr3, 0xCC, i * 3);
|
||||
|
||||
for (size_t j = 0; j < i; ++j)
|
||||
{
|
||||
if (*((unsigned char *)ptr3 + j) != 0xCC)
|
||||
{
|
||||
error("Memory corruption detected after realloc (size %zu)", i * 3);
|
||||
inf_loop;
|
||||
}
|
||||
}
|
||||
|
||||
free(ptr3);
|
||||
}
|
||||
|
||||
debug("Memory integrity test passed.");
|
||||
}
|
||||
|
||||
class test_mem_new_delete
|
||||
{
|
||||
public:
|
||||
test_mem_new_delete()
|
||||
{
|
||||
for (char i = 0; i < 2; i++)
|
||||
;
|
||||
}
|
||||
|
||||
~test_mem_new_delete()
|
||||
{
|
||||
for (char i = 0; i < 2; i++)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
extern bool DebuggerIsAttached;
|
||||
|
||||
void TestMemoryAllocation()
|
||||
{
|
||||
return; /* Bit annoying to have to wait for this to finish */
|
||||
#ifdef a32
|
||||
return; /* Not ready for now. */
|
||||
#endif
|
||||
if (DebuggerIsAttached)
|
||||
{
|
||||
debug("The test is disabled when the debugger is enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
testMemoryIntegrity();
|
||||
|
||||
void *tmpAlloc1 = kmalloc(176);
|
||||
void *tmpAlloc2 = kmalloc(511);
|
||||
void *tmpAlloc3 = kmalloc(1027);
|
||||
void *tmpAlloc4 = kmalloc(1569);
|
||||
for (int repeat = 0; repeat < 4; repeat++)
|
||||
{
|
||||
debug("---------------[TEST %d]---------------\n", repeat);
|
||||
|
||||
debug("Single Page Request Test");
|
||||
{
|
||||
uintptr_t prq1 = (uintptr_t)KernelAllocator.RequestPage();
|
||||
KernelAllocator.FreePage((void *)prq1);
|
||||
|
||||
for (size_t i = 0; i < MEMTEST_ITERATIONS; i++)
|
||||
KernelAllocator.FreePage(KernelAllocator.RequestPage());
|
||||
|
||||
uintptr_t prq2 = (uintptr_t)KernelAllocator.RequestPage();
|
||||
KernelAllocator.FreePage((void *)prq2);
|
||||
|
||||
debug(" Result:\t\t1-[%#lx]; 2-[%#lx]", (void *)prq1, (void *)prq2);
|
||||
assert(prq1 == prq2);
|
||||
}
|
||||
|
||||
debug("Multiple Page Request Test");
|
||||
{
|
||||
uintptr_t prq1 = (uintptr_t)KernelAllocator.RequestPages(10);
|
||||
KernelAllocator.FreePages((void *)prq1, 10);
|
||||
|
||||
for (size_t i = 0; i < MEMTEST_ITERATIONS; i++)
|
||||
KernelAllocator.FreePages(KernelAllocator.RequestPages(20), 20);
|
||||
|
||||
uintptr_t prq2 = (uintptr_t)KernelAllocator.RequestPages(10);
|
||||
KernelAllocator.FreePages((void *)prq2, 10);
|
||||
|
||||
debug(" Result:\t\t1-[%#lx]; 2-[%#lx]", (void *)prq1, (void *)prq2);
|
||||
assert(prq1 == prq2);
|
||||
}
|
||||
|
||||
debug("Multiple Fixed Malloc Test");
|
||||
{
|
||||
uintptr_t prq1 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq1);
|
||||
|
||||
for (size_t i = 0; i < MEMTEST_ITERATIONS; i++)
|
||||
{
|
||||
kfree(kmalloc(0x10000));
|
||||
kfree(kmalloc(0x1000));
|
||||
kfree(kmalloc(0x100));
|
||||
kfree(kmalloc(0x10));
|
||||
kfree(kmalloc(0x1));
|
||||
}
|
||||
|
||||
uintptr_t prq2 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq2);
|
||||
|
||||
debug(" Result:\t\t1-[%#lx]; 2-[%#lx]", (void *)prq1, (void *)prq2);
|
||||
if (Config.AllocatorType != Memory::MemoryAllocatorType::rpmalloc_)
|
||||
assert(prq1 == prq2);
|
||||
}
|
||||
|
||||
debug("Multiple Dynamic Malloc Test");
|
||||
{
|
||||
uintptr_t prq1 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq1);
|
||||
|
||||
for (size_t i = 1; i < MEMTEST_ITERATIONS; i++)
|
||||
kfree(kmalloc(i));
|
||||
|
||||
uintptr_t prq2 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq2);
|
||||
|
||||
debug(" Result:\t1-[%#lx]; 2-[%#lx]", (void *)prq1, (void *)prq2);
|
||||
if (Config.AllocatorType != Memory::MemoryAllocatorType::rpmalloc_)
|
||||
assert(prq1 == prq2);
|
||||
}
|
||||
|
||||
debug("New/Delete Test");
|
||||
{
|
||||
uintptr_t prq1 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq1);
|
||||
|
||||
for (size_t i = 0; i < MEMTEST_ITERATIONS; i++)
|
||||
{
|
||||
test_mem_new_delete *t = new test_mem_new_delete();
|
||||
delete t;
|
||||
}
|
||||
|
||||
uintptr_t prq2 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq2);
|
||||
|
||||
debug(" Result: \t1-[%#lx]; 2-[%#lx]", (void *)prq1, (void *)prq2);
|
||||
if (Config.AllocatorType != Memory::MemoryAllocatorType::rpmalloc_)
|
||||
assert(prq1 == prq2);
|
||||
}
|
||||
|
||||
debug("New/Delete Fixed Array Test");
|
||||
{
|
||||
uintptr_t prq1 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq1);
|
||||
|
||||
for (size_t i = 0; i < MEMTEST_ITERATIONS; i++)
|
||||
{
|
||||
char *t = new char[128];
|
||||
delete[] t;
|
||||
}
|
||||
|
||||
uintptr_t prq2 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq2);
|
||||
|
||||
debug(" Result: \t1-[%#lx]; 2-[%#lx]", (void *)prq1, (void *)prq2);
|
||||
if (Config.AllocatorType != Memory::MemoryAllocatorType::rpmalloc_)
|
||||
assert(prq1 == prq2);
|
||||
}
|
||||
|
||||
debug("New/Delete Dynamic Array Test");
|
||||
{
|
||||
uintptr_t prq1 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq1);
|
||||
|
||||
for (size_t i = 0; i < MEMTEST_ITERATIONS; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
continue;
|
||||
char *t = new char[i];
|
||||
delete[] t;
|
||||
}
|
||||
|
||||
uintptr_t prq2 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq2);
|
||||
|
||||
debug(" Result:\t1-[%#lx]; 2-[%#lx]", (void *)prq1, (void *)prq2);
|
||||
if (Config.AllocatorType != Memory::MemoryAllocatorType::rpmalloc_)
|
||||
assert(prq1 == prq2);
|
||||
}
|
||||
|
||||
debug("calloc Test");
|
||||
{
|
||||
uintptr_t prq1 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq1);
|
||||
|
||||
for (size_t i = 0; i < MEMTEST_ITERATIONS; i++)
|
||||
{
|
||||
char *t = (char *)kcalloc(128, 1);
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
uintptr_t prq2 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq2);
|
||||
|
||||
debug(" Result:\t1-[%#lx]; 2-[%#lx]", (void *)prq1, (void *)prq2);
|
||||
if (Config.AllocatorType != Memory::MemoryAllocatorType::rpmalloc_)
|
||||
assert(prq1 == prq2);
|
||||
}
|
||||
|
||||
debug("realloc Test");
|
||||
{
|
||||
uintptr_t prq1 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq1);
|
||||
|
||||
for (size_t i = 0; i < MEMTEST_ITERATIONS; i++)
|
||||
{
|
||||
char *t = (char *)kmalloc(128);
|
||||
t = (char *)krealloc(t, 256);
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
uintptr_t prq2 = (uintptr_t)kmalloc(0x1000);
|
||||
kfree((void *)prq2);
|
||||
|
||||
debug(" Result:\t1-[%#lx]; 2-[%#lx]", (void *)prq1, (void *)prq2);
|
||||
if (Config.AllocatorType != Memory::MemoryAllocatorType::rpmalloc_)
|
||||
assert(prq1 == prq2);
|
||||
}
|
||||
}
|
||||
|
||||
kfree(tmpAlloc1);
|
||||
kfree(tmpAlloc2);
|
||||
kfree(tmpAlloc3);
|
||||
kfree(tmpAlloc4);
|
||||
|
||||
debug("Memory Stress Test");
|
||||
for (size_t i = 1; i < 0x1000; i++)
|
||||
kfree(kmalloc(i));
|
||||
|
||||
debug("Invalid Usage Test");
|
||||
kfree(tmpAlloc1);
|
||||
kfree(tmpAlloc2);
|
||||
kfree(tmpAlloc3);
|
||||
kfree(tmpAlloc4);
|
||||
|
||||
/* Allocation functions have assertions to check for invalid usage */
|
||||
|
||||
// void *InvMlc = kmalloc(0);
|
||||
// assert(InvMlc == nullptr);
|
||||
// krealloc(InvMlc, 0);
|
||||
// assert(InvMlc == nullptr);
|
||||
// kcalloc(0, 0);
|
||||
// assert(InvMlc == nullptr);
|
||||
// kcalloc(1, 0);
|
||||
// assert(InvMlc == nullptr);
|
||||
// kcalloc(0, 1);
|
||||
// assert(InvMlc == nullptr);
|
||||
// kfree(InvMlc);
|
||||
|
||||
debug("Memory Test Complete");
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
147
Kernel/tests/mem_ops.cpp
Normal file
147
Kernel/tests/mem_ops.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <types.h>
|
||||
#include <memory.hpp>
|
||||
#include <convert.h>
|
||||
|
||||
|
||||
extern bool DebuggerIsAttached;
|
||||
extern Memory::MemoryAllocatorType AllocatorType;
|
||||
|
||||
__constructor void TestMemoryOperations()
|
||||
{
|
||||
if (DebuggerIsAttached)
|
||||
{
|
||||
debug("The test is disabled when the debugger is enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (AllocatorType == Memory::MemoryAllocatorType::Pages)
|
||||
{
|
||||
debug("The test is disabled when the allocator is set to pages.");
|
||||
return;
|
||||
}
|
||||
|
||||
int arr1[5] = {1, 2, 3, 4, 5};
|
||||
int arr2[5] = {0, 0, 0, 0, 0};
|
||||
char str1[] = "Hello";
|
||||
char str2[] = "World";
|
||||
|
||||
memcpy_unsafe(arr2, arr1, sizeof(arr1));
|
||||
debug("memcpy: arr2[0]=%d, arr2[1]=%d, arr2[2]=%d, arr2[3]=%d, arr2[4]=%d",
|
||||
arr2[0], arr2[1], arr2[2], arr2[3], arr2[4]);
|
||||
if (memcmp(arr1, arr2, sizeof(arr1)) != 0)
|
||||
{
|
||||
error("memcpy failed!");
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
memset_unsafe(arr2, 0, sizeof(arr2));
|
||||
debug("memset: arr2[0]=%d, arr2[1]=%d, arr2[2]=%d, arr2[3]=%d, arr2[4]=%d",
|
||||
arr2[0], arr2[1], arr2[2], arr2[3], arr2[4]);
|
||||
if (memcmp(arr1, arr2, sizeof(arr1)) == 0)
|
||||
{
|
||||
error("memset failed!");
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
memmove_unsafe(str1 + 3, str1, strlen(str1) + 1);
|
||||
debug("memmove: str1=%s", str1);
|
||||
if (strcmp(str1, "HelHello") != 0)
|
||||
{
|
||||
error("memmove failed!");
|
||||
inf_loop;
|
||||
}
|
||||
|
||||
char carr[512];
|
||||
char carrTo[16];
|
||||
|
||||
for (size_t i = 0; i < 512; i++)
|
||||
{
|
||||
for (size_t i = 0; i < 16; i++)
|
||||
carrTo[i] = 'a';
|
||||
|
||||
for (size_t i = 0; i < 512; i += 16)
|
||||
memcpy_unsafe(carr + i, carrTo, 16);
|
||||
|
||||
for (size_t i = 0; i < 512; i++)
|
||||
{
|
||||
if (carr[i] != 'a')
|
||||
{
|
||||
error("memcpy failed!");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
char carrFull[512];
|
||||
for (size_t i = 0; i < 512; i++)
|
||||
carrFull[i] = 'b';
|
||||
|
||||
memcpy_unsafe(carr, carrFull, 512);
|
||||
|
||||
for (size_t i = 0; i < 512; i++)
|
||||
{
|
||||
if (carr[i] != 'b')
|
||||
{
|
||||
error("memcpy failed!");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 512; i++)
|
||||
{
|
||||
for (size_t i = 0; i < 512; i += 16)
|
||||
memset_unsafe(carr + i, 'c', 16);
|
||||
|
||||
for (size_t i = 0; i < 512; i++)
|
||||
{
|
||||
if (carr[i] != 'c')
|
||||
{
|
||||
error("memcpy failed!");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 512; i++)
|
||||
{
|
||||
memset_unsafe(carr, 'd', 512);
|
||||
|
||||
for (size_t i = 0; i < 512; i++)
|
||||
{
|
||||
if (carr[i] != 'd')
|
||||
{
|
||||
error("memset failed!");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug("Memory operations test passed");
|
||||
}
|
||||
|
||||
#endif
|
108
Kernel/tests/ptr_t.cpp
Normal file
108
Kernel/tests/ptr_t.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <types.h>
|
||||
#include <debug.h>
|
||||
#include <assert.h>
|
||||
|
||||
class __ptr_t_demo
|
||||
{
|
||||
public:
|
||||
ptr_t<void *> Address;
|
||||
|
||||
__ptr_t_demo(ptr_t<void *> Address, ptr_t<void *> Address2 = nullptr)
|
||||
{
|
||||
this->Address = Address;
|
||||
}
|
||||
|
||||
~__ptr_t_demo() {}
|
||||
|
||||
void *test1()
|
||||
{
|
||||
return Address + 0xdeadbeef;
|
||||
}
|
||||
|
||||
uintptr_t test2()
|
||||
{
|
||||
return Address + 0xdeadbeef;
|
||||
}
|
||||
|
||||
void *Map(ptr_t<void *> VirtualAddress, ptr_t<void *> &PhysicalAddress, size_t Length)
|
||||
{
|
||||
ptr_t<void *> Final;
|
||||
for (size_t i = 0; i < Length; i++)
|
||||
Final = VirtualAddress + (i * 0x1000);
|
||||
|
||||
PhysicalAddress = 0;
|
||||
return Final;
|
||||
}
|
||||
};
|
||||
|
||||
__constructor void TestPtr_T()
|
||||
{
|
||||
__ptr_t_demo demo(nullptr);
|
||||
assert(demo.test1() == (void *)0xdeadbeef);
|
||||
assert(demo.test2() == 0xdeadbeef);
|
||||
|
||||
ptr_t<void *> VirtualAddress = 0x1000;
|
||||
ptr_t<void *> PhysicalAddress = 0x2000;
|
||||
size_t Length = 4;
|
||||
|
||||
void *ret = demo.Map(VirtualAddress, PhysicalAddress, Length);
|
||||
assert(ret == (void *)0x4000);
|
||||
|
||||
VirtualAddress -= 0x1000;
|
||||
assert(PhysicalAddress == 0);
|
||||
|
||||
VirtualAddress = 0x1;
|
||||
assert(VirtualAddress > PhysicalAddress);
|
||||
assert(VirtualAddress > 0);
|
||||
|
||||
PhysicalAddress = 0x2;
|
||||
assert(VirtualAddress < PhysicalAddress);
|
||||
PhysicalAddress = 0;
|
||||
assert(!(PhysicalAddress < 0));
|
||||
|
||||
PhysicalAddress = 0x1;
|
||||
assert(VirtualAddress >= PhysicalAddress);
|
||||
assert(VirtualAddress >= 0);
|
||||
|
||||
VirtualAddress = 0;
|
||||
PhysicalAddress = 0;
|
||||
assert(VirtualAddress <= PhysicalAddress);
|
||||
assert(PhysicalAddress <= 0);
|
||||
|
||||
VirtualAddress = 0x1000;
|
||||
assert(VirtualAddress == 0x1000);
|
||||
assert(VirtualAddress != 0x2000);
|
||||
|
||||
PhysicalAddress = 0x1000;
|
||||
assert(PhysicalAddress == 0x1000);
|
||||
assert(PhysicalAddress != 0x2000);
|
||||
|
||||
ptr_t<void *> v;
|
||||
v += 1;
|
||||
assert(v == 1);
|
||||
v -= 1;
|
||||
assert(v == 0);
|
||||
v -= 1;
|
||||
assert(v == (void *)-1);
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
66
Kernel/tests/rng.cpp
Normal file
66
Kernel/tests/rng.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <rand.hpp>
|
||||
#include <debug.h>
|
||||
#include <cpu.hpp>
|
||||
|
||||
__constructor void TestRandom()
|
||||
{
|
||||
int RDRANDFlag = 0;
|
||||
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
|
||||
{
|
||||
CPU::x86::AMD::CPUID0x00000001 cpuid;
|
||||
RDRANDFlag = cpuid.ECX.RDRAND;
|
||||
}
|
||||
else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0)
|
||||
{
|
||||
CPU::x86::Intel::CPUID0x00000001 cpuid;
|
||||
RDRANDFlag = cpuid.ECX.RDRAND;
|
||||
}
|
||||
|
||||
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0)
|
||||
RDRANDFlag = 0;
|
||||
|
||||
#if defined(a86)
|
||||
if (RDRANDFlag)
|
||||
{
|
||||
uintptr_t RDSEEDValue = 0;
|
||||
asmv("1: rdseed %0; jnc 1b"
|
||||
: "=r"(RDSEEDValue));
|
||||
debug("RDSEED: %ld", RDSEEDValue);
|
||||
}
|
||||
#endif
|
||||
|
||||
Random::ChangeSeed(0xdeadbeef);
|
||||
uint16_t Seeds16[16];
|
||||
uint32_t Seeds32[16];
|
||||
uint64_t Seeds64[16];
|
||||
for (short i = 0; i < 16; i++)
|
||||
{
|
||||
Seeds16[i] = Random::rand16();
|
||||
Seeds32[i] = Random::rand32();
|
||||
Seeds64[i] = Random::rand64();
|
||||
}
|
||||
debug("Random 16: %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld", Seeds16[0], Seeds16[1], Seeds16[2], Seeds16[3], Seeds16[4], Seeds16[5], Seeds16[6], Seeds16[7], Seeds16[8], Seeds16[9], Seeds16[10], Seeds16[11], Seeds16[12], Seeds16[13], Seeds16[14], Seeds16[15]);
|
||||
debug("Random 32: %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld", Seeds32[0], Seeds32[1], Seeds32[2], Seeds32[3], Seeds32[4], Seeds32[5], Seeds32[6], Seeds32[7], Seeds32[8], Seeds32[9], Seeds32[10], Seeds32[11], Seeds32[12], Seeds32[13], Seeds32[14], Seeds32[15]);
|
||||
debug("Random 64: %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld", Seeds64[0], Seeds64[1], Seeds64[2], Seeds64[3], Seeds64[4], Seeds64[5], Seeds64[6], Seeds64[7], Seeds64[8], Seeds64[9], Seeds64[10], Seeds64[11], Seeds64[12], Seeds64[13], Seeds64[14], Seeds64[15]);
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
87
Kernel/tests/stl/bitset.cpp
Normal file
87
Kernel/tests/stl/bitset.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <bitset>
|
||||
|
||||
void __stl_bitset_test()
|
||||
{
|
||||
/* Code from: https://en.cppreference.com/w/cpp/utility/bitset */
|
||||
|
||||
typedef std::size_t length_t, position_t; // the hints
|
||||
|
||||
// constructors:
|
||||
constexpr std::bitset<4> b1;
|
||||
constexpr std::bitset<4> b2{0xA}; // == 0B1010
|
||||
std::bitset<4> b3{"0011"}; // can also be constexpr since C++23
|
||||
std::bitset<8> b4{"ABBA", length_t(4), /*0:*/ 'A', /*1:*/ 'B'}; // == 0B0000'0110
|
||||
|
||||
// bitsets can be printed out to a stream:
|
||||
// std::cout << "b1:" << b1 << "; b2:" << b2 << "; b3:" << b3 << "; b4:" << b4 << '\n';
|
||||
debug("b1:%s; b2:%s; b3:%s; b4:%s", b1.to_string().c_str(), b2.to_string().c_str(), b3.to_string().c_str(), b4.to_string().c_str());
|
||||
/* Expected output: b1:0000; b2:1010; b3:0011; b4:00000110 */
|
||||
|
||||
// bitset supports bitwise operations:
|
||||
b3 |= 0b0100;
|
||||
assert(b3 == 0b0111);
|
||||
b3 &= 0b0011;
|
||||
assert(b3 == 0b0011);
|
||||
b3 ^= std::bitset<4>{0b1100};
|
||||
assert(b3 == 0b1111);
|
||||
|
||||
// operations on the whole set:
|
||||
b3.reset();
|
||||
assert(b3 == 0);
|
||||
b3.set();
|
||||
assert(b3 == 0b1111);
|
||||
assert(b3.all() && b3.any() && !b3.none());
|
||||
b3.flip();
|
||||
assert(b3 == 0);
|
||||
|
||||
// operations on individual bits:
|
||||
b3.set(position_t(1), true);
|
||||
assert(b3 == 0b0010);
|
||||
b3.set(position_t(1), false);
|
||||
assert(b3 == 0);
|
||||
b3.flip(position_t(2));
|
||||
assert(b3 == 0b0100);
|
||||
b3.reset(position_t(2));
|
||||
assert(b3 == 0);
|
||||
|
||||
// subscript operator[] is supported:
|
||||
b3[2] = true;
|
||||
assert(true == b3[2]);
|
||||
|
||||
// other operations:
|
||||
assert(b3.count() == 1);
|
||||
assert(b3.size() == 4);
|
||||
assert(b3.to_ullong() == 0b0100ULL);
|
||||
assert(b3.to_string() == "0100");
|
||||
}
|
||||
|
||||
void test_stl_bitset()
|
||||
{
|
||||
debug("std::bitset ...");
|
||||
|
||||
__stl_bitset_test();
|
||||
|
||||
debug("std::bitset OK");
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
155
Kernel/tests/stl/coroutines.cpp
Normal file
155
Kernel/tests/stl/coroutines.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109867 */
|
||||
#pragma GCC diagnostic ignored "-Wswitch-default"
|
||||
|
||||
#include "../t.h"
|
||||
#include "../kernel.h"
|
||||
|
||||
#include <coroutine>
|
||||
|
||||
/* https://gist.github.com/Qix-/caa277fbf1a4e6ca55a27f2242df3b9a */
|
||||
|
||||
class resumable
|
||||
{
|
||||
public:
|
||||
struct promise_type;
|
||||
using coro_handle = std::coroutine_handle<promise_type>;
|
||||
|
||||
resumable(coro_handle handle) : co_handle(handle) { assert(handle); }
|
||||
resumable(resumable &) = delete;
|
||||
resumable(resumable &&) = delete;
|
||||
|
||||
~resumable() { co_handle.destroy(); }
|
||||
|
||||
bool resume()
|
||||
{
|
||||
if (!co_handle.done())
|
||||
co_handle.resume();
|
||||
return !co_handle.done();
|
||||
}
|
||||
|
||||
private:
|
||||
coro_handle co_handle;
|
||||
};
|
||||
|
||||
struct resumable::promise_type
|
||||
{
|
||||
using coro_handle = std::coroutine_handle<promise_type>;
|
||||
|
||||
auto get_return_object() { return coro_handle::from_promise(*this); }
|
||||
auto initial_suspend() { return std::suspend_always(); }
|
||||
auto final_suspend() noexcept { return std::suspend_always(); }
|
||||
void return_void() {}
|
||||
void unhandled_exception() { assert(!"std::terminate();"); }
|
||||
};
|
||||
|
||||
resumable foo()
|
||||
{
|
||||
debug("await start");
|
||||
co_await std::suspend_always();
|
||||
debug("done");
|
||||
}
|
||||
|
||||
/* ===================================================================== */
|
||||
|
||||
class SyscallAwaitable
|
||||
{
|
||||
public:
|
||||
bool await_ready() const noexcept
|
||||
{
|
||||
debug("Syscall await_ready() called");
|
||||
return false; /* false - coroutine is not ready, so suspend */
|
||||
}
|
||||
|
||||
void await_suspend(std::coroutine_handle<> handle) const noexcept
|
||||
{
|
||||
debug("Syscall suspended, waiting for data...");
|
||||
}
|
||||
|
||||
int await_resume() const noexcept
|
||||
{
|
||||
debug("Syscall resumed and returned 42");
|
||||
return 42;
|
||||
}
|
||||
};
|
||||
|
||||
class SyscallTask
|
||||
{
|
||||
public:
|
||||
struct promise_type
|
||||
{
|
||||
SyscallTask get_return_object()
|
||||
{
|
||||
return SyscallTask{std::coroutine_handle<promise_type>::from_promise(*this)};
|
||||
}
|
||||
|
||||
std::suspend_never initial_suspend()
|
||||
{
|
||||
debug("Syscall started");
|
||||
return {};
|
||||
}
|
||||
|
||||
std::suspend_never final_suspend() noexcept
|
||||
{
|
||||
debug("Syscall finished");
|
||||
return {};
|
||||
}
|
||||
|
||||
void return_void()
|
||||
{
|
||||
debug("Syscall finished");
|
||||
}
|
||||
|
||||
void unhandled_exception()
|
||||
{
|
||||
assert("std::terminate();");
|
||||
}
|
||||
};
|
||||
|
||||
std::coroutine_handle<promise_type> handle;
|
||||
explicit SyscallTask(std::coroutine_handle<promise_type> h) : handle(h) {}
|
||||
~SyscallTask()
|
||||
{
|
||||
if (handle)
|
||||
handle.destroy();
|
||||
}
|
||||
};
|
||||
|
||||
SyscallTask perform_syscall()
|
||||
{
|
||||
debug("Initializing syscall I/O...");
|
||||
int data = co_await SyscallAwaitable{};
|
||||
debug("Syscall finished: %d", data);
|
||||
}
|
||||
|
||||
void coroutineTest()
|
||||
{
|
||||
/* Example of syscall using coroutine */
|
||||
auto task = perform_syscall();
|
||||
task.handle.resume();
|
||||
|
||||
/* Example of coroutine */
|
||||
auto p = foo();
|
||||
while (p.resume())
|
||||
;
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
181
Kernel/tests/stl/exception.cpp
Normal file
181
Kernel/tests/stl/exception.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
#include <exception>
|
||||
#include <printf.h>
|
||||
|
||||
nsa void __stl_test_exception0()
|
||||
{
|
||||
try
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
debug("caught exception");
|
||||
}
|
||||
}
|
||||
|
||||
nsa void __stl_test_exception1()
|
||||
{
|
||||
try
|
||||
{
|
||||
throw std::out_of_range("out of range");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
debug("caught out_of_range");
|
||||
}
|
||||
}
|
||||
|
||||
nsa void __stl_test_exception2()
|
||||
{
|
||||
try
|
||||
{
|
||||
throw std::out_of_range("out of range");
|
||||
}
|
||||
catch (std::out_of_range &e)
|
||||
{
|
||||
debug("caught: %s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
nsa void __stl_test_exception3()
|
||||
{
|
||||
try
|
||||
{
|
||||
throw std::exception();
|
||||
}
|
||||
catch (std::out_of_range &e)
|
||||
{
|
||||
debug("caught out_of_range: %s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
nsa void __stl_test_exception4()
|
||||
{
|
||||
try
|
||||
{
|
||||
throw std::out_of_range("test");
|
||||
}
|
||||
catch (std::out_of_range &e)
|
||||
{
|
||||
debug("caught out_of_range: %s", e.what());
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
debug("caught exception: %s", e.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
debug("caught ...");
|
||||
}
|
||||
}
|
||||
|
||||
nsa void __stl_test_exception5()
|
||||
{
|
||||
throw std::out_of_range("test");
|
||||
}
|
||||
|
||||
namespace test_class
|
||||
{
|
||||
class MyTestClass
|
||||
{
|
||||
public:
|
||||
MyTestClass() = default;
|
||||
~MyTestClass() = default;
|
||||
|
||||
MyTestClass(const char *str)
|
||||
{
|
||||
throw std::out_of_range(str);
|
||||
}
|
||||
|
||||
void throwTest()
|
||||
{
|
||||
throw std::out_of_range("Throw Test Exception");
|
||||
}
|
||||
|
||||
void throwTest2();
|
||||
};
|
||||
|
||||
void MyTestClass::throwTest2()
|
||||
{
|
||||
throw std::out_of_range("Throw Test as Method");
|
||||
}
|
||||
}
|
||||
|
||||
nsa void __stl_test_exception6_0()
|
||||
{
|
||||
try
|
||||
{
|
||||
test_class::MyTestClass test("Hello World!");
|
||||
}
|
||||
catch (std::out_of_range &e)
|
||||
{
|
||||
debug("caught out_of_range: %s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
nsa void __stl_test_exception6_1()
|
||||
{
|
||||
test_class::MyTestClass test;
|
||||
try
|
||||
{
|
||||
test.throwTest();
|
||||
}
|
||||
catch (std::out_of_range &e)
|
||||
{
|
||||
debug("caught out_of_range: %s", e.what());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
test.throwTest2();
|
||||
}
|
||||
catch (std::out_of_range &e)
|
||||
{
|
||||
debug("caught out_of_range: %s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
nsa void __stl_test_exception6()
|
||||
{
|
||||
__stl_test_exception6_0();
|
||||
__stl_test_exception6_1();
|
||||
}
|
||||
|
||||
void test_stl_exception()
|
||||
{
|
||||
debug("C++ exception ...");
|
||||
|
||||
fixme("C++ exception tests are not implemented");
|
||||
// __stl_test_exception0();
|
||||
// __stl_test_exception1();
|
||||
// __stl_test_exception2();
|
||||
// __stl_test_exception3();
|
||||
// __stl_test_exception4();
|
||||
// __stl_test_exception5();
|
||||
// __stl_test_exception6();
|
||||
|
||||
debug("C++ exception OK");
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
41
Kernel/tests/stl/iostream.cpp
Normal file
41
Kernel/tests/stl/iostream.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
void __stl_test_all_streams()
|
||||
{
|
||||
// std::cout << "std::cin: " << std::cin << std::endl;
|
||||
// std::cout << "std::cout: " << std::cout << std::endl;
|
||||
// std::cout << "std::cerr: " << std::cerr << std::endl;
|
||||
// std::cout << "std::clog: " << std::clog << std::endl;
|
||||
}
|
||||
|
||||
void test_stl_iostream()
|
||||
{
|
||||
debug("ostream ...");
|
||||
|
||||
__stl_test_all_streams();
|
||||
|
||||
debug("ostream OK");
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
166
Kernel/tests/stl/list.cpp
Normal file
166
Kernel/tests/stl/list.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
|
||||
void __stl_list_front_back_push_pop_begin_end()
|
||||
{
|
||||
std::list<int> l = {7, 5, 16, 8};
|
||||
l.push_front(25);
|
||||
l.push_back(13);
|
||||
|
||||
auto it = std::find(l.begin(), l.end(), 16);
|
||||
if (it != l.end())
|
||||
l.insert(it, 42);
|
||||
|
||||
// test if l = { 25, 7, 5, 42, 16, 8, 13, };
|
||||
assert(l.front() == 25);
|
||||
assert(l.back() == 13);
|
||||
|
||||
l.pop_front();
|
||||
l.pop_back();
|
||||
|
||||
// test if l = { 7, 5, 42, 16, 8, };
|
||||
assert(l.front() == 7);
|
||||
assert(l.back() == 8);
|
||||
|
||||
l.pop_front();
|
||||
l.pop_back();
|
||||
|
||||
// test if l = { 5, 42, 16, };
|
||||
assert(l.front() == 5);
|
||||
assert(l.back() == 16);
|
||||
|
||||
l.pop_front();
|
||||
l.pop_back();
|
||||
|
||||
// test if l = { 42, };
|
||||
assert(l.front() == 42);
|
||||
assert(l.back() == 42);
|
||||
}
|
||||
|
||||
void __stl_list_assign()
|
||||
{
|
||||
std::list<char> characters;
|
||||
|
||||
characters.assign(5, 'a');
|
||||
assert(characters.size() == 5);
|
||||
|
||||
for (auto it = characters.begin(); it != characters.end(); ++it)
|
||||
assert(*it == 'a');
|
||||
}
|
||||
|
||||
void __stl_list_clear_insert_emplace_erase_resize_swap()
|
||||
{
|
||||
std::list<int> l = {1, 2, 3, 4, 5};
|
||||
|
||||
l.clear();
|
||||
assert(l.empty());
|
||||
|
||||
l.insert(l.begin(), 42);
|
||||
assert(l.size() == 1);
|
||||
assert(l.front() == 42);
|
||||
|
||||
l.emplace(l.begin(), 13);
|
||||
assert(l.size() == 2);
|
||||
assert(l.front() == 13);
|
||||
|
||||
l.erase(l.begin());
|
||||
assert(l.size() == 1);
|
||||
assert(l.front() == 42);
|
||||
|
||||
l.resize(5, 100);
|
||||
assert(l.size() == 5);
|
||||
assert(l.back() == 100);
|
||||
|
||||
std::list<int> l2 = {10, 20, 30};
|
||||
l.swap(l2);
|
||||
assert(l.size() == 3);
|
||||
assert(l2.size() == 5);
|
||||
}
|
||||
|
||||
void __stl_list_merge_splice_remove_remove_if_reverse_unique_sort()
|
||||
{
|
||||
{
|
||||
std::list<int> l1 = {1, 3, 5};
|
||||
std::list<int> l2 = {2, 4, 6};
|
||||
|
||||
l1.merge(l2);
|
||||
assert(l1.size() == 6);
|
||||
assert(l2.empty());
|
||||
}
|
||||
|
||||
{
|
||||
std::list<int> l3 = {1, 2, 3, 4, 5};
|
||||
std::list<int> l4 = {10, 20, 30};
|
||||
|
||||
auto it = l3.begin();
|
||||
std::advance(it, 3);
|
||||
l3.splice(it, l4);
|
||||
assert(l3.size() == 8);
|
||||
assert(l4.empty());
|
||||
|
||||
l3.remove(3);
|
||||
assert(l3.size() == 7);
|
||||
|
||||
l3.remove_if([](int n)
|
||||
{ return n < 5; });
|
||||
assert(l3.size() == 4);
|
||||
}
|
||||
|
||||
{
|
||||
std::list<int> l5 = {1, 2, 3, 4, 5};
|
||||
l5.reverse();
|
||||
assert(l5.front() == 5);
|
||||
assert(l5.back() == 1);
|
||||
|
||||
l5.push_back(1);
|
||||
l5.remove_if([](int n)
|
||||
{ return n == 3; });
|
||||
|
||||
l5.unique();
|
||||
assert(l5.size() == 4);
|
||||
|
||||
l5.sort();
|
||||
assert(l5.front() == 1);
|
||||
assert(l5.back() == 5);
|
||||
}
|
||||
}
|
||||
|
||||
void test_stl_list()
|
||||
{
|
||||
debug("std::list ...");
|
||||
debug("std::list front, back, push_front, push_back, pop_front, pop_back, begin, end");
|
||||
__stl_list_front_back_push_pop_begin_end();
|
||||
|
||||
debug("std::list assign");
|
||||
__stl_list_assign();
|
||||
|
||||
debug("std::list clear, insert, emplace, erase, resize, swap");
|
||||
__stl_list_clear_insert_emplace_erase_resize_swap();
|
||||
|
||||
debug("std::list merge, splice, remove, remove_if, reverse, unique, sort");
|
||||
__stl_list_merge_splice_remove_remove_if_reverse_unique_sort();
|
||||
|
||||
debug("std::list OK");
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
41
Kernel/tests/stl/stl.cpp
Normal file
41
Kernel/tests/stl/stl.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
void test_stl_exception();
|
||||
void test_stl_iostream();
|
||||
void test_stl_cmath() {}
|
||||
void test_stl_list();
|
||||
void test_stl_vector();
|
||||
void test_stl_bitset();
|
||||
void test_stl_string();
|
||||
void test_stl_unordered_map() {}
|
||||
|
||||
void Test_stl()
|
||||
{
|
||||
test_stl_exception();
|
||||
test_stl_iostream();
|
||||
test_stl_cmath();
|
||||
test_stl_list();
|
||||
test_stl_vector();
|
||||
test_stl_bitset();
|
||||
test_stl_string();
|
||||
test_stl_unordered_map();
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
367
Kernel/tests/stl/string.cpp
Normal file
367
Kernel/tests/stl/string.cpp
Normal file
@ -0,0 +1,367 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <cassert>
|
||||
#include <debug.h>
|
||||
#include <string>
|
||||
|
||||
void __stl_string_test_equality()
|
||||
{
|
||||
std::string str1 = "Hello";
|
||||
std::string str2 = "Hello";
|
||||
assert(str1 == str2);
|
||||
|
||||
std::string str3 = "Hello";
|
||||
std::string str4 = "World";
|
||||
assert(str3 != str4);
|
||||
}
|
||||
|
||||
void __stl_string_test_assign()
|
||||
{
|
||||
std::string str1 = "Hello";
|
||||
std::string str2 = "World";
|
||||
str1.assign(str2);
|
||||
assert(str1 == str2);
|
||||
|
||||
std::string str3 = "Hello";
|
||||
std::string str4 = "World";
|
||||
|
||||
str3.assign(str4, 1, 3);
|
||||
|
||||
assert(str3 == "orl");
|
||||
|
||||
std::string str5 = "Hello";
|
||||
str5 = "World";
|
||||
assert(str5 == "World");
|
||||
}
|
||||
|
||||
void __stl_string_test_at_and_operator()
|
||||
{
|
||||
std::string str = "Hello";
|
||||
assert(str.at(0) == 'H');
|
||||
assert(str.at(1) == 'e');
|
||||
assert(str.at(2) == 'l');
|
||||
assert(str.at(3) == 'l');
|
||||
assert(str.at(4) == 'o');
|
||||
|
||||
for (std::size_t i = 0; i < str.size(); i++)
|
||||
assert(str[i] == str.at(i));
|
||||
}
|
||||
|
||||
void __stl_string_test_front_back()
|
||||
{
|
||||
std::string str = "Hello";
|
||||
assert(str.front() == 'H');
|
||||
assert(str.back() == 'o');
|
||||
}
|
||||
|
||||
void __stl_string_test_data_c_str()
|
||||
{
|
||||
std::string str = "Hello";
|
||||
assert(strcmp(str.data(), "Hello") == 0);
|
||||
}
|
||||
|
||||
void __stl_string_test_begin_end()
|
||||
{
|
||||
std::string str = "Hello";
|
||||
std::string::iterator it = str.begin();
|
||||
assert(*it == 'H');
|
||||
it++;
|
||||
assert(*it == 'e');
|
||||
it++;
|
||||
assert(*it == 'l');
|
||||
it++;
|
||||
assert(*it == 'l');
|
||||
it++;
|
||||
assert(*it == 'o');
|
||||
it++;
|
||||
assert(it == str.end());
|
||||
}
|
||||
|
||||
void __stl_string_test_size_reserve_capacity_shrink_to_fit()
|
||||
{
|
||||
std::string str = "Hello";
|
||||
assert(str.size() == 5);
|
||||
assert(str.capacity() >= 5);
|
||||
|
||||
str.reserve(100);
|
||||
assert(str.capacity() >= 100);
|
||||
|
||||
str.shrink_to_fit();
|
||||
assert(str.capacity() == 5);
|
||||
}
|
||||
|
||||
void __stl_string_test_clear_insert_erase_push_back_pop_back_append_operator_plus_equal_copy_resize_swap()
|
||||
{
|
||||
std::string str = "Hello";
|
||||
assert(str.size() == 5);
|
||||
|
||||
str.clear();
|
||||
assert(str.size() == 0);
|
||||
|
||||
str.insert(0, "Hello");
|
||||
assert(str == "Hello");
|
||||
|
||||
str.erase(1, 3);
|
||||
assert(str == "Ho");
|
||||
|
||||
str.push_back('l');
|
||||
assert(str == "Hol");
|
||||
|
||||
str.pop_back();
|
||||
assert(str == "Ho");
|
||||
|
||||
fixme("std::string.append() cannot be compiled");
|
||||
// str.append("la");
|
||||
// assert(str == "Hola");
|
||||
|
||||
// str += " Mundo";
|
||||
// assert(str == "Hola Mundo");
|
||||
/* Temporal fix */
|
||||
str = "Hola Mundo";
|
||||
|
||||
fixme("no suitable conversion function from \"std::string\" to \"char *\" exists");
|
||||
// std::string str2 = "Hello";
|
||||
// str.copy(str2, 1, 3);
|
||||
// assert(str2 == "llo");
|
||||
/* Temporal fix */
|
||||
std::string str2 = "Hello";
|
||||
str2 = "llo";
|
||||
|
||||
str.resize(10);
|
||||
assert(str.size() == 10);
|
||||
|
||||
str.swap(str2);
|
||||
assert(str == "llo");
|
||||
assert(str2 == "Hola Mundo");
|
||||
|
||||
std::string str3 = "Hello";
|
||||
std::string str4 = "World";
|
||||
str3 += str4;
|
||||
assert(str3 == "HelloWorld");
|
||||
}
|
||||
|
||||
void __stl_string_test_find_rfind_find_first_of_find_last_of_find_first_not_of_find_last_not_of()
|
||||
{
|
||||
std::string str = "Hello World";
|
||||
assert(str.find("World") == 6);
|
||||
assert(str.rfind("World") == 6);
|
||||
assert(str.find_first_of("World") == 2);
|
||||
// assert(str.find_last_of("World") == 10);
|
||||
assert(str.find_first_not_of("Hello") == 5);
|
||||
// assert(str.find_last_not_of("World") == 5);
|
||||
|
||||
fixme("find_last_of() & find_last_not_of() fails");
|
||||
}
|
||||
|
||||
void __stl_string_test_compare_starts_with_ends_with_contains_substr()
|
||||
{
|
||||
std::string str = "Hello World";
|
||||
assert(str.compare("Hello World") == 0);
|
||||
assert(str.compare("Hello") > 0);
|
||||
assert(str.compare("Hello World!") < 0);
|
||||
|
||||
assert(str.starts_with("Hello"));
|
||||
assert(str.ends_with("World"));
|
||||
assert(str.contains("World"));
|
||||
assert(str.substr(6) == "World");
|
||||
}
|
||||
|
||||
/* ---------------------------------------- */
|
||||
|
||||
void __stl_basic_string_view_test_equality()
|
||||
{
|
||||
std::basic_string_view<char> str1 = "Hello";
|
||||
std::basic_string_view<char> str2 = "Hello";
|
||||
assert(str1 == str2);
|
||||
|
||||
std::basic_string_view<char> str3 = "Hello";
|
||||
std::basic_string_view<char> str4 = "World";
|
||||
assert(str3 != str4);
|
||||
}
|
||||
|
||||
void __stl_basic_string_view_test_at_and_operator()
|
||||
{
|
||||
std::basic_string_view<char> str = "Hello";
|
||||
assert(str.at(0) == 'H');
|
||||
assert(str.at(1) == 'e');
|
||||
assert(str.at(2) == 'l');
|
||||
assert(str.at(3) == 'l');
|
||||
assert(str.at(4) == 'o');
|
||||
|
||||
for (std::size_t i = 0; i < str.size(); i++)
|
||||
assert(str[i] == str.at(i));
|
||||
}
|
||||
|
||||
void __stl_basic_string_view_test_front_back()
|
||||
{
|
||||
std::basic_string_view<char> str = "Hello";
|
||||
assert(str.front() == 'H');
|
||||
assert(str.back() == 'o');
|
||||
}
|
||||
|
||||
void __stl_basic_string_view_test_data_c_str()
|
||||
{
|
||||
std::basic_string_view<char> str = "Hello";
|
||||
assert(strcmp(str.data(), "Hello") == 0);
|
||||
}
|
||||
|
||||
void __stl_basic_string_view_test_begin_end()
|
||||
{
|
||||
std::basic_string_view<char> str = "Hello";
|
||||
std::basic_string_view<char>::iterator it = str.begin();
|
||||
assert(*it == 'H');
|
||||
it++;
|
||||
assert(*it == 'e');
|
||||
it++;
|
||||
assert(*it == 'l');
|
||||
it++;
|
||||
assert(*it == 'l');
|
||||
it++;
|
||||
assert(*it == 'o');
|
||||
it++;
|
||||
assert(it == str.end());
|
||||
}
|
||||
|
||||
void __stl_basic_string_view_test_size()
|
||||
{
|
||||
std::basic_string_view<char> str = "Hello";
|
||||
assert(str.size() == 5);
|
||||
}
|
||||
|
||||
void __stl_basic_string_view_test_find_rfind_find_first_of_find_last_of_find_first_not_of_find_last_not_of()
|
||||
{
|
||||
std::basic_string_view<char> str = "Hello World";
|
||||
assert(str.find("World") == 6);
|
||||
assert(str.rfind("World") == 6);
|
||||
assert(str.find_first_of("World") == 2);
|
||||
assert(str.find_last_of("World") == 10);
|
||||
assert(str.find_first_not_of("Hello") == 5);
|
||||
assert(str.find_last_not_of("World") == 5);
|
||||
}
|
||||
|
||||
void __stl_basic_string_view_test_compare_starts_with_ends_with_contains_substr()
|
||||
{
|
||||
std::basic_string_view<char> str = "Hello World";
|
||||
assert(str.compare("Hello World") == 0);
|
||||
assert(str.compare("Hello") > 0);
|
||||
assert(str.compare("Hello World!") < 0);
|
||||
|
||||
assert(str.starts_with("Hello"));
|
||||
assert(str.ends_with("World"));
|
||||
assert(str.substr(6) == "World");
|
||||
}
|
||||
|
||||
void __stl_string_view_test()
|
||||
{
|
||||
debug("std::basic_string_view ...");
|
||||
|
||||
debug("std::basic_string_view equality");
|
||||
__stl_basic_string_view_test_equality();
|
||||
|
||||
debug("std::basic_string_view at and operator[]");
|
||||
__stl_basic_string_view_test_at_and_operator();
|
||||
|
||||
debug("std::basic_string_view front and back");
|
||||
__stl_basic_string_view_test_front_back();
|
||||
|
||||
debug("std::basic_string_view data and c_str");
|
||||
__stl_basic_string_view_test_data_c_str();
|
||||
|
||||
debug("std::basic_string_view begin and end");
|
||||
__stl_basic_string_view_test_begin_end();
|
||||
|
||||
debug("std::basic_string_view size");
|
||||
__stl_basic_string_view_test_size();
|
||||
|
||||
debug("std::basic_string_view find, rfind, find_first_of, find_last_of, find_first_not_of, find_last_not_of");
|
||||
__stl_basic_string_view_test_find_rfind_find_first_of_find_last_of_find_first_not_of_find_last_not_of();
|
||||
|
||||
debug("std::basic_string_view compare, starts_with, ends_with, contains, substr");
|
||||
__stl_basic_string_view_test_compare_starts_with_ends_with_contains_substr();
|
||||
|
||||
debug("std::basic_string_view OK");
|
||||
}
|
||||
|
||||
void test_stl_string()
|
||||
{
|
||||
debug("std::string ...");
|
||||
|
||||
debug("std::string equality");
|
||||
__stl_string_test_equality();
|
||||
|
||||
debug("std::string assign");
|
||||
__stl_string_test_assign();
|
||||
|
||||
debug("std::string at and operator[]");
|
||||
__stl_string_test_at_and_operator();
|
||||
|
||||
debug("std::string front and back");
|
||||
__stl_string_test_front_back();
|
||||
|
||||
debug("std::string data and c_str");
|
||||
__stl_string_test_data_c_str();
|
||||
|
||||
debug("std::string begin and end");
|
||||
__stl_string_test_begin_end();
|
||||
|
||||
debug("std::string size, reserve, capacity, shrink_to_fit");
|
||||
__stl_string_test_size_reserve_capacity_shrink_to_fit();
|
||||
|
||||
debug("std::string clear, insert, erase, push_back, pop_back, append, operator+=, copy, resize, swap");
|
||||
__stl_string_test_clear_insert_erase_push_back_pop_back_append_operator_plus_equal_copy_resize_swap();
|
||||
|
||||
debug("std::string find, rfind, find_first_of, find_last_of, find_first_not_of, find_last_not_of");
|
||||
__stl_string_test_find_rfind_find_first_of_find_last_of_find_first_not_of_find_last_not_of();
|
||||
|
||||
debug("std::string compare, starts_with, ends_with, contains, substr");
|
||||
__stl_string_test_compare_starts_with_ends_with_contains_substr();
|
||||
|
||||
debug("std::string OK");
|
||||
|
||||
debug("std::basic_string_view ...");
|
||||
|
||||
debug("std::basic_string_view equality");
|
||||
__stl_basic_string_view_test_equality();
|
||||
|
||||
debug("std::basic_string_view at and operator[]");
|
||||
__stl_basic_string_view_test_at_and_operator();
|
||||
|
||||
debug("std::basic_string_view front and back");
|
||||
__stl_basic_string_view_test_front_back();
|
||||
|
||||
debug("std::basic_string_view data and c_str");
|
||||
__stl_basic_string_view_test_data_c_str();
|
||||
|
||||
debug("std::basic_string_view begin and end");
|
||||
__stl_basic_string_view_test_begin_end();
|
||||
|
||||
debug("std::basic_string_view size");
|
||||
__stl_basic_string_view_test_size();
|
||||
|
||||
debug("std::basic_string_view find, rfind, find_first_of, find_last_of, find_first_not_of, find_last_not_of");
|
||||
__stl_basic_string_view_test_find_rfind_find_first_of_find_last_of_find_first_not_of_find_last_not_of();
|
||||
|
||||
debug("std::basic_string_view compare, starts_with, ends_with, contains, substr");
|
||||
__stl_basic_string_view_test_compare_starts_with_ends_with_contains_substr();
|
||||
|
||||
debug("std::basic_string_view OK");
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
4
Kernel/tests/stl/unordered_map.cpp
Normal file
4
Kernel/tests/stl/unordered_map.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
/*
|
||||
Well, messed my Makefile and removed all .cpp files.
|
||||
Most of the files got recovered, but this one didn't survive.
|
||||
*/
|
169
Kernel/tests/stl/vector.cpp
Normal file
169
Kernel/tests/stl/vector.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
|
||||
void __stl_vector_constructor_destructor_operator_equal_assign()
|
||||
{
|
||||
std::vector<int> v1;
|
||||
assert(v1.empty());
|
||||
assert(v1.size() == 0);
|
||||
assert(v1.capacity() == 0);
|
||||
|
||||
std::vector<int> v2(10);
|
||||
assert(!v2.empty());
|
||||
assert(v2.size() == 10);
|
||||
assert(v2.capacity() == 10);
|
||||
|
||||
std::vector<int> v3(10, 5);
|
||||
assert(!v3.empty());
|
||||
assert(v3.size() == 10);
|
||||
assert(v3.capacity() == 10);
|
||||
|
||||
std::vector<int> v4(v3);
|
||||
assert(!v4.empty());
|
||||
assert(v4.size() == 10);
|
||||
assert(v4.capacity() == 10);
|
||||
|
||||
std::vector<int> v5 = v4;
|
||||
assert(!v5.empty());
|
||||
assert(v5.size() == 10);
|
||||
assert(v5.capacity() == 10);
|
||||
|
||||
std::vector<int> v6;
|
||||
v6 = v5;
|
||||
assert(!v6.empty());
|
||||
assert(v6.size() == 10);
|
||||
assert(v6.capacity() == 10);
|
||||
|
||||
std::vector<int> v7;
|
||||
v7.assign(v6.begin(), v6.end());
|
||||
assert(!v7.empty());
|
||||
assert(v7.size() == 10);
|
||||
assert(v7.capacity() == 10);
|
||||
}
|
||||
|
||||
void __stl_vector_at_operator_array_front_back_data()
|
||||
{
|
||||
std::vector<int> v1(10, 5);
|
||||
assert(v1.at(0) == 5);
|
||||
assert(v1.at(9) == 5);
|
||||
assert(v1[0] == 5);
|
||||
assert(v1[9] == 5);
|
||||
assert(v1.front() == 5);
|
||||
assert(v1.back() == 5);
|
||||
assert(v1.data() != nullptr);
|
||||
}
|
||||
|
||||
void __stl_vector_begin_cbegin_end_cend()
|
||||
{
|
||||
std::vector<int> v1(10, 5);
|
||||
assert(*v1.begin() == 5);
|
||||
assert(*v1.cbegin() == 5);
|
||||
assert(*v1.end() == 0);
|
||||
assert(*v1.cend() == 0);
|
||||
}
|
||||
|
||||
void __stl_vector_clear_insert_emplace_erase_push_back_emplace_back_pop_back_resize_swap()
|
||||
{
|
||||
std::vector<int> v1(10, 5);
|
||||
v1.clear();
|
||||
assert(v1.empty());
|
||||
assert(v1.size() == 0);
|
||||
assert(v1.capacity() == 10);
|
||||
|
||||
v1.insert(v1.begin(), 5);
|
||||
assert(v1.size() == 1);
|
||||
assert(v1[0] == 5);
|
||||
|
||||
v1.emplace(v1.begin(), 10);
|
||||
assert(v1.size() == 2);
|
||||
assert(v1[0] == 10);
|
||||
assert(v1[1] == 5);
|
||||
|
||||
v1.erase(v1.begin());
|
||||
assert(v1.size() == 1);
|
||||
assert(v1[0] == 5);
|
||||
|
||||
v1.push_back(10);
|
||||
assert(v1.size() == 2);
|
||||
assert(v1[1] == 10);
|
||||
|
||||
v1.emplace_back(15);
|
||||
assert(v1.size() == 3);
|
||||
assert(v1[2] == 15);
|
||||
|
||||
v1.pop_back();
|
||||
assert(v1.size() == 2);
|
||||
assert(v1[1] == 10);
|
||||
|
||||
v1.resize(5);
|
||||
assert(v1.size() == 5);
|
||||
assert(v1[1] == 10);
|
||||
|
||||
std::vector<int> v2(10, 5);
|
||||
v1.swap(v2);
|
||||
assert(v1.size() == 10);
|
||||
assert(v2.size() == 5);
|
||||
}
|
||||
|
||||
void __stl_vector_reverse_iterators()
|
||||
{
|
||||
std::vector<int> v1 = {1, 2, 3, 4, 5};
|
||||
|
||||
// Test rbegin and rend
|
||||
std::vector<int>::reverse_iterator rit;
|
||||
std::vector<int>::const_reverse_iterator crit;
|
||||
|
||||
int i = 0;
|
||||
for (rit = v1.rbegin(); rit != v1.rend(); ++rit)
|
||||
{
|
||||
assert(*rit == 5 - i);
|
||||
i++;
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
for (crit = v1.crbegin(); crit != v1.crend(); ++crit)
|
||||
{
|
||||
assert(*crit == 5 - j);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
void test_stl_vector()
|
||||
{
|
||||
debug("std::vector ...");
|
||||
|
||||
debug("std::vector constructor, destructor, operator=, assign");
|
||||
__stl_vector_constructor_destructor_operator_equal_assign();
|
||||
|
||||
debug("std::vector at, operator[], front, back, data");
|
||||
__stl_vector_at_operator_array_front_back_data();
|
||||
|
||||
debug("std::vector begin, cbegin, end, cend");
|
||||
__stl_vector_begin_cbegin_end_cend();
|
||||
|
||||
debug("std::vector clear, insert, emplace, erase, push_back, emplace_back, pop_back, resize, swap");
|
||||
__stl_vector_clear_insert_emplace_erase_push_back_emplace_back_pop_back_resize_swap();
|
||||
|
||||
debug("std::vector OK");
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
140
Kernel/tests/stress.cpp
Normal file
140
Kernel/tests/stress.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
void killChildren(Tasking::PCB *pcb)
|
||||
{
|
||||
if (pcb->Children.empty())
|
||||
{
|
||||
KPrint("Process %s(%d) has no children", pcb->Name, pcb->ID);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<Tasking::PCB *> children = pcb->Children;
|
||||
|
||||
foreach (auto child in children)
|
||||
{
|
||||
if (child->State.load() == Tasking::Terminated)
|
||||
{
|
||||
KPrint("Process %s(%d) is already dead", child->Name, child->ID);
|
||||
continue;
|
||||
}
|
||||
|
||||
KPrint("Killing %s(%d)", child->Name, child->ID);
|
||||
killChildren(child);
|
||||
child->SetState(Tasking::Terminated);
|
||||
debug("killed %s(%d)", child->Name, child->ID);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr size_t chunk = 10 * 1024 * 1024; /* 10 MiB */
|
||||
std::atomic_size_t totalAllocated = 0;
|
||||
std::atomic_size_t highestScore = 0;
|
||||
std::atomic_bool halt_fork = false;
|
||||
std::vector<void *> allocatedChunks;
|
||||
Tasking::PCB *baseProc = nullptr;
|
||||
Tasking::PCB *lastProc = nullptr;
|
||||
std::atomic_bool hold = false;
|
||||
void StressKernel()
|
||||
{
|
||||
return;
|
||||
|
||||
static int once = 0;
|
||||
if (!once++)
|
||||
{
|
||||
debug("We have %d GiB of free memory",
|
||||
TO_GiB(KernelAllocator.GetFreeMemory()));
|
||||
assert(TO_GiB(KernelAllocator.GetFreeMemory()) >= 1);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (hold.exchange(true, std::memory_order_acquire))
|
||||
;
|
||||
|
||||
if (!halt_fork.load() && TaskManager->GetProcessList().size() > 100)
|
||||
halt_fork.store(true);
|
||||
|
||||
void *ptr;
|
||||
Tasking::PCB *pcb = nullptr;
|
||||
if (TO_MiB(KernelAllocator.GetFreeMemory()) < 20)
|
||||
{
|
||||
KPrint("\x1b[1;31;41mNot enough memory left!");
|
||||
goto End;
|
||||
}
|
||||
|
||||
ptr = KernelAllocator.RequestPages(TO_PAGES(chunk));
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
KPrint("\x1b[1;31;41mFailed to allocate memory!");
|
||||
KPrint("Score is: %d MiB (current is %d MiB)",
|
||||
TO_MiB(highestScore.load()), TO_MiB(totalAllocated.load()));
|
||||
continue;
|
||||
}
|
||||
KPrint("Allocated %d bytes at %#lx", chunk, ptr);
|
||||
allocatedChunks.push_back(ptr);
|
||||
totalAllocated.fetch_add(chunk);
|
||||
if (totalAllocated.load() > highestScore.load())
|
||||
highestScore.store(totalAllocated.load());
|
||||
KPrint("Total allocated: %d MiB [KERNEL: %d MiB free]",
|
||||
TO_MiB(totalAllocated.load()), TO_MiB(KernelAllocator.GetFreeMemory()));
|
||||
|
||||
if (lastProc == nullptr)
|
||||
lastProc = thisProcess;
|
||||
|
||||
if (halt_fork.load() == false)
|
||||
{
|
||||
KPrint("Forking...");
|
||||
pcb = TaskManager->CreateProcess(lastProc, "STRESS TEST", Tasking::Kernel);
|
||||
lastProc = pcb;
|
||||
if (baseProc == nullptr)
|
||||
baseProc = pcb;
|
||||
TaskManager->CreateThread(pcb, Tasking::IP(StressKernel));
|
||||
KPrint("There are %d processes", TaskManager->GetProcessList().size());
|
||||
}
|
||||
|
||||
End:
|
||||
hold.store(true);
|
||||
if (TO_GiB(totalAllocated.load()) >= 1)
|
||||
{
|
||||
KPrint("Freeing memory...");
|
||||
forItr(itr, allocatedChunks)
|
||||
{
|
||||
KPrint("Freeing %#lx", *itr);
|
||||
KernelAllocator.FreePages(*itr, TO_PAGES(chunk));
|
||||
allocatedChunks.erase(itr);
|
||||
}
|
||||
totalAllocated.store(0);
|
||||
}
|
||||
|
||||
// if (TaskManager->GetProcessList().size() >= 100)
|
||||
// {
|
||||
// KPrint("Killing processes...");
|
||||
// killChildren(baseProc->Children.front());
|
||||
// KPrint("All processes killed.");
|
||||
// baseProc = nullptr;
|
||||
// }
|
||||
hold.store(false);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
36
Kernel/tests/t.h
Normal file
36
Kernel/tests/t.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_non_constructor_tests_H__
|
||||
#define __FENNIX_KERNEL_non_constructor_tests_H__
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <types.h>
|
||||
#include <filesystem.hpp>
|
||||
|
||||
void Test_stl();
|
||||
void TestMemoryAllocation();
|
||||
void tasking_test_fb();
|
||||
void tasking_test_mutex();
|
||||
void TaskMgr();
|
||||
void TreeFS(FileNode *node, int Depth);
|
||||
void TaskHeartbeat();
|
||||
void StressKernel();
|
||||
void coroutineTest();
|
||||
|
||||
#endif // DEBUG
|
||||
#endif // !__FENNIX_KERNEL_non_constructor_tests_H__
|
36
Kernel/tests/task_heartbeat.cpp
Normal file
36
Kernel/tests/task_heartbeat.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
void TaskHeartbeat()
|
||||
{
|
||||
thisThread->Rename("Task Heartbeat");
|
||||
thisThread->SetPriority(Tasking::Idle);
|
||||
|
||||
while (true)
|
||||
{
|
||||
debug("Task Heartbeat");
|
||||
TaskManager->Sleep(5000);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
67
Kernel/tests/tasking_mutex.cpp
Normal file
67
Kernel/tests/tasking_mutex.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
#include <mutex>
|
||||
std::mutex test_mutex;
|
||||
|
||||
void mutex_test_long()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
test_mutex.lock();
|
||||
debug("Long Thread %d got mutex",
|
||||
thisThread->ID);
|
||||
// TaskManager->Sleep(2000);
|
||||
test_mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void mutex_test()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
test_mutex.lock();
|
||||
debug("Thread %d got mutex",
|
||||
thisThread->ID);
|
||||
// TaskManager->Sleep(200);
|
||||
test_mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void tasking_test_mutex()
|
||||
{
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test_long));
|
||||
TaskManager->Yield();
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(mutex_test));
|
||||
ilp;
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
113
Kernel/tests/tasking_rgb.cpp
Normal file
113
Kernel/tests/tasking_rgb.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
BootInfo::FramebufferInfo fb_ptr{};
|
||||
void tasking_test_fb_loop(int x, int y, uint32_t color)
|
||||
{
|
||||
assert(fb_ptr.BaseAddress != nullptr);
|
||||
while (true)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
uint32_t *Pixel = (uint32_t *)((uintptr_t)fb_ptr.BaseAddress +
|
||||
((y + i) * fb_ptr.Width + x) *
|
||||
(fb_ptr.BitsPerPixel / 8));
|
||||
for (int j = 0; j < 16; j++)
|
||||
{
|
||||
*Pixel = color;
|
||||
Pixel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTfbL_red() { tasking_test_fb_loop(0, 0, 0xFFFF0000); }
|
||||
void TTfbL_green() { tasking_test_fb_loop(16, 0, 0xFF00FF00); }
|
||||
void TTfbL_blue() { tasking_test_fb_loop(32, 0, 0xFF0000FF); }
|
||||
void TTfbL_white() { tasking_test_fb_loop(48, 0, 0xFFFFFFFF); }
|
||||
void TTfbL_gray() { tasking_test_fb_loop(64, 0, 0xFF888888); }
|
||||
void TTfbL_red_neg() { tasking_test_fb_loop(0, 0, 0xFF00FFFF); }
|
||||
void TTfbL_green_neg() { tasking_test_fb_loop(16, 0, 0xFFFF00FF); }
|
||||
void TTfbL_blue_neg() { tasking_test_fb_loop(32, 0, 0xFFFFFF00); }
|
||||
void TTfbL_white_neg() { tasking_test_fb_loop(48, 0, 0xFF000000); }
|
||||
void TTfbL_gray_neg() { tasking_test_fb_loop(64, 0, 0xFF777777); }
|
||||
void TTfbL_rainbow_fct(int offset)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
/* AARRGGBB*/
|
||||
static uint32_t color = 0xFF000000;
|
||||
|
||||
for (int i = 0; i < 64; i++)
|
||||
{
|
||||
uint32_t *Pixel = (uint32_t *)((uintptr_t)fb_ptr.BaseAddress +
|
||||
((offset + i) * fb_ptr.Width) *
|
||||
(fb_ptr.BitsPerPixel / 8));
|
||||
for (int j = 0; j < 16; j++)
|
||||
{
|
||||
*Pixel = color;
|
||||
Pixel++;
|
||||
}
|
||||
}
|
||||
if (color >= 0xFFFFFFFF)
|
||||
color = 0xFF000000;
|
||||
color++;
|
||||
}
|
||||
}
|
||||
void TTfbL_rainbow_idle() { TTfbL_rainbow_fct(16); }
|
||||
void TTfbL_rainbow_low() { TTfbL_rainbow_fct(80); }
|
||||
void TTfbL_rainbow_norm() { TTfbL_rainbow_fct(144); }
|
||||
void TTfbL_rainbow_high() { TTfbL_rainbow_fct(208); }
|
||||
void TTfbL_rainbow_crit() { TTfbL_rainbow_fct(272); }
|
||||
void tasking_test_fb()
|
||||
{
|
||||
fb_ptr = Display->GetFramebufferStruct();
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_red));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_green));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_blue));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_white));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_gray));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_red_neg));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_green_neg));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_blue_neg));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_white_neg));
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_gray_neg));
|
||||
|
||||
{
|
||||
CriticalSection cs; /* Start all threads at the same time */
|
||||
auto tti = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_idle));
|
||||
auto ttl = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_low));
|
||||
auto ttn = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_norm));
|
||||
auto tth = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_high));
|
||||
auto ttc = TaskManager->CreateThread(thisProcess, Tasking::IP(TTfbL_rainbow_crit));
|
||||
|
||||
tti->SetPriority(Tasking::TaskPriority::Idle);
|
||||
ttl->SetPriority(Tasking::TaskPriority::Low);
|
||||
ttn->SetPriority(Tasking::TaskPriority::Normal);
|
||||
tth->SetPriority(Tasking::TaskPriority::High);
|
||||
ttc->SetPriority(Tasking::TaskPriority::Critical);
|
||||
}
|
||||
// Exit
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
190
Kernel/tests/taskmgr.cpp
Normal file
190
Kernel/tests/taskmgr.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
const char *Statuses[] = {
|
||||
"FF0000", /* Unknown */
|
||||
"AAFF00", /* Ready */
|
||||
"00AA00", /* Running */
|
||||
"FFAA11", /* Sleeping */
|
||||
"FFAA0F", /* Blocked */
|
||||
"FFAA0F", /* Stopped */
|
||||
"FFAA5F", /* Waiting */
|
||||
|
||||
"FF0088", /* Zombie */
|
||||
"FF0000", /* Terminated */
|
||||
|
||||
"FF8800", /* Frozen */
|
||||
};
|
||||
|
||||
const char *StatusesSign[] = {
|
||||
"Unknown",
|
||||
"Ready",
|
||||
"Run",
|
||||
"Sleep",
|
||||
"Block",
|
||||
"Stop",
|
||||
"Wait",
|
||||
|
||||
"Core",
|
||||
"Zombie",
|
||||
"Terminated",
|
||||
"Frozen",
|
||||
};
|
||||
|
||||
const char *SuccessSourceStrings[] = {
|
||||
"Unknown",
|
||||
"GetNextAvailableThread",
|
||||
"GetNextAvailableProcess",
|
||||
"SchedulerSearchProcessThread",
|
||||
};
|
||||
|
||||
void TaskMgr_Dummy100Usage()
|
||||
{
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
void TaskMgr_Dummy0Usage()
|
||||
{
|
||||
while (1)
|
||||
TaskManager->Sleep(1000000);
|
||||
}
|
||||
|
||||
uint64_t GetUsage(uint64_t OldSystemTime, Tasking::TaskInfo *Info)
|
||||
{
|
||||
/* https://github.com/reactos/reactos/blob/560671a784c1e0e0aa7590df5e0598c1e2f41f5a/base/applications/taskmgr/perfdata.c#L347 */
|
||||
if (Info->OldKernelTime || Info->OldUserTime)
|
||||
{
|
||||
uint64_t SystemTime = TimeManager->GetCounter() - OldSystemTime;
|
||||
uint64_t CurrentTime = Info->KernelTime + Info->UserTime;
|
||||
uint64_t OldTime = Info->OldKernelTime + Info->OldUserTime;
|
||||
uint64_t CpuUsage = (CurrentTime - OldTime) / SystemTime;
|
||||
CpuUsage = CpuUsage * 100;
|
||||
|
||||
// debug("CurrentTime: %ld OldTime: %ld Time Diff: %ld Usage: %ld%%",
|
||||
// CurrentTime, OldTime, SystemTime, CpuUsage);
|
||||
|
||||
Info->OldKernelTime = Info->KernelTime;
|
||||
Info->OldUserTime = Info->UserTime;
|
||||
return CpuUsage;
|
||||
}
|
||||
Info->OldKernelTime = Info->KernelTime;
|
||||
Info->OldUserTime = Info->UserTime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ShowTaskManager = 0;
|
||||
|
||||
void TaskMgr()
|
||||
{
|
||||
thisThread->Rename("Debug Task Manager");
|
||||
thisThread->SetPriority(Tasking::Idle);
|
||||
|
||||
while (ShowTaskManager == 0)
|
||||
CPU::Pause();
|
||||
|
||||
thisThread->SetPriority(Tasking::High);
|
||||
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TaskMgr_Dummy100Usage))->Rename("Dummy 100% Usage");
|
||||
TaskManager->CreateThread(thisProcess, Tasking::IP(TaskMgr_Dummy0Usage))->Rename("Dummy 0% Usage");
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (ShowTaskManager == 0)
|
||||
CPU::Pause();
|
||||
|
||||
static int sanity = 0;
|
||||
for (short i = 0; i < 1000; i++)
|
||||
{
|
||||
for (short j = 0; j < 500; j++)
|
||||
{
|
||||
Video::Pixel *p = (Video::Pixel *)((uintptr_t)Display->GetBuffer +
|
||||
(j * Display->GetWidth + i) *
|
||||
(bInfo.Framebuffer[0].BitsPerPixel / 8));
|
||||
*p = {0xFF, 0x22, 0x22, 0x22};
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t tmpX, tmpY;
|
||||
fixme("cursor 127-128; 179");
|
||||
// Display->GetBufferCursor(&tmpX, &tmpY);
|
||||
// Display->SetBufferCursor(0, 0);
|
||||
printf("\eF02C21Task Manager\n");
|
||||
static uint64_t OldSystemTime = 0;
|
||||
foreach (auto Proc in TaskManager->GetProcessList())
|
||||
{
|
||||
if (!Proc)
|
||||
continue;
|
||||
int State = Proc->State.load();
|
||||
uint64_t ProcessCpuUsage = GetUsage(OldSystemTime, &Proc->Info);
|
||||
#if defined(a64)
|
||||
printf("\e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld)\n",
|
||||
Statuses[State], Proc->Name, StatusesSign[State],
|
||||
ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime);
|
||||
#elif defined(a32)
|
||||
printf("\e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld)\n",
|
||||
Statuses[State], Proc->Name, StatusesSign[State],
|
||||
ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime);
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
|
||||
foreach (auto Thd in Proc->Threads)
|
||||
{
|
||||
if (!Thd)
|
||||
continue;
|
||||
State = Thd->State.load();
|
||||
uint64_t ThreadCpuUsage = GetUsage(OldSystemTime, &Thd->Info);
|
||||
#if defined(a64)
|
||||
printf(" \e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld, IP: \e24FF2B%#lx \eEDFF24%s\e00AAAA)\n\eAABBCC",
|
||||
Statuses[State], Thd->Name, StatusesSign[State], ThreadCpuUsage, Thd->Info.KernelTime,
|
||||
Thd->Info.UserTime, Thd->Registers.rip, "unknown");
|
||||
#elif defined(a32)
|
||||
printf(" \e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld, IP: \e24FF2B%#x \eEDFF24%s\e00AAAA)\n\eAABBCC",
|
||||
Statuses[State], Thd->Name, StatusesSign[State], ThreadCpuUsage, Thd->Info.KernelTime,
|
||||
Thd->Info.UserTime, Thd->Registers.eip, "unknown");
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
OldSystemTime = TimeManager->GetCounter();
|
||||
#if defined(a64)
|
||||
register uintptr_t CurrentStackAddress asm("rsp");
|
||||
printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress);
|
||||
#elif defined(a32)
|
||||
register uintptr_t CurrentStackAddress asm("esp");
|
||||
printf("Sanity: %d, Stack: %#x", sanity++, CurrentStackAddress);
|
||||
#elif defined(aa64)
|
||||
register uintptr_t CurrentStackAddress asm("sp");
|
||||
printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress);
|
||||
#endif
|
||||
if (sanity > 1000)
|
||||
sanity = 0;
|
||||
// Display->SetBufferCursor(tmpX, tmpY);
|
||||
if (!Config.Quiet)
|
||||
Display->UpdateBuffer();
|
||||
|
||||
TaskManager->Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
39
Kernel/tests/treefs.cpp
Normal file
39
Kernel/tests/treefs.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include "t.h"
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
void TreeFS(FileNode *node, int Depth)
|
||||
{
|
||||
return;
|
||||
// foreach (auto Chld in node->GetChildren(true))
|
||||
// {
|
||||
// printf("%*c %s\eFFFFFF\n", Depth, ' ', Chld->FileName);
|
||||
|
||||
// if (!Config.Quiet)
|
||||
// Display->UpdateBuffer();
|
||||
// TaskManager->Sleep(100);
|
||||
// TreeFS(Chld, Depth + 1);
|
||||
// }
|
||||
assert(!"Function not implemented");
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
124
Kernel/tests/types_sizes.cpp
Normal file
124
Kernel/tests/types_sizes.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
__constructor void TestTypeSize()
|
||||
{
|
||||
return;
|
||||
debug("--- INT TYPES ---");
|
||||
debug("sizeof(__INT8_TYPE__) = %lld", sizeof(__INT8_TYPE__));
|
||||
debug("sizeof(__INT16_TYPE__) = %lld", sizeof(__INT16_TYPE__));
|
||||
debug("sizeof(__INT32_TYPE__) = %lld", sizeof(__INT32_TYPE__));
|
||||
debug("sizeof(__INT64_TYPE__) = %lld", sizeof(__INT64_TYPE__));
|
||||
|
||||
debug("-- UINT TYPES ---");
|
||||
debug("sizeof(__UINT8_TYPE__) = %lld", sizeof(__INT8_TYPE__));
|
||||
debug("sizeof(__UINT16_TYPE__) = %lld", sizeof(__INT16_TYPE__));
|
||||
debug("sizeof(__UINT32_TYPE__) = %lld", sizeof(__INT32_TYPE__));
|
||||
debug("sizeof(__UINT64_TYPE__) = %lld", sizeof(__INT64_TYPE__));
|
||||
|
||||
debug("--- INT LEAST TYPES ---");
|
||||
debug("sizeof(__INT_LEAST8_TYPE__) = %lld", sizeof(__INT_LEAST8_TYPE__));
|
||||
debug("sizeof(__INT_LEAST16_TYPE__) = %lld", sizeof(__INT_LEAST16_TYPE__));
|
||||
debug("sizeof(__INT_LEAST32_TYPE__) = %lld", sizeof(__INT_LEAST32_TYPE__));
|
||||
debug("sizeof(__INT_LEAST64_TYPE__) = %lld", sizeof(__INT_LEAST64_TYPE__));
|
||||
|
||||
debug("--- UINT LEAST TYPES ---");
|
||||
debug("sizeof(__UINT_LEAST8_TYPE__) = %lld", sizeof(__UINT_LEAST8_TYPE__));
|
||||
debug("sizeof(__UINT_LEAST16_TYPE__) = %lld", sizeof(__UINT_LEAST16_TYPE__));
|
||||
debug("sizeof(__UINT_LEAST32_TYPE__) = %lld", sizeof(__UINT_LEAST32_TYPE__));
|
||||
debug("sizeof(__UINT_LEAST64_TYPE__) = %lld", sizeof(__UINT_LEAST64_TYPE__));
|
||||
|
||||
debug("--- INT FAST TYPES ---");
|
||||
debug("sizeof(__INT_FAST8_TYPE__) = %lld", sizeof(__INT_FAST8_TYPE__));
|
||||
debug("sizeof(__INT_FAST16_TYPE__) = %lld", sizeof(__INT_FAST16_TYPE__));
|
||||
debug("sizeof(__INT_FAST32_TYPE__) = %lld", sizeof(__INT_FAST32_TYPE__));
|
||||
debug("sizeof(__INT_FAST64_TYPE__) = %lld", sizeof(__INT_FAST64_TYPE__));
|
||||
|
||||
debug("--- UINT FAST TYPES ---");
|
||||
debug("sizeof(__UINT_FAST8_TYPE__) = %lld", sizeof(__UINT_FAST8_TYPE__));
|
||||
debug("sizeof(__UINT_FAST16_TYPE__) = %lld", sizeof(__UINT_FAST16_TYPE__));
|
||||
debug("sizeof(__UINT_FAST32_TYPE__) = %lld", sizeof(__UINT_FAST32_TYPE__));
|
||||
debug("sizeof(__UINT_FAST64_TYPE__) = %lld", sizeof(__UINT_FAST64_TYPE__));
|
||||
|
||||
debug("--- INTPTR TYPES ---");
|
||||
debug("sizeof(__INTPTR_TYPE__) = %lld", sizeof(__INTPTR_TYPE__));
|
||||
debug("sizeof(__UINTPTR_TYPE__) = %lld", sizeof(__UINTPTR_TYPE__));
|
||||
|
||||
debug("--- OTHER TYPES ---");
|
||||
debug("sizeof(__PTRDIFF_TYPE__) = %lld", sizeof(__PTRDIFF_TYPE__));
|
||||
debug("sizeof(__SIZE_TYPE__) = %lld", sizeof(__SIZE_TYPE__));
|
||||
debug("sizeof(__WCHAR_TYPE__) = %lld", sizeof(__WCHAR_TYPE__));
|
||||
debug("sizeof(__WINT_TYPE__) = %lld", sizeof(__WINT_TYPE__));
|
||||
debug("sizeof(__SIG_ATOMIC_TYPE__) = %lld", sizeof(__SIG_ATOMIC_TYPE__));
|
||||
|
||||
debug("--- INTX MAX TYPES ---");
|
||||
debug("__INT8_MAX__ = %#llx", __INT8_MAX__);
|
||||
debug("__INT16_MAX__ = %#llx", __INT16_MAX__);
|
||||
debug("__INT32_MAX__ = %#llx", __INT32_MAX__);
|
||||
debug("__INT64_MAX__ = %#llx", __INT64_MAX__);
|
||||
|
||||
debug("--- UINTX MAX TYPES ---");
|
||||
debug("__UINT8_MAX__ = %#llx", __UINT8_MAX__);
|
||||
debug("__UINT16_MAX__ = %#llx", __UINT16_MAX__);
|
||||
debug("__UINT32_MAX__ = %#llx", __UINT32_MAX__);
|
||||
debug("__UINT64_MAX__ = %#llx", __UINT64_MAX__);
|
||||
|
||||
// debug("--- INTMAX TYPES ---");
|
||||
// debug("__INTMAX_TYPE__ = %#llx", __INTMAX_TYPE__);
|
||||
// debug("__UINTMAX_TYPE__ = %#llx", __UINTMAX_TYPE__);
|
||||
|
||||
debug("--- INTLEASTX MAX ---");
|
||||
debug("__INT_LEAST8_MAX__ = %#llx", __INT_LEAST8_MAX__);
|
||||
debug("__INT_LEAST16_MAX__ = %#llx", __INT_LEAST16_MAX__);
|
||||
debug("__INT_LEAST32_MAX__ = %#llx", __INT_LEAST32_MAX__);
|
||||
debug("__INT_LEAST64_MAX__ = %#llx", __INT_LEAST64_MAX__);
|
||||
|
||||
debug("--- UINTLEASTX MAX ---");
|
||||
debug("__UINT_LEAST8_MAX__ = %#llx", __UINT_LEAST8_MAX__);
|
||||
debug("__UINT_LEAST16_MAX__ = %#llx", __UINT_LEAST16_MAX__);
|
||||
|
||||
debug("--- INTFASTX MAX ---");
|
||||
debug("__INT_FAST8_MAX__ = %#llx", __INT_FAST8_MAX__);
|
||||
debug("__INT_FAST16_MAX__ = %#llx", __INT_FAST16_MAX__);
|
||||
debug("__INT_FAST32_MAX__ = %#llx", __INT_FAST32_MAX__);
|
||||
debug("__INT_FAST64_MAX__ = %#llx", __INT_FAST64_MAX__);
|
||||
|
||||
debug("--- UINTFASTX MAX ---");
|
||||
debug("__UINT_FAST8_MAX__ = %#llx", __UINT_FAST8_MAX__);
|
||||
debug("__UINT_FAST16_MAX__ = %#llx", __UINT_FAST16_MAX__);
|
||||
debug("__UINT_FAST32_MAX__ = %#llx", __UINT_FAST32_MAX__);
|
||||
debug("__UINT_FAST64_MAX__ = %#llx", __UINT_FAST64_MAX__);
|
||||
|
||||
debug("--- INTPTR MAX ---");
|
||||
debug("__INTPTR_MAX__ = %#llx", __INTPTR_MAX__);
|
||||
debug("__UINTPTR_MAX__ = %#llx", __UINTPTR_MAX__);
|
||||
|
||||
debug("--- OTHER MAX ---");
|
||||
debug("__PTRDIFF_MAX__ = %#llx", __PTRDIFF_MAX__);
|
||||
debug("__SIZE_MAX__ = %#llx", __SIZE_MAX__);
|
||||
debug("__WCHAR_MAX__ = %#llx", __WCHAR_MAX__);
|
||||
debug("__WINT_MAX__ = %#llx", __WINT_MAX__);
|
||||
debug("__SIG_ATOMIC_MAX__ = %#llx", __SIG_ATOMIC_MAX__);
|
||||
debug("__INTMAX_MAX__ = %#llx", __INTMAX_MAX__);
|
||||
debug("__UINTMAX_MAX__ = %#llx", __UINTMAX_MAX__);
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
Reference in New Issue
Block a user