diff options
| -rw-r--r-- | doc/specs/SPECFICATION_MACROS.md (renamed from src/kernel/MACROS_MAP.md) | 10 | ||||
| -rw-r--r-- | public/frameworks/KernelTest.fwrk/headers/Foundation.h | 6 | ||||
| -rw-r--r-- | public/frameworks/KernelTest.fwrk/headers/TestCase.h | 3 | ||||
| -rw-r--r-- | src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc | 48 | ||||
| -rw-r--r-- | src/libSystem/src/SystemCalls.cc | 54 | ||||
| -rw-r--r-- | src/modules/CoreGfx/CoreGfx.h | 2 | ||||
| -rw-r--r-- | test/.keep | 0 | ||||
| -rw-r--r-- | test/kernel_test/Makefile | 22 | ||||
| -rw-r--r-- | test/kernel_test/error.test.cc | 2 | ||||
| -rw-r--r-- | test/kernel_test/event.test.cc | 103 | ||||
| -rw-r--r-- | test/kernel_test/process.test.cc | 13 | ||||
| -rw-r--r-- | test/kernel_test/scheduler.test.cc | 108 | ||||
| -rw-r--r-- | test/libsystem_test/Makefile | 22 | ||||
| -rw-r--r-- | test/libsystem_test/memory.test.cc | 2 | ||||
| -rw-r--r-- | test/libsystem_test/thread.test.cc | 2 |
15 files changed, 144 insertions, 253 deletions
diff --git a/src/kernel/MACROS_MAP.md b/doc/specs/SPECFICATION_MACROS.md index bae5aef1..e3456e50 100644 --- a/src/kernel/MACROS_MAP.md +++ b/doc/specs/SPECFICATION_MACROS.md @@ -1,5 +1,11 @@ -# __nekernel: Configuration Macros of NeKernel. +# Configuration Macros of NeKernel. + +## NeKernel - `__nekernel_max_cores` -> Max SMP cores usable by NeKernel's scheduler. -- `__nekernel_boot_core_index` -> Index of the boot core (0, 1, or 3) +- `__nekernel_boot_core_index` -> Index of the boot core (0, 1, or 3). + +## KernelTest: + +- `__KT_TEST_MAIN` -> KernelTest entrypoint symbol. diff --git a/public/frameworks/KernelTest.fwrk/headers/Foundation.h b/public/frameworks/KernelTest.fwrk/headers/Foundation.h index e1ebb936..97f82e59 100644 --- a/public/frameworks/KernelTest.fwrk/headers/Foundation.h +++ b/public/frameworks/KernelTest.fwrk/headers/Foundation.h @@ -17,4 +17,10 @@ #define KT_TEST_SUCCESS (kErrorSuccess) #define KT_TEST_FAILURE (kErrorSuccess + 1) +#ifndef __KT_TEST_MAIN +#define __KT_TEST_MAIN WinMain +#endif + +#define KT_TEST_MAIN __KT_TEST_MAIN + #endif diff --git a/public/frameworks/KernelTest.fwrk/headers/TestCase.h b/public/frameworks/KernelTest.fwrk/headers/TestCase.h index 46568233..79ebab8d 100644 --- a/public/frameworks/KernelTest.fwrk/headers/TestCase.h +++ b/public/frameworks/KernelTest.fwrk/headers/TestCase.h @@ -14,7 +14,8 @@ #define KT_RUN_TEST(OBJECT) \ { \ - KTTestCase##OBJECT{}.Run(); \ + KTTestCase##OBJECT obj{}; \ + obj.Run(); \ } #define KT_MUST_PASS(MSG, LEFT_COND, RIGHT_COND) \ diff --git a/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc index bb735ffb..7ee4a69c 100644 --- a/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc +++ b/src/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc @@ -26,26 +26,26 @@ STATIC void hal_int_send_eoi(UInt8 vector) { /// @param rsp EXTERN_C Kernel::Void int_handle_gpf(Kernel::UIntPtr rsp) { auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); + process.Crash(); hal_int_send_eoi(13); - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.Status; } /// @brief Handle page fault. /// @param rsp EXTERN_C void int_handle_pf(Kernel::UIntPtr rsp) { auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); + process.Crash(); hal_int_send_eoi(14); - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.Status; } /// @brief Handle scheduler interrupt. @@ -67,28 +67,28 @@ EXTERN_C void int_handle_scheduler(Kernel::UIntPtr rsp) { /// @param rsp EXTERN_C void int_handle_math(Kernel::UIntPtr rsp) { auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); + process.Crash(); hal_int_send_eoi(8); - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.Status; } /// @brief Handle any generic fault. /// @param rsp EXTERN_C void int_handle_generic(Kernel::UIntPtr rsp) { auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); + process.Crash(); hal_int_send_eoi(30); Kernel::kout << "Kernel: Generic Process Fault.\r"; - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.Status; Kernel::kout << "Kernel: SIGKILL status.\r"; } @@ -98,25 +98,25 @@ EXTERN_C Kernel::Void int_handle_breakpoint(Kernel::UIntPtr rip) { hal_int_send_eoi(3); - process.Leak().Signal.SignalArg = rip; - process.Leak().Signal.SignalID = SIGTRAP; + process.Signal.SignalArg = rip; + process.Signal.SignalID = SIGTRAP; - process.Leak().Signal.Status = process.Leak().Status; + process.Signal.Status = process.Status; - process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + process.Status = Kernel::ProcessStatusKind::kFrozen; } /// @brief Handle #UD fault. /// @param rsp EXTERN_C void int_handle_ud(Kernel::UIntPtr rsp) { auto process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - process.Leak().Crash(); + process.Crash(); hal_int_send_eoi(6); - process.Leak().Signal.SignalArg = rsp; - process.Leak().Signal.SignalID = SIGKILL; - process.Leak().Signal.Status = process.Leak().Status; + process.Signal.SignalArg = rsp; + process.Signal.SignalID = SIGKILL; + process.Signal.Status = process.Status; } /// @brief Enter syscall from assembly (libSystem only) diff --git a/src/libSystem/src/SystemCalls.cc b/src/libSystem/src/SystemCalls.cc index 0574d7ba..2651fb28 100644 --- a/src/libSystem/src/SystemCalls.cc +++ b/src/libSystem/src/SystemCalls.cc @@ -6,6 +6,8 @@ #include <libSystem/SystemKit/Syscall.h> #include <libSystem/SystemKit/System.h> #include <libSystem/SystemKit/Verify.h> +#include "hint/CompilerHint.h" +#include "libSystem/SystemKit/Macros.h" using namespace LibSystem; @@ -148,6 +150,58 @@ IMPORT_C UInt64 IoTellFile(_Input Ref desc) { return *ret; } +IMPORT_C SInt32 PrintRelease(_Input IORef buf) { + SInt32* ret = static_cast<SInt32*>(libsys_syscall_arg_2(SYSCALL_HASH("PrintRelease"), static_cast<VoidPtr>(buf))); + if (!ret) return -kErrorInvalidData; + + return static_cast<SInt32>(*ret); +} + +IMPORT_C IORef PrintCreate(Void) { + return static_cast<IORef>(libsys_syscall_arg_1(SYSCALL_HASH("PrintCreate"))); +} + + +IMPORT_C VoidPtr MmCreateHeap(UInt64 initial_size, UInt32 max_size) { + return static_cast<VoidPtr>(libsys_syscall_arg_3(SYSCALL_HASH("MmCreateHeap"), + reinterpret_cast<VoidPtr>(&initial_size), + reinterpret_cast<VoidPtr>(&max_size))); +} + +IMPORT_C SInt32 MmDestroyHeap(VoidPtr heap) +{ + auto ret = libsys_syscall_arg_2(SYSCALL_HASH("MmDestroyHeap"), static_cast<VoidPtr>(heap)); + return *static_cast<SInt32*>(ret); +} + +IMPORT_C SInt32 PrintIn(_Input IORef desc, const Char* fmt, ...) { + va_list args; + va_start(args, fmt); + + auto buf = StrFmt(fmt, args); + + va_end(args); + + // if truncated, `needed` >= kBufferSz; we still send truncated buffer + auto ret_ptr = libsys_syscall_arg_3(SYSCALL_HASH("PrintIn"), static_cast<VoidPtr>(desc), + Verify::sys_safe_cast<Char, Void>(buf)); + + if (!ret_ptr) return -kErrorInvalidData; + + auto ret = static_cast<const volatile SInt32*>(ret_ptr); + + return *ret; +} + +IMPORT_C IORef PrintGet(const Char* path) { + return static_cast<IORef>(libsys_syscall_arg_2(SYSCALL_HASH("PrintGet"), + Verify::sys_safe_cast<Char, Void>(path))); +} + +IMPORT_C ErrRef ErrGetLastError(Void) { + return *static_cast<ErrRef*>(libsys_syscall_arg_1(SYSCALL_HASH("ErrGetLastError"))); +} + IMPORT_C SInt32 PrintOut(_Input IORef desc, const Char* fmt, ...) { va_list args; va_start(args, fmt); diff --git a/src/modules/CoreGfx/CoreGfx.h b/src/modules/CoreGfx/CoreGfx.h index 470dd510..c22aee38 100644 --- a/src/modules/CoreGfx/CoreGfx.h +++ b/src/modules/CoreGfx/CoreGfx.h @@ -11,7 +11,7 @@ #define cg_color(R, G, B) RGB(R, G, B) -#define cg_get_clear_clr() RGB(0, 0, 0x80) +#define cg_get_clear_clr() RGB(0, 0, 0) #define cg_clear() kCGCursor = 0UL diff --git a/test/.keep b/test/.keep deleted file mode 100644 index e69de29b..00000000 --- a/test/.keep +++ /dev/null diff --git a/test/kernel_test/Makefile b/test/kernel_test/Makefile new file mode 100644 index 00000000..823ac0d2 --- /dev/null +++ b/test/kernel_test/Makefile @@ -0,0 +1,22 @@ +################################################## +# (c) Amlal El Mahrouss and NeKernel Authors, licensed under the Apache 2.0 license. +# This file is for libSystem.dll's testing stubs. +################################################## + +GCC=x86_64-w64-mingw32-g++ -Wl,-subsystem=17 +LIB=-L../../src/libSystem -lSystem +STD=-std=c++20 -DKT_TESTING_ENABLED +INCLUDE=-I../../src -I../../public -I../../public/frameworks/ -I../../ + +OBJ_FILES = \ + error.test.exe \ + print.test.exe \ + process.test.exe + +.PHONY: all +all: $(OBJ_FILES) + +%.exe: %.cc + @echo "==> Building test: $@" + $(GCC) $(LIB) $< \ + $(STD) $(INCLUDE) -o $(basename $<).exe
\ No newline at end of file diff --git a/test/kernel_test/error.test.cc b/test/kernel_test/error.test.cc index 084566b2..ece8f71d 100644 --- a/test/kernel_test/error.test.cc +++ b/test/kernel_test/error.test.cc @@ -55,7 +55,7 @@ KT_DECL_TEST(ErrGetLastErrorMultipleCalls, []() -> bool { }); /// \brief Run error tests. -SInt32 KT_TEST_MAIN() { +IMPORT_C SInt32 KT_TEST_MAIN() { KT_RUN_TEST(ErrGetLastErrorInitial); KT_RUN_TEST(ErrGetLastErrorAfterSuccess); KT_RUN_TEST(ErrGetLastErrorAfterFailure); diff --git a/test/kernel_test/event.test.cc b/test/kernel_test/event.test.cc deleted file mode 100644 index 6e342c6b..00000000 --- a/test/kernel_test/event.test.cc +++ /dev/null @@ -1,103 +0,0 @@ -/// \file event.test.cc -/// \brief Event handling API tests. -/// \author Amlal El Mahrouss (amlal at nekernel dot org) - -#include <libSystem/SystemKit/System.h> -#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h> - -/// \note Mock event listener -static Bool event_listener_called = NO; - -static Void mock_event_listener(VoidPtr data) { - event_listener_called = YES; -} - -/// \note EvtAddListener tests -KT_DECL_TEST(EvtAddListenerValid, []() -> bool { - REF_TYPE listener_ref; - listener_ref.__hash = 0x1234; - listener_ref.__self = (VoidPtr) mock_event_listener; - - EvtAddListener("test_event", (Ref) &listener_ref); - return YES; -}); - -KT_DECL_TEST(EvtAddListenerNull, []() -> bool { - EvtAddListener(nullptr, nullptr); - return YES; -}); - -/// \note EvtRemoveListener tests -KT_DECL_TEST(EvtRemoveListenerValid, []() -> bool { - REF_TYPE listener_ref; - listener_ref.__hash = 0x1234; - listener_ref.__self = (VoidPtr) mock_event_listener; - - EvtAddListener("remove_test", (Ref) &listener_ref); - EvtRemoveListener("remove_test", (Ref) &listener_ref); - return YES; -}); - -KT_DECL_TEST(EvtRemoveListenerNull, []() -> bool { - EvtRemoveListener(nullptr, nullptr); - return YES; -}); - -/// \note EvtDispatchEvent tests -KT_DECL_TEST(EvtDispatchEventValid, []() -> bool { - REF_TYPE listener_ref; - listener_ref.__hash = 0x5678; - listener_ref.__self = (VoidPtr) mock_event_listener; - - event_listener_called = NO; - - EvtAddListener("dispatch_test", (Ref) &listener_ref); - - char data[] = "event_data"; - EvtDispatchEvent("dispatch_test", (VoidPtr) data); - - return YES; -}); - -KT_DECL_TEST(EvtDispatchEventNull, []() -> bool { - VoidPtr result = EvtDispatchEvent(nullptr, nullptr); - return result == nullptr; -}); - -KT_DECL_TEST(EvtDispatchEventNotExist, []() -> bool { - VoidPtr result = EvtDispatchEvent("nonexistent_event", nullptr); - return YES; -}); - -/// \note Event lifecycle test -KT_DECL_TEST(EvtLifecycleTest, []() -> bool { - REF_TYPE listener_ref; - listener_ref.__hash = 0xABCD; - listener_ref.__self = (VoidPtr) mock_event_listener; - - EvtAddListener("lifecycle_event", (Ref) &listener_ref); - - char data[] = "test"; - EvtDispatchEvent("lifecycle_event", (VoidPtr) data); - - EvtRemoveListener("lifecycle_event", (Ref) &listener_ref); - - return YES; -}); - -/// \brief Run event tests. -SInt32 KT_TEST_MAIN() { - KT_RUN_TEST(EvtAddListenerValid); - KT_RUN_TEST(EvtAddListenerNull); - - KT_RUN_TEST(EvtRemoveListenerValid); - KT_RUN_TEST(EvtRemoveListenerNull); - - KT_RUN_TEST(EvtDispatchEventValid); - KT_RUN_TEST(EvtDispatchEventNull); - KT_RUN_TEST(EvtDispatchEventNotExist); - - KT_RUN_TEST(EvtLifecycleTest); - - return KT_TEST_SUCCESS; -} diff --git a/test/kernel_test/process.test.cc b/test/kernel_test/process.test.cc index 451cacfe..b742b5c1 100644 --- a/test/kernel_test/process.test.cc +++ b/test/kernel_test/process.test.cc @@ -3,7 +3,7 @@ /// \author Amlal El Mahrouss (amlal at nekernel dot org) #include <libSystem/SystemKit/System.h> -#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h> +#include <KernelTest.fwrk/headers/TestCase.h> /// \note RtlSpawnProcess tests KT_DECL_TEST(ProcessHasFailed, []() -> bool { @@ -17,14 +17,6 @@ KT_DECL_TEST(ProcessHasSucceeded, []() -> bool { return RtlSpawnProcess("/system/list", 0, nullptr, nullptr, 0) > 0; }); -KT_DECL_TEST(ProcessSpawnWithArgs, []() -> bool { - Char* argv[] = {(Char*) "arg1", (Char*) "arg2"}; - Char* envp[] = {(Char*) "VAR=value"}; - - UIntPtr pid = RtlSpawnProcess("/system/list", 2, argv, envp, 1); - return pid > 0; -}); - KT_DECL_TEST(ProcessSpawnNullPath, []() -> bool { return RtlSpawnProcess(nullptr, 0, nullptr, nullptr, 0) == -1; }); @@ -69,10 +61,9 @@ KT_DECL_TEST(ProcessExitInvalid, []() -> bool { }); /// \brief Run 'process' test. -SInt32 KT_TEST_MAIN() { +IMPORT_C SInt32 KT_TEST_MAIN() { KT_RUN_TEST(ProcessHasFailed); KT_RUN_TEST(ProcessHasSucceeded); - KT_RUN_TEST(ProcessSpawnWithArgs); KT_RUN_TEST(ProcessSpawnNullPath); KT_RUN_TEST(ProcessSpawnInvalidPath); diff --git a/test/kernel_test/scheduler.test.cc b/test/kernel_test/scheduler.test.cc deleted file mode 100644 index 58cf6017..00000000 --- a/test/kernel_test/scheduler.test.cc +++ /dev/null @@ -1,108 +0,0 @@ -/// \file scheduler.test.cc -/// \brief Scheduler and debugging API tests. -/// \author Amlal El Mahrouss (amlal at nekernel dot org) - -#include <libSystem/SystemKit/System.h> -#include <public/frameworks/KernelTest.fwrk/headers/TestCase.h> - -/// \note SchedGetCurrentProcessID tests -KT_DECL_TEST(SchedGetCurrentPIDValid, []() -> bool { - UIntPtr pid = SchedGetCurrentProcessID(); - return pid > 0; -}); - -/// \note SchedSetAffinity/SchedGetAffinity tests -KT_DECL_TEST(SchedSetAffinityValid, []() -> bool { - UIntPtr pid = SchedGetCurrentProcessID(); - AffinityRef affinity; - - SInt32 result = SchedSetAffinity(pid, 1, &affinity); - return result >= 0; -}); - -KT_DECL_TEST(SchedGetAffinityValid, []() -> bool { - UIntPtr pid = SchedGetCurrentProcessID(); - AffinityRef affinity; - - SInt32 result = SchedGetAffinity(pid, &affinity); - return result >= 0; -}); - -KT_DECL_TEST(SchedSetAffinityInvalid, []() -> bool { - AffinityRef affinity; - SInt32 result = SchedSetAffinity(0, 1, &affinity); - return result < 0; -}); - -KT_DECL_TEST(SchedGetAffinityInvalid, []() -> bool { - AffinityRef affinity; - SInt32 result = SchedGetAffinity(0, &affinity); - return result < 0; -}); - -KT_DECL_TEST(SchedAffinityRoundTrip, []() -> bool { - UIntPtr pid = SchedGetCurrentProcessID(); - AffinityRef affinity_set; - AffinityRef affinity_get; - - SchedSetAffinity(pid, 2, &affinity_set); - SInt32 result = SchedGetAffinity(pid, &affinity_get); - - return result >= 0; -}); - -/// \note SchedFireSignal tests -KT_DECL_TEST(SchedFireSignalValid, []() -> bool { - UIntPtr pid = SchedGetCurrentProcessID(); - SInt32 result = SchedFireSignal(pid, 1); - return result >= 0; -}); - -KT_DECL_TEST(SchedFireSignalInvalid, []() -> bool { - SInt32 result = SchedFireSignal(0, 1); - return result < 0; -}); - -/// \note SchedReadMemory/SchedWriteMemory tests -KT_DECL_TEST(SchedReadMemoryValid, []() -> bool { - UIntPtr pid = SchedGetCurrentProcessID(); - SInt32 result = SchedReadMemory(pid, 0x1000, 64); - return result >= 0; -}); - -KT_DECL_TEST(SchedWriteMemoryValid, []() -> bool { - UIntPtr pid = SchedGetCurrentProcessID(); - SInt32 result = SchedWriteMemory(pid, 0x1000, 0x42); - return result >= 0; -}); - -KT_DECL_TEST(SchedReadMemoryInvalid, []() -> bool { - SInt32 result = SchedReadMemory(0, 0x1000, 64); - return result < 0; -}); - -KT_DECL_TEST(SchedWriteMemoryInvalid, []() -> bool { - SInt32 result = SchedWriteMemory(0, 0x1000, 0x42); - return result < 0; -}); - -/// \brief Run scheduler tests. -SInt32 KT_TEST_MAIN() { - KT_RUN_TEST(SchedGetCurrentPIDValid); - - KT_RUN_TEST(SchedSetAffinityValid); - KT_RUN_TEST(SchedGetAffinityValid); - KT_RUN_TEST(SchedSetAffinityInvalid); - KT_RUN_TEST(SchedGetAffinityInvalid); - KT_RUN_TEST(SchedAffinityRoundTrip); - - KT_RUN_TEST(SchedFireSignalValid); - KT_RUN_TEST(SchedFireSignalInvalid); - - KT_RUN_TEST(SchedReadMemoryValid); - KT_RUN_TEST(SchedWriteMemoryValid); - KT_RUN_TEST(SchedReadMemoryInvalid); - KT_RUN_TEST(SchedWriteMemoryInvalid); - - return KT_TEST_SUCCESS; -} diff --git a/test/libsystem_test/Makefile b/test/libsystem_test/Makefile new file mode 100644 index 00000000..0e38e134 --- /dev/null +++ b/test/libsystem_test/Makefile @@ -0,0 +1,22 @@ +################################################## +# (c) Amlal El Mahrouss and NeKernel Authors, licensed under the Apache 2.0 license. +# This file is for libSystem.dll's testing stubs. +################################################## + +GCC=x86_64-w64-mingw32-g++ -Wl,-subsystem=17 +LIB=-L../../src/libSystem -lSystem +STD=-std=c++20 -DKT_TESTING_ENABLED +INCLUDE=-I../../src -I../../public -I../../public/frameworks/ -I../../ + +OBJ_FILES = \ + thread.test.exe \ + memory.test.exe \ + io.test.exe + +.PHONY: all +all: $(OBJ_FILES) + +%.exe: %.cc + @echo "==> Building test: $@" + $(GCC) $(LIB) $< \ + $(STD) $(INCLUDE) -o $(basename $<).exe
\ No newline at end of file diff --git a/test/libsystem_test/memory.test.cc b/test/libsystem_test/memory.test.cc index 5083570c..28d758cc 100644 --- a/test/libsystem_test/memory.test.cc +++ b/test/libsystem_test/memory.test.cc @@ -110,7 +110,7 @@ KT_DECL_TEST(MmFillCRC32HeapValid, []() -> bool { }); /// \brief Run memory tests. -SInt32 KT_TEST_MAIN() { +IMPORT_C SInt32 KT_TEST_MAIN() { KT_RUN_TEST(MmCreateHeapSuccess); KT_RUN_TEST(MmCreateHeapZeroSize); KT_RUN_TEST(MmDestroyHeapValid); diff --git a/test/libsystem_test/thread.test.cc b/test/libsystem_test/thread.test.cc index ec8ccbad..db248e26 100644 --- a/test/libsystem_test/thread.test.cc +++ b/test/libsystem_test/thread.test.cc @@ -120,7 +120,7 @@ KT_DECL_TEST(ThrExitMainThreadValid, []() -> bool { }); /// \brief Run threading tests. -SInt32 KT_TEST_MAIN() { +IMPORT_C SInt32 KT_TEST_MAIN() { KT_RUN_TEST(ThrCreateThreadValid); KT_RUN_TEST(ThrCreateThreadNull); KT_RUN_TEST(ThrCreateThreadWithName); |
