wip: 重新整理 install cmd

This commit is contained in:
zhaoyupeng
2026-01-13 20:13:29 +08:00
parent fcbaa5be2f
commit 760784a5ac
15 changed files with 957 additions and 665 deletions

144
pkg/syscheck/mem.go Normal file
View File

@@ -0,0 +1,144 @@
package syscheck
import (
"context"
"crypto/rand"
"fmt"
"time"
"golang.org/x/sys/unix"
)
// GetMemorySpace returns total physical memory (RAM) in bytes, excluding swap
func GetMemorySpace(ctx context.Context) (int64, error) {
var info unix.Sysinfo_t
if err := unix.Sysinfo(&info); err != nil {
return 0, fmt.Errorf("failed to get memory info: %w", err)
}
// Total physical RAM (excluding swap)
// info.Totalram is in memory unit size (info.Unit)
totalMemory := int64(info.Totalram) * int64(info.Unit)
return totalMemory, nil
}
// GetMemorySpeed measures memory read/write speed by allocating and accessing memory
// Returns read speed and write speed in bytes per second
func GetMemorySpeed(ctx context.Context) (int64, int64, error) {
const (
testSize = 512 * 1024 * 1024 // 512MB test size
iterations = 5 // Number of iterations for averaging
)
// Test write speed
writeSpeed, err := measureMemoryWriteSpeed(ctx, testSize, iterations)
if err != nil {
return 0, 0, fmt.Errorf("failed to measure memory write speed: %w", err)
}
// Test read speed
readSpeed, err := measureMemoryReadSpeed(ctx, testSize, iterations)
if err != nil {
return 0, 0, fmt.Errorf("failed to measure memory read speed: %w", err)
}
return readSpeed, writeSpeed, nil
}
// measureMemoryWriteSpeed measures memory write speed
func measureMemoryWriteSpeed(ctx context.Context, size int64, iterations int) (int64, error) {
var totalDuration time.Duration
for i := 0; i < iterations; i++ {
// Check context cancellation
select {
case <-ctx.Done():
return 0, ctx.Err()
default:
}
// Allocate memory buffer
buffer := make([]byte, size)
// Generate random data
source := make([]byte, 1024*1024) // 1MB source buffer
if _, err := rand.Read(source); err != nil {
return 0, fmt.Errorf("failed to generate random data: %w", err)
}
// Start timing
startTime := time.Now()
// Write data to memory buffer
for offset := int64(0); offset < size; offset += int64(len(source)) {
remaining := size - offset
if remaining < int64(len(source)) {
copy(buffer[offset:], source[:remaining])
} else {
copy(buffer[offset:offset+int64(len(source))], source)
}
}
// Stop timing
duration := time.Since(startTime)
totalDuration += duration
// Force the buffer to be used to prevent optimization
_ = buffer[0]
}
// Calculate average speed
avgDuration := totalDuration / time.Duration(iterations)
speed := int64(float64(size) / avgDuration.Seconds())
return speed, nil
}
// measureMemoryReadSpeed measures memory read speed
func measureMemoryReadSpeed(ctx context.Context, size int64, iterations int) (int64, error) {
var totalDuration time.Duration
// Pre-allocate and fill buffer
buffer := make([]byte, size)
if _, err := rand.Read(buffer); err != nil {
return 0, fmt.Errorf("failed to initialize buffer: %w", err)
}
for i := 0; i < iterations; i++ {
// Check context cancellation
select {
case <-ctx.Done():
return 0, ctx.Err()
default:
}
// Start timing
startTime := time.Now()
// Read data from memory buffer
var sum int64
for offset := int64(0); offset < size; offset += 1024 {
// Read in chunks to simulate real access patterns
end := offset + 1024
if end > size {
end = size
}
for j := offset; j < end; j++ {
sum += int64(buffer[j])
}
}
// Stop timing
duration := time.Since(startTime)
totalDuration += duration
// Use sum to prevent optimization
_ = sum
}
// Calculate average speed
avgDuration := totalDuration / time.Duration(iterations)
speed := int64(float64(size) / avgDuration.Seconds())
return speed, nil
}