-
Notifications
You must be signed in to change notification settings - Fork 1
Development #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Development #70
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
#ifndef PIC_H | ||
#define PIC_H | ||
|
||
#include "stdint.h" | ||
void PicInstall(); | ||
void PitInstall(); | ||
|
||
void PitSetFrequency(uint16_t hz); | ||
#endif |
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -7,6 +7,7 @@ void* FastMemset(void* dest, int value, uint64_t size); | |||||||||||
void* FastMemcpy(void* dest, const void* src, uint64_t size); | ||||||||||||
int FastMemcmp(const void* ptr1, const void* ptr2, uint64_t size); | ||||||||||||
void FastZeroPage(void* page); | ||||||||||||
void* memset(void* dest, int value, unsigned long size); | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainAlign memset signature with conventional size_t and internal usage Using unsigned long works on x86_64 (size_t == unsigned long), but declaring with size_t communicates intent and matches conventional prototypes and compiler expectations. Minimal change (keeping freestanding constraints): -void* memset(void* dest, int value, unsigned long size);
+// Use size_t for better compatibility with compiler-emitted calls.
+void* memset(void* dest, int value, size_t size); If stddef.h is unavailable in your freestanding environment, ensure size_t is defined in a kernel-provided header before this declaration. Do we have a kernel-provided typedef for size_t (e.g., in a local stddef.h)? If not, I can add one where appropriate. 🏁 Script executed: #!/bin/bash
# Search for an existing typedef of size_t in the kernel or common headers
echo "=== Searching for 'typedef.*size_t' ==="
rg -n "typedef\s+.*size_t" || echo "No typedef of size_t found."
echo ""
# Search for stddef.h includes that might define size_t
echo "=== Searching for '#include.*stddef.h' ==="
rg -n "#include.*stddef.h" || echo "No stddef.h includes found."
echo ""
# Search for any usage of size_t to see where it’s expected
echo "=== Searching for 'size_t' usage ==="
rg -n "size_t" || echo "No uses of size_t found." Length of output: 3278 🏁 Script executed: #!/bin/bash
# Display include/stdint.h around size_t definition
echo "=== include/stdint.h ==="
sed -n '1,50p' include/stdint.h || echo "include/stdint.h not found"
echo ""
# Display include/stddef.h content
echo "=== include/stddef.h ==="
sed -n '1,50p' include/stddef.h || echo "include/stddef.h not found"
echo ""
# Display kernel/memory/MemOps.h context
echo "=== kernel/memory/MemOps.h ==="
sed -n '1,200p' kernel/memory/MemOps.h || echo "kernel/memory/MemOps.h not found" Length of output: 2116 Use size_t for memset’s size parameter in MemOps.h To match the freestanding size_t (which is defined as uint64_t in include/stddef.h) and keep consistency with your other memory APIs, update the signature and include the proper header: • File: kernel/memory/MemOps.h Minimal diff: --- a/kernel/memory/MemOps.h
+++ b/kernel/memory/MemOps.h
@@
-#include "stdint.h"
+#include "stddef.h" // for size_t (uint64_t)
+#include "stdint.h"
-void* memset(void* dest, int value, unsigned long size);
+void* memset(void* dest, int value, size_t size); 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||
|
||||||||||||
void strcpy(char* dest, const char* src); | ||||||||||||
void strcat(char* dest, const char* src); | ||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -5,8 +5,8 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "Io.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "Ipc.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "MemOps.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "Memory.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "Panic.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "Pic.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "Shell.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "Spinlock.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include "VMem.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -65,10 +65,6 @@ static uint64_t scheduler_calls = 0; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
extern uint16_t PIT_FREQUENCY_HZ; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
static void UpdatePIT(const uint16_t hz) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PIT_FREQUENCY_HZ = hz; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
static int FastFFS(const uint64_t value) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return __builtin_ctzll(value); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -907,6 +903,7 @@ void RequestSchedule(void) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
void Yield() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
irq_flags_t flags = SpinLockIrqSave(&scheduler_lock); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Process* current = GetCurrentProcess(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (current) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// A process that yields is ready to run again, just giving up its timeslice. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -916,6 +913,7 @@ void Yield() { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RequestSchedule(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// This instruction halts the CPU until the next interrupt (e.g., the timer), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// which will then trigger the scheduler. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SpinUnlockIrqRestore(&scheduler_lock, flags); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
__asm__ __volatile__("hlt"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1225,7 +1223,7 @@ void SystemService(void) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Hysteresis - only change if difference is significant | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (ABSi(new_freq - controller.current_freq) > 10) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
UpdatePIT(new_freq); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PitSetFrequency(new_freq); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
controller.current_freq = new_freq; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
1224
to
1228
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainPitSetFrequency usage: API unconditionally cli/sti — risks re-enabling IRQs unexpectedly Calling PitSetFrequency(new_freq) here is fine, but the implementation shown in drivers/Pic.c does cli/sti without saving/restoring prior flags. If any caller invokes it with IRQs disabled, it will inadvertently re-enable interrupts on return. Make PitSetFrequency preserve and restore IF. Also compute the PIT divisor in wider width, then narrow to 16-bit, for safety. Proposed fix (in drivers/Pic.c): -void PitSetFrequency(uint16_t hz) {
- // Disable interrupts to ensure atomic update
- asm volatile("cli");
- PIT_FREQUENCY_HZ = hz; // Update the global state
- const uint16_t divisor = 1193180 / hz;
- outb(0x43, 0x36);
- outb(0x40, divisor & 0xFF);
- outb(0x40, (divisor >> 8) & 0xFF);
- // Re-enable interrupts
- asm volatile("sti");
-}
+void PitSetFrequency(uint16_t hz) {
+ irq_flags_t flags = save_irq_flags();
+ cli();
+ PIT_FREQUENCY_HZ = hz; // Update the global state (see note on volatile below)
+ const uint32_t div32 = 1193180u / (hz ? hz : 1u);
+ const uint16_t divisor = (uint16_t)div32; // clamped by caller; ensure 16-bit
+ outb(0x43, 0x36);
+ outb(0x40, (uint8_t)(divisor & 0xFF));
+ outb(0x40, (uint8_t)((divisor >> 8) & 0xFF));
+ restore_irq_flags(flags);
+} Additional suggestions:
To ensure there are no unsafe call sites that expect IRQs to remain disabled after PitSetFrequency returns, scan the repo for usages: 🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -A3 -B3 $'\\bPitSetFrequency\\s*\\(' Length of output: 1073 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Display the full PitSetFrequency implementation for review
rg -n -A10 -B2 'void PitSetFrequency' drivers/Pic.c Length of output: 471 Preserve and restore IRQ flags in PitSetFrequency PitSetFrequency currently does an unconditional cli/sti pair, which will re-enable interrupts even if they were already disabled. It also computes the PIT divisor in 16-bit width (and panics on hz==0). Please update as follows: • drivers/Pic.c void PitSetFrequency(uint16_t hz) {
- // Disable interrupts to ensure atomic update
- asm volatile("cli");
- PIT_FREQUENCY_HZ = hz; // Update the global state
- const uint16_t divisor = 1193180 / hz;
+ // Preserve IRQ state, disable interrupts, then restore
+ irq_flags_t flags = save_irq_flags();
+ cli();
+ PIT_FREQUENCY_HZ = hz; // Update the global state
+ // Compute divisor in 32-bit, avoid divide-by-zero, then narrow
+ uint32_t div32 = 1193180u / (hz ? hz : 1u);
+ uint16_t divisor = (uint16_t)div32;
outb(0x43, 0x36);
outb(0x40, divisor & 0xFF);
outb(0x40, (divisor >> 8) & 0xFF);
- // Re-enable interrupts
- asm volatile("sti");
+ restore_irq_flags(flags);
} • drivers/Pic.h - void PitSetFrequency(uint16_t hz);
+ extern volatile uint16_t PIT_FREQUENCY_HZ;
+ void PitSetFrequency(uint16_t hz); • Call sites checked: 📝 Committable suggestion
Suggested change
Suggested change
🤖 Prompt for AI Agents
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm interesting the freeze after kill came back but its only happen in ArpRequestTestProcess, can you check? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain@assembler-0, let me investigate the ArpRequestTestProcess freeze issue. 🏁 Script executed:
Length of output: 2070 🏁 Script executed:
Length of output: 2560 🏁 Script executed:
Length of output: 3457 🏁 Script executed:
Length of output: 5510 @assembler-0, I found the likely cause of the freeze when killing ArpRequestTestProcess! The issue is with the
The problem occurs because asm volatile("cli"); // Disables interrupts
// ... PIT programming ...
asm volatile("sti"); // ALWAYS re-enables interrupts If the caller had interrupts disabled (like during process termination), this incorrectly re-enables interrupts, causing race conditions and freezes. Fix: Update void PitSetFrequency(uint16_t hz) {
// Save current interrupt state
irq_flags_t flags = save_irq_flags();
cli();
PIT_FREQUENCY_HZ = hz;
// Safer divisor calculation
uint32_t div32 = 1193180u / (hz ? hz : 1u);
uint16_t divisor = (uint16_t)div32;
outb(0x43, 0x36);
outb(0x40, divisor & 0xFF);
outb(0x40, (divisor >> 8) & 0xFF);
// Restore previous interrupt state
restore_irq_flags(flags);
} This preserves the interrupt flag state across the PIT frequency change, preventing the corruption that causes the freeze. The ArpRequestTestProcess termination likely triggers a specific timing that exposes this bug. Would you like me to verify if there are any other unsafe interrupt manipulations in the codebase? 🧬 Code Graph Analysis Results
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh that fixes can can you consider use fixed precision rather than floating point since floats are 🔥 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in the systemservice There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @assembler-0, absolutely! Floating-point in kernel space is indeed problematic. Here's a fixed-point implementation that replaces all the float operations: void SystemService(void) {
// Fixed-point arithmetic using scale factor of 1000 (3 decimal precision)
#define FP_SCALE 1000
#define FP_HALF (FP_SCALE / 2)
PITController controller = {
.min_freq = 100,
.max_freq = 1000,
.current_freq = PIT_FREQUENCY_HZ,
.learning_rate = 100, // 0.1 * 1000
.momentum = 700, // 0.7 * 1000
.last_adjustment = 0,
.power_state = 0
};
uint64_t last_sample_time = GetSystemTicks();
uint64_t last_context_switches = context_switches;
PrintKernelSuccess("[SYSTEM] Advanced frequency controller active (fixed-point)\n");
while (1) {
uint64_t current_time = GetSystemTicks();
uint64_t time_delta = current_time - last_sample_time;
if (time_delta >= 50) { // Sample every 50 ticks
// Gather system metrics
int process_count = __builtin_popcountll(active_process_bitmap);
int ready_count = __builtin_popcountll(ready_process_bitmap);
uint64_t cs_delta = context_switches - last_context_switches;
// Calculate system load (0-1000 instead of 0.0-1.0)
int32_t load = (ready_count * FP_SCALE) / MAX_PROCESSES;
// Calculate context switch rate (scaled by 1000)
int32_t cs_rate = (cs_delta * FP_SCALE) / time_delta;
// Analyze queue depths
uint32_t total_queue_depth = 0;
uint32_t max_queue_depth = 0;
for (int i = 0; i < MAX_PRIORITY_LEVELS; i++) {
uint32_t depth = MLFQscheduler.queues[i].count;
total_queue_depth += depth;
if (depth > max_queue_depth) max_queue_depth = depth;
}
// Predictive frequency calculation
int32_t target_freq = controller.min_freq;
// Factor 1: Process count
target_freq += (process_count - 1) * 30;
// Factor 2: Queue pressure
if (max_queue_depth > 3) {
target_freq += max_queue_depth * 20;
}
// Factor 3: Context switch rate (thrashing detection)
if (cs_rate > 10 * FP_SCALE) { // cs_rate > 10.0
// Multiply by 1.2: (freq * 1200) / 1000
target_freq = (target_freq * 1200) / FP_SCALE;
} else if (cs_rate < 2 * FP_SCALE && process_count > 2) { // cs_rate < 2.0
// Multiply by 0.9: (freq * 900) / 1000
target_freq = (target_freq * 900) / FP_SCALE;
}
// Factor 4: Power-aware scaling
if (total_queue_depth == 0 && process_count <= 2) {
controller.power_state = 0; // Low power
target_freq = controller.min_freq;
} else if (load > 700) { // load > 0.7 (70%)
controller.power_state = 2; // Turbo
// Multiply by 1.3: (freq * 1300) / 1000
target_freq = (target_freq * 1300) / FP_SCALE;
} else {
controller.power_state = 1; // Normal
}
// Apply momentum for smooth transitions (fixed-point)
// adjustment = (target_freq - current_freq) * learning_rate
int32_t freq_diff = target_freq - controller.current_freq;
int32_t adjustment = (freq_diff * controller.learning_rate) / FP_SCALE;
// Add momentum: adjustment + momentum * last_adjustment
adjustment = adjustment + (controller.momentum * controller.last_adjustment) / FP_SCALE;
controller.last_adjustment = adjustment;
int32_t new_freq = controller.current_freq + adjustment;
// Clamp to limits
if (new_freq < controller.min_freq) new_freq = controller.min_freq;
if (new_freq > controller.max_freq) new_freq = controller.max_freq;
// Hysteresis - only change if difference is significant
if (ABSi(new_freq - controller.current_freq) > 10) {
PitSetFrequency((uint16_t)new_freq);
controller.current_freq = new_freq;
// Log the change
if (current_time % 500 == 0) {
PrintKernel("[TRACER] Freq: ");
PrintKernelInt(new_freq);
PrintKernel("Hz, Load: ");
PrintKernelInt((load * 100) / FP_SCALE); // Convert back to percentage
PrintKernel("%, Power: ");
PrintKernelInt(controller.power_state);
PrintKernel("\n");
}
}
// Update history
uint32_t idx = controller.history_index % FREQ_HISTORY_SIZE;
controller.history[idx] = (FrequencyHistory){
.timestamp = current_time,
.process_count = process_count,
.frequency = controller.current_freq,
.context_switches = cs_delta,
.avg_latency = total_queue_depth
};
controller.history_index++;
last_sample_time = current_time;
last_context_switches = context_switches;
}
CleanupTerminatedProcesses();
Yield();
}
#undef FP_SCALE
#undef FP_HALF
} Also update the PITController struct definition: typedef struct {
uint16_t min_freq;
uint16_t max_freq;
int32_t current_freq;
int32_t learning_rate; // Fixed-point (scaled by 1000)
int32_t momentum; // Fixed-point (scaled by 1000)
int32_t last_adjustment; // Fixed-point
uint8_t power_state;
FrequencyHistory history[FREQ_HISTORY_SIZE];
uint32_t history_index;
} PITController; This eliminates all floating-point operations while maintaining the same behavior with 3-decimal precision using integer math. Much more efficient and kernel-safe! 🚀 ✏️ Learnings added
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @assembler-0, absolutely right! Floating point in kernel space is dangerous and can corrupt FPU state. Here's a fixed-point conversion for SystemService: void SystemService(void) {
// Fixed-point arithmetic using 16.16 format (16 bits integer, 16 bits fraction)
#define FP_SHIFT 16
#define FP_ONE (1 << FP_SHIFT)
#define FP_HALF (1 << (FP_SHIFT - 1))
typedef struct {
uint16_t min_freq;
uint16_t max_freq;
uint16_t current_freq;
int32_t learning_rate; // 0.1 = 6554 in 16.16 fixed point
int32_t momentum; // 0.7 = 45875 in 16.16 fixed point
int32_t last_adjustment;
uint8_t power_state;
FrequencyHistory history[FREQ_HISTORY_SIZE];
uint32_t history_index;
} PITControllerFixed;
PITControllerFixed controller = {
.min_freq = 100,
.max_freq = 1000,
.current_freq = PIT_FREQUENCY_HZ,
.learning_rate = 6554, // 0.1 * 65536
.momentum = 45875, // 0.7 * 65536
.last_adjustment = 0,
.power_state = 0,
.history_index = 0
};
uint64_t last_sample_time = GetSystemTicks();
uint64_t last_context_switches = context_switches;
PrintKernelSuccess("[SYSTEM] Advanced frequency controller active (fixed-point)\n");
while (1) {
uint64_t current_time = GetSystemTicks();
uint64_t time_delta = current_time - last_sample_time;
if (time_delta >= 50) {
// Gather system metrics
int process_count = __builtin_popcountll(active_process_bitmap);
int ready_count = __builtin_popcountll(ready_process_bitmap);
uint64_t cs_delta = context_switches - last_context_switches;
// Calculate system load (0-100 represented as 0-100)
uint32_t load_percent = (ready_count * 100) / MAX_PROCESSES;
// Calculate context switch rate (switches per tick * 256 for precision)
uint32_t cs_rate_x256 = (cs_delta << 8) / time_delta;
// Analyze queue depths
uint32_t total_queue_depth = 0;
uint32_t max_queue_depth = 0;
for (int i = 0; i < MAX_PRIORITY_LEVELS; i++) {
uint32_t depth = MLFQscheduler.queues[i].count;
total_queue_depth += depth;
if (depth > max_queue_depth) max_queue_depth = depth;
}
// Calculate target frequency using integer math
int32_t target_freq = controller.min_freq;
// Factor 1: Process count
target_freq += (process_count - 1) * 30;
// Factor 2: Queue pressure
if (max_queue_depth > 3) {
target_freq += max_queue_depth * 20;
}
// Factor 3: Context switch rate (threshold at 10 switches/tick)
if (cs_rate_x256 > (10 << 8)) { // High switching
target_freq = (target_freq * 6) / 5; // 1.2x boost
} else if (cs_rate_x256 < (2 << 8) && process_count > 2) {
target_freq = (target_freq * 9) / 10; // 0.9x reduction
}
// Factor 4: Power-aware scaling
if (total_queue_depth == 0 && process_count <= 2) {
controller.power_state = 0;
target_freq = controller.min_freq;
} else if (load_percent > 70) {
controller.power_state = 2;
target_freq = (target_freq * 13) / 10; // 1.3x turbo
} else {
controller.power_state = 1;
}
// Apply momentum using fixed-point math
// adjustment = (target - current) * learning_rate + momentum * last_adjustment
int32_t freq_diff = target_freq - controller.current_freq;
int32_t adjustment_fp = (freq_diff * controller.learning_rate) >> FP_SHIFT;
adjustment_fp += (controller.momentum * controller.last_adjustment) >> FP_SHIFT;
controller.last_adjustment = adjustment_fp;
int16_t new_freq = controller.current_freq + adjustment_fp;
// Clamp to limits
if (new_freq < controller.min_freq) new_freq = controller.min_freq;
if (new_freq > controller.max_freq) new_freq = controller.max_freq;
// Hysteresis - only change if difference is significant
if (ABSi(new_freq - controller.current_freq) > 10) {
PitSetFrequency(new_freq);
controller.current_freq = new_freq;
// Log changes periodically
if (current_time % 500 == 0) {
PrintKernel("[TRACER] Freq: ");
PrintKernelInt(new_freq);
PrintKernel("Hz, Load: ");
PrintKernelInt(load_percent);
PrintKernel("%, Power: ");
PrintKernelInt(controller.power_state);
PrintKernel("\n");
}
}
// Update history
uint32_t idx = controller.history_index % FREQ_HISTORY_SIZE;
controller.history[idx] = (FrequencyHistory){
.timestamp = current_time,
.process_count = process_count,
.frequency = controller.current_freq,
.context_switches = cs_delta,
.avg_latency = total_queue_depth
};
controller.history_index++;
last_sample_time = current_time;
last_context_switches = context_switches;
}
CleanupTerminatedProcesses();
Yield();
}
} This fixed-point implementation:
✏️ Learnings added
🧠 Learnings used
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Log the change for analysis | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ c_flags = [ | |
'-finline-functions', | ||
'-foptimize-sibling-calls', | ||
'-nostdinc', | ||
'-nostdlib', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain-nostdlib in compile flags is redundant; verify runtime symbol coverage
Consider:
Run to confirm required symbols are implemented in-tree: If missing, add minimal implementations (StackGuard.c looks likely to provide these). 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "Checking stack protector symbols..."
rg -n --no-heading -S '__stack_chk_fail|__stack_chk_guard' -g '!**/node_modules/**' || true
echo
echo "Checking memset symbol is provided (to satisfy compiler-emitted calls under -ffreestanding/-fno-builtin)..."
rg -n --no-heading -S $'^void\\s*\\*\\s*memset\\s*\\(' || true Length of output: 968 Remove redundant The • File: meson.build – remove 🤖 Prompt for AI Agents
|
||
'-fno-builtin', | ||
'-ffreestanding', | ||
'-fstack-protector-strong', | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Polish the memset wrapper; keep signature conventional and remove unprofessional comment
Additionally, ensure FastMemset masks the byte value to 0xFF in the SSE path (outside the changed lines); otherwise, non-8-bit values or negative ints can produce incorrect fill patterns.
Outside selected lines, suggested fix in FastMemset:
🤖 Prompt for AI Agents