diff --git a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp b/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp index 29fde3b..a9e6591 100644 --- a/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp +++ b/Architecture/amd64/cpu/SymmetricMultiprocessing.cpp @@ -27,7 +27,7 @@ volatile bool CPUEnabled = false; #pragma GCC diagnostic ignored "-Wmissing-field-initializers" static __attribute__((aligned(PAGE_SIZE))) CPUData CPUs[MAX_CPU] = {0}; -CPUData *GetCPU(long id) { return &CPUs[id]; } +SafeFunction CPUData *GetCPU(long id) { return &CPUs[id]; } SafeFunction CPUData *GetCurrentCPU() { diff --git a/Core/Interrupts/IntManager.cpp b/Core/Interrupts/IntManager.cpp index 5c91622..9a90fd0 100644 --- a/Core/Interrupts/IntManager.cpp +++ b/Core/Interrupts/IntManager.cpp @@ -124,14 +124,14 @@ namespace Interrupts if (likely(CoreData != nullptr)) Core = CoreData->ID; - // If this is false, we have a big problem. + /* If this is false, we have a big problem. */ if (likely(Frame->InterruptNumber < CPU::x86::IRQ223 && Frame->InterruptNumber > CPU::x86::ISR0)) { - if (Frame->InterruptNumber == CPU::x86::IRQ29) // Halt core interrupt + /* Halt core interrupt */ + if (unlikely(Frame->InterruptNumber == CPU::x86::IRQ29)) CPU::Stop(); Handler *handler = nullptr; - foreach (auto var in RegisteredEvents) { if (var.ID == static_cast(Frame->InterruptNumber)) diff --git a/Tasking/Scheduler.cpp b/Tasking/Scheduler.cpp index 80cce7a..bfad338 100644 --- a/Tasking/Scheduler.cpp +++ b/Tasking/Scheduler.cpp @@ -90,10 +90,10 @@ NewLock(SchedulerLock); #define wut_schedbg(m, ...) #endif -extern "C" SafeFunction __no_instrument_function void TaskingScheduler_OneShot(int TimeSlice) +extern "C" SafeFunction NIF void TaskingScheduler_OneShot(int TimeSlice) { if (TimeSlice == 0) - TimeSlice = 10; + TimeSlice = Tasking::TaskPriority::Normal; #if defined(__amd64__) ((APIC::Timer *)Interrupts::apicTimer[GetCurrentCPU()->ID])->OneShot(CPU::x86::IRQ16, TimeSlice); #elif defined(__i386__) @@ -104,47 +104,51 @@ extern "C" SafeFunction __no_instrument_function void TaskingScheduler_OneShot(i namespace Tasking { #if defined(__amd64__) - SafeFunction __no_instrument_function bool Task::FindNewProcess(void *CPUDataPointer) + SafeFunction NIF bool Task::FindNewProcess(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; fnp_schedbg("%d processes", ListProcess.size()); #ifdef DEBUG_FIND_NEW_PROCESS - foreach (auto pcb in ListProcess) - fnp_schedbg("Process %d %s", pcb->ID, pcb->Name); + foreach (auto process in ListProcess) + fnp_schedbg("Process %d %s", process->ID, process->Name); #endif - foreach (auto pcb in ListProcess) + foreach (auto process in ListProcess) { - if (InvalidPCB(pcb)) + if (InvalidPCB(process)) continue; - switch (pcb->Status) + switch (process->Status) { case TaskStatus::Ready: - fnp_schedbg("Ready process (%s)%d", pcb->Name, pcb->ID); + fnp_schedbg("Ready process (%s)%d", + process->Name, process->ID); break; default: - fnp_schedbg("Process \"%s\"(%d) status %d", pcb->Name, pcb->ID, pcb->Status); + fnp_schedbg("Process \"%s\"(%d) status %d", + process->Name, process->ID, + process->Status); + /* We don't actually remove the process. RemoveProcess firstly checks if it's terminated, if not, it will loop through Threads and call RemoveThread on terminated threads. */ - RemoveProcess(pcb); + RemoveProcess(process); continue; } - foreach (auto tcb in pcb->Threads) + foreach (auto thread in process->Threads) { - if (InvalidTCB(tcb)) + if (InvalidTCB(thread)) continue; - if (tcb->Status != TaskStatus::Ready) + if (thread->Status != TaskStatus::Ready) continue; - if (tcb->Info.Affinity[CurrentCPU->ID] == false) + if (thread->Info.Affinity[CurrentCPU->ID] == false) continue; - CurrentCPU->CurrentProcess = pcb; - CurrentCPU->CurrentThread = tcb; + CurrentCPU->CurrentProcess = process; + CurrentCPU->CurrentThread = thread; return true; } } @@ -152,7 +156,7 @@ namespace Tasking return false; } - SafeFunction __no_instrument_function bool Task::GetNextAvailableThread(void *CPUDataPointer) + SafeFunction NIF bool Task::GetNextAvailableThread(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; @@ -162,94 +166,103 @@ namespace Tasking { size_t TempIndex = i; RetryAnotherThread: - TCB *thread = CurrentCPU->CurrentProcess->Threads[TempIndex + 1]; - if (unlikely(InvalidTCB(thread))) + TCB *nextThread = CurrentCPU->CurrentProcess->Threads[TempIndex + 1]; + + if (unlikely(InvalidTCB(nextThread))) { if (TempIndex > CurrentCPU->CurrentProcess->Threads.size()) break; TempIndex++; - gnat_schedbg("Thread %#lx is invalid", thread); + + gnat_schedbg("Thread %#lx is invalid", nextThread); goto RetryAnotherThread; } - gnat_schedbg("\"%s\"(%d) and next thread is \"%s\"(%d)", CurrentCPU->CurrentProcess->Threads[i]->Name, CurrentCPU->CurrentProcess->Threads[i]->ID, thread->Name, thread->ID); + gnat_schedbg("\"%s\"(%d) and next thread is \"%s\"(%d)", + CurrentCPU->CurrentProcess->Threads[i]->Name, + CurrentCPU->CurrentProcess->Threads[i]->ID, + thread->Name, thread->ID); - if (thread->Status != TaskStatus::Ready) + if (nextThread->Status != TaskStatus::Ready) { - gnat_schedbg("Thread %d is not ready", thread->ID); + gnat_schedbg("Thread %d is not ready", nextThread->ID); TempIndex++; goto RetryAnotherThread; } - if (thread->Info.Affinity[CurrentCPU->ID] == false) + if (nextThread->Info.Affinity[CurrentCPU->ID] == false) continue; - CurrentCPU->CurrentThread = thread; - gnat_schedbg("[thd 0 -> end] Scheduling thread %d parent of %s->%d Procs %d", thread->ID, thread->Parent->Name, CurrentCPU->CurrentProcess->Threads.size(), ListProcess.size()); + CurrentCPU->CurrentThread = nextThread; + gnat_schedbg("[thd 0 -> end] Scheduling thread %d parent of %s->%d Procs %d", + thread->ID, thread->Parent->Name, + CurrentCPU->CurrentProcess->Threads.size(), ListProcess.size()); return true; } #ifdef DEBUG else { - gnat_schedbg("Thread %d is not the current one", CurrentCPU->CurrentProcess->Threads[i]->ID); + gnat_schedbg("Thread %d is not the current one", + CurrentCPU->CurrentProcess->Threads[i]->ID); } #endif } return false; } - SafeFunction __no_instrument_function bool Task::GetNextAvailableProcess(void *CPUDataPointer) + SafeFunction NIF bool Task::GetNextAvailableProcess(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; bool Skip = true; - foreach (auto pcb in ListProcess) + foreach (auto process in ListProcess) { - if (pcb == CurrentCPU->CurrentProcess.Load()) + if (process == CurrentCPU->CurrentProcess.Load()) { Skip = false; - gnap_schedbg("Found current process %#lx", pcb); + gnap_schedbg("Found current process %#lx", process); continue; } if (Skip) { - gnap_schedbg("Skipping process %#lx", pcb); + gnap_schedbg("Skipping process %#lx", process); continue; } - if (InvalidPCB(pcb)) + if (InvalidPCB(process)) { - gnap_schedbg("Invalid process %#lx", pcb); + gnap_schedbg("Invalid process %#lx", process); continue; } - if (pcb->Status != TaskStatus::Ready) + if (process->Status != TaskStatus::Ready) { - gnap_schedbg("Process %d is not ready", pcb->ID); + gnap_schedbg("Process %d is not ready", process->ID); continue; } - foreach (auto tcb in pcb->Threads) + foreach (auto thread in process->Threads) { - if (InvalidTCB(tcb)) + if (InvalidTCB(thread)) { - gnap_schedbg("Invalid thread %#lx", tcb); + gnap_schedbg("Invalid thread %#lx", thread); continue; } - if (tcb->Status != TaskStatus::Ready) + if (thread->Status != TaskStatus::Ready) { - gnap_schedbg("Thread %d is not ready", tcb->ID); + gnap_schedbg("Thread %d is not ready", thread->ID); continue; } - if (tcb->Info.Affinity[CurrentCPU->ID] == false) + if (thread->Info.Affinity[CurrentCPU->ID] == false) continue; - CurrentCPU->CurrentProcess = pcb; - CurrentCPU->CurrentThread = tcb; - gnap_schedbg("[cur proc+1 -> first thd] Scheduling thread %d %s->%d (Total Procs %d)", tcb->ID, tcb->Name, pcb->Threads.size(), ListProcess.size()); + CurrentCPU->CurrentProcess = process; + CurrentCPU->CurrentThread = thread; + gnap_schedbg("[cur proc+1 -> first thd] Scheduling thread %d %s->%d (Total Procs %d)", + thread->ID, thread->Name, process->Threads.size(), ListProcess.size()); return true; } } @@ -257,75 +270,76 @@ namespace Tasking return false; } - SafeFunction __no_instrument_function void Task::SchedulerCleanupProcesses() + SafeFunction NIF void Task::SchedulerCleanupProcesses() { - foreach (auto pcb in ListProcess) + foreach (auto process in ListProcess) { - if (InvalidPCB(pcb)) + if (InvalidPCB(process)) continue; - RemoveProcess(pcb); + RemoveProcess(process); } } - SafeFunction __no_instrument_function bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) + SafeFunction NIF bool Task::SchedulerSearchProcessThread(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; - foreach (auto pcb in ListProcess) + foreach (auto process in ListProcess) { - if (InvalidPCB(pcb)) + if (InvalidPCB(process)) { - sspt_schedbg("Invalid process %#lx", pcb); + sspt_schedbg("Invalid process %#lx", process); continue; } - if (pcb->Status != TaskStatus::Ready) + if (process->Status != TaskStatus::Ready) { - sspt_schedbg("Process %d is not ready", pcb->ID); + sspt_schedbg("Process %d is not ready", process->ID); continue; } - foreach (auto tcb in pcb->Threads) + foreach (auto thread in process->Threads) { - if (InvalidTCB(tcb)) + if (InvalidTCB(thread)) { - sspt_schedbg("Invalid thread %#lx", tcb); + sspt_schedbg("Invalid thread %#lx", thread); continue; } - if (tcb->Status != TaskStatus::Ready) + if (thread->Status != TaskStatus::Ready) { - sspt_schedbg("Thread %d is not ready", tcb->ID); + sspt_schedbg("Thread %d is not ready", thread->ID); continue; } - if (tcb->Info.Affinity[CurrentCPU->ID] == false) + if (thread->Info.Affinity[CurrentCPU->ID] == false) continue; - CurrentCPU->CurrentProcess = pcb; - CurrentCPU->CurrentThread = tcb; - sspt_schedbg("[proc 0 -> end -> first thd] Scheduling thread %d parent of %s->%d (Procs %d)", tcb->ID, tcb->Parent->Name, pcb->Threads.size(), ListProcess.size()); + CurrentCPU->CurrentProcess = process; + CurrentCPU->CurrentThread = thread; + sspt_schedbg("[proc 0 -> end -> first thd] Scheduling thread %d parent of %s->%d (Procs %d)", + thread->ID, thread->Parent->Name, process->Threads.size(), ListProcess.size()); return true; } } return false; } - SafeFunction __no_instrument_function void Task::UpdateProcessStatus() + SafeFunction NIF void Task::UpdateProcessStatus() { - foreach (auto pcb in ListProcess) + foreach (auto process in ListProcess) { - if (InvalidPCB(pcb)) + if (InvalidPCB(process)) continue; - if (pcb->Status == TaskStatus::Terminated || - pcb->Status == TaskStatus::Stopped) + if (process->Status == TaskStatus::Terminated || + process->Status == TaskStatus::Stopped) continue; bool AllThreadsSleeping = true; - foreach (auto tcb in pcb->Threads) + foreach (auto thread in process->Threads) { - if (tcb->Status != TaskStatus::Sleeping) + if (thread->Status != TaskStatus::Sleeping) { AllThreadsSleeping = false; break; @@ -333,45 +347,46 @@ namespace Tasking } if (AllThreadsSleeping) - pcb->Status = TaskStatus::Sleeping; - else if (pcb->Status == TaskStatus::Sleeping) - pcb->Status = TaskStatus::Ready; + process->Status = TaskStatus::Sleeping; + else if (process->Status == TaskStatus::Sleeping) + process->Status = TaskStatus::Ready; } } - SafeFunction __no_instrument_function void Task::WakeUpThreads(void *CPUDataPointer) + SafeFunction NIF void Task::WakeUpThreads(void *CPUDataPointer) { CPUData *CurrentCPU = (CPUData *)CPUDataPointer; - foreach (auto pcb in ListProcess) + foreach (auto process in ListProcess) { - if (InvalidPCB(pcb)) + if (InvalidPCB(process)) continue; - if (pcb->Status == TaskStatus::Terminated || - pcb->Status == TaskStatus::Stopped) + if (process->Status == TaskStatus::Terminated || + process->Status == TaskStatus::Stopped) continue; - foreach (auto tcb in pcb->Threads) + foreach (auto thread in process->Threads) { - if (InvalidTCB(tcb)) + if (InvalidTCB(thread)) continue; - if (tcb->Status != TaskStatus::Sleeping) + if (thread->Status != TaskStatus::Sleeping) continue; /* Check if the thread is ready to wake up. */ - if (tcb->Info.SleepUntil < TimeManager->GetCounter()) + if (thread->Info.SleepUntil < TimeManager->GetCounter()) { - if (pcb->Status == TaskStatus::Sleeping) - pcb->Status = TaskStatus::Ready; - tcb->Status = TaskStatus::Ready; + if (process->Status == TaskStatus::Sleeping) + process->Status = TaskStatus::Ready; + thread->Status = TaskStatus::Ready; - tcb->Info.SleepUntil = 0; - wut_schedbg("Thread \"%s\"(%d) woke up.", tcb->Name, tcb->ID); + thread->Info.SleepUntil = 0; + wut_schedbg("Thread \"%s\"(%d) woke up.", thread->Name, thread->ID); } else { - wut_schedbg("Thread \"%s\"(%d) is not ready to wake up. (SleepUntil: %d, Counter: %d)", tcb->Name, tcb->ID, tcb->Info.SleepUntil, TimeManager->GetCounter()); + wut_schedbg("Thread \"%s\"(%d) is not ready to wake up. (SleepUntil: %d, Counter: %d)", + thread->Name, thread->ID, thread->Info.SleepUntil, TimeManager->GetCounter()); } } } @@ -408,7 +423,7 @@ namespace Tasking "SchedulerSearchProcessThread", }; - SafeFunction __no_instrument_function void OnScreenTaskManagerUpdate() + SafeFunction NIF void OnScreenTaskManagerUpdate() { TimeManager->Sleep(100); Video::ScreenBuffer *sb = Display->GetBuffer(0); @@ -448,7 +463,7 @@ namespace Tasking } #endif - SafeFunction __no_instrument_function void Task::Schedule(CPU::x64::TrapFrame *Frame) + SafeFunction NIF void Task::Schedule(CPU::x64::TrapFrame *Frame) { SmartCriticalSection(SchedulerLock); if (StopScheduler) @@ -599,7 +614,8 @@ namespace Tasking // wrmsr(MSR_SHADOW_GS_BASE, CurrentCPU->CurrentThread->gs); break; default: - error("Unknown trust level %d.", CurrentCPU->CurrentProcess->Security.TrustLevel); + error("Unknown trust level %d.", + CurrentCPU->CurrentProcess->Security.TrustLevel); break; } @@ -628,7 +644,8 @@ namespace Tasking CurrentCPU->CurrentThread->Registers.rsp); schedbg("================================================================"); - schedbg("Technical Informations on Thread %s[%ld]:", CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID); + schedbg("Technical Informations on Thread %s[%ld]:", + CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID); uint64_t ds; asmv("mov %%ds, %0" : "=r"(ds)); @@ -653,7 +670,7 @@ namespace Tasking __sync; /* TODO: Is this really needed? */ } - SafeFunction __no_instrument_function void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame) { this->Schedule(Frame); } + SafeFunction NIF void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame) { this->Schedule(Frame); } #elif defined(__i386__) SafeFunction bool Task::FindNewProcess(void *CPUDataPointer) { diff --git a/include/cpu.hpp b/include/cpu.hpp index 7ff8412..c69aecb 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -130,20 +130,17 @@ namespace CPU /** * @brief Stop the CPU (infinite loop) */ - SafeFunction static inline void Stop() + SafeFunction __noreturn __naked __used inline void Stop() { - while (1) - { #if defined(__amd64__) || defined(__i386__) - asmv("CPUStopLoop:\n" - "cli\n" - "hlt\n" - "jmp CPUStopLoop"); + asmv("CPUStopLoop:\n" + "cli\n" + "hlt\n" + "jmp CPUStopLoop"); #elif defined(__aarch64__) - asmv("msr daifset, #2"); - asmv("wfe"); + asmv("msr daifset, #2"); + asmv("wfe"); #endif - } } /** diff --git a/include/vector.hpp b/include/vector.hpp index 417dc8c..ba8b434 100644 --- a/include/vector.hpp +++ b/include/vector.hpp @@ -16,7 +16,7 @@ private: public: typedef T *iterator; - __no_instrument_function Vector() + NIF Vector() { #ifdef DEBUG_MEM_ALLOCATION debug("VECTOR INIT: Vector( )"); @@ -26,7 +26,7 @@ public: VectorBuffer = 0; } - __no_instrument_function Vector(size_t Size) + NIF Vector(size_t Size) { VectorCapacity = Size; VectorSize = Size; @@ -36,7 +36,7 @@ public: VectorBuffer = new T[Size]; } - __no_instrument_function Vector(size_t Size, const T &Initial) + NIF Vector(size_t Size, const T &Initial) { VectorSize = Size; VectorCapacity = Size; @@ -49,7 +49,7 @@ public: VectorBuffer[i] = Initial; } - __no_instrument_function Vector(const Vector &Vector) + NIF Vector(const Vector &Vector) { VectorSize = Vector.VectorSize; VectorCapacity = Vector.VectorCapacity; @@ -62,11 +62,13 @@ public: VectorBuffer[i] = Vector.VectorBuffer[i]; } - __no_instrument_function ~Vector() + NIF ~Vector() { #ifdef DEBUG_MEM_ALLOCATION debug("VECTOR INIT: ~Vector( ~%lx )", VectorBuffer); #endif + VectorSize = 0; + VectorCapacity = 0; if (VectorBuffer != nullptr) { delete[] VectorBuffer; @@ -74,7 +76,7 @@ public: } } - __no_instrument_function void remove(size_t Position) + NIF void remove(size_t Position) { if (Position >= VectorSize) return; @@ -86,7 +88,7 @@ public: VectorSize--; } - __no_instrument_function void remove(const T &Value) + NIF void remove(const T &Value) { for (size_t i = 0; i < VectorSize; i++) { @@ -98,30 +100,91 @@ public: } } - __no_instrument_function size_t capacity() const { return VectorCapacity; } + NIF T &null_elem() + { + static T null_elem; + return null_elem; + } - __no_instrument_function size_t size() const { return VectorSize; } + NIF bool null_elem(size_t Index) + { + if (!reinterpret_cast(&VectorBuffer[Index])) + return false; + return true; + } - __no_instrument_function bool empty() const; + NIF T &next(size_t Position) + { + if (Position + 1 < VectorSize && reinterpret_cast(&VectorBuffer[Position + 1])) + return VectorBuffer[Position + 1]; + warn("next( %lld ) is null (requested by %#lx)", Position, __builtin_return_address(0)); + return this->null_elem(); + } - __no_instrument_function iterator begin() { return VectorBuffer; } + NIF T &prev(size_t Position) + { + if (Position > 0 && reinterpret_cast(&VectorBuffer[Position - 1])) + return VectorBuffer[Position - 1]; + warn("prev( %lld ) is null (requested by %#lx)", Position, __builtin_return_address(0)); + return this->null_elem(); + } - __no_instrument_function iterator end() { return VectorBuffer + size(); } + NIF T &next(const T &Value) + { + for (size_t i = 0; i < VectorSize; i++) + { + if (VectorBuffer[i] == Value) + { + if (i + 1 < VectorSize && reinterpret_cast(&VectorBuffer[i + 1])) + return VectorBuffer[i + 1]; + else + break; + } + } + warn("next( %#lx ) is null (requested by %#lx)", Value, __builtin_return_address(0)); + return this->null_elem(); + } - __no_instrument_function T &front() { return VectorBuffer[0]; } + NIF T &prev(const T &Value) + { + for (size_t i = 0; i < VectorSize; i++) + { + if (VectorBuffer[i] == Value) + { + if (i > 0 && reinterpret_cast(&VectorBuffer[i - 1])) + return VectorBuffer[i - 1]; + else + break; + } + } + warn("prev( %#lx ) is null (requested by %#lx)", Value, __builtin_return_address(0)); + return this->null_elem(); + } - __no_instrument_function T &back() { return VectorBuffer[VectorSize - 1]; } + NIF size_t capacity() const { return VectorCapacity; } - __no_instrument_function void push_back(const T &Value) + NIF size_t size() const { return VectorSize; } + + NIF bool empty() const; + + NIF iterator begin() { return VectorBuffer; } + + NIF iterator end() { return VectorBuffer + size(); } + + NIF T &front() { return VectorBuffer[0]; } + + NIF T &back() { return VectorBuffer[VectorSize - 1]; } + + NIF void push_back(const T &Value) { if (VectorSize >= VectorCapacity) reserve(VectorCapacity + 5); VectorBuffer[VectorSize++] = Value; } - __no_instrument_function void pop_back() { VectorSize--; } + NIF void pop_back() { VectorSize--; } - __no_instrument_function void reverse() + NIF void reverse() { if (VectorSize <= 1) return; @@ -133,7 +196,7 @@ public: } } - __no_instrument_function void reserve(size_t Capacity) + NIF void reserve(size_t Capacity) { if (VectorBuffer == 0) { @@ -155,24 +218,36 @@ public: VectorBuffer = NewBuffer; } - __no_instrument_function void resize(size_t Size) + NIF void resize(size_t Size) { reserve(Size); VectorSize = Size; } - __no_instrument_function T &operator[](size_t Index) + NIF void clear() + { + VectorCapacity = 0; + VectorSize = 0; + if (VectorBuffer != nullptr) + { + delete[] VectorBuffer; + VectorBuffer = nullptr; + } + } + + NIF T *data() { return VectorBuffer; } + + NIF T &operator[](size_t Index) { if (!reinterpret_cast(&VectorBuffer[Index])) { warn("operator[]( %lld ) is null (requested by %#lx)", Index, __builtin_return_address(0)); - static T null_elem; - return null_elem; + return this->null_elem(); } return VectorBuffer[Index]; } - __no_instrument_function Vector &operator=(const Vector &Vector) + NIF Vector &operator=(const Vector &Vector) { delete[] VectorBuffer; VectorSize = Vector.VectorSize; @@ -185,19 +260,6 @@ public: VectorBuffer[i] = Vector.VectorBuffer[i]; return *this; } - - __no_instrument_function void clear() - { - VectorCapacity = 0; - VectorSize = 0; - if (VectorBuffer != nullptr) - { - delete[] VectorBuffer; - VectorBuffer = nullptr; - } - } - - __no_instrument_function T *data() { return VectorBuffer; } }; #endif // !__FENNIX_KERNEL_VECTOR_H__