mirror of
https://github.com/goplus/llgo.git
synced 2025-09-26 19:51:21 +08:00

- Consolidate _demo, _pydemo, _embdemo into single _demo directory structure - Organize demos by language: _demo/{go,py,c,embed}/ - Categorize demos based on imports: - Python library demos (py imports) → _demo/py/ - C/C++ library demos (c/cpp imports) → _demo/c/ - Go-specific demos → _demo/go/ - Embedded demos → _demo/embed/ - Move C-related demos (asm*, cabi*, cgo*, linkname, targetsbuild) from go/ to c/ - Update all path references in README.md and GitHub workflows - Improve demo organization and navigation as requested in #1256 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
113 lines
2.4 KiB
Go
113 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
// Counter represents a thread-safe counter
|
|
type Counter struct {
|
|
mu sync.Mutex
|
|
value int64
|
|
}
|
|
|
|
// Increment increases the counter value by 1
|
|
func (c *Counter) Increment() {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
c.value++
|
|
}
|
|
|
|
// GetValue returns the current value of the counter
|
|
func (c *Counter) GetValue() int64 {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
return c.value
|
|
}
|
|
|
|
// Constant values for the test
|
|
const (
|
|
numGoroutines = 64
|
|
numIterations = 10000
|
|
expectedTotal = numGoroutines * numIterations
|
|
)
|
|
|
|
func main() {
|
|
// Create a new counter instance
|
|
counter := &Counter{}
|
|
|
|
// Create a wait group to wait for all goroutines to finish
|
|
var wg sync.WaitGroup
|
|
|
|
// Track active goroutines for monitoring
|
|
var activeGoroutines int32
|
|
|
|
// Start time
|
|
startTime := time.Now()
|
|
|
|
// Launch goroutines
|
|
for i := 0; i < numGoroutines; i++ {
|
|
wg.Add(1)
|
|
atomic.AddInt32(&activeGoroutines, 1)
|
|
|
|
go func(id int) {
|
|
defer func() {
|
|
wg.Done()
|
|
atomic.AddInt32(&activeGoroutines, -1)
|
|
}()
|
|
|
|
// Each goroutine increments the counter numIterations times
|
|
for j := 0; j < numIterations; j++ {
|
|
counter.Increment()
|
|
|
|
// Simulate varying workload with random sleeps
|
|
if j%100 == 0 {
|
|
time.Sleep(time.Microsecond)
|
|
}
|
|
}
|
|
fmt.Printf("Goroutine %d finished\n", id)
|
|
}(i)
|
|
}
|
|
|
|
// Monitor progress in a separate goroutine
|
|
go func() {
|
|
for {
|
|
active := atomic.LoadInt32(&activeGoroutines)
|
|
if active == 0 {
|
|
break
|
|
}
|
|
fmt.Printf("Active goroutines: %d\n", active)
|
|
time.Sleep(time.Second)
|
|
}
|
|
}()
|
|
|
|
// Wait for all goroutines to complete
|
|
wg.Wait()
|
|
|
|
// Calculate execution time
|
|
duration := time.Since(startTime)
|
|
|
|
// Get and verify the final result
|
|
finalValue := counter.GetValue()
|
|
fmt.Printf("\nExecution completed in: %v\n", duration)
|
|
fmt.Printf("Final counter value: %d\n", finalValue)
|
|
fmt.Printf("Expected value: %d\n", expectedTotal)
|
|
|
|
// Assert the result
|
|
if finalValue != expectedTotal {
|
|
panic(fmt.Sprintf("ERROR: Counter value mismatch! Expected %d, got %d\n",
|
|
expectedTotal, finalValue))
|
|
} else {
|
|
fmt.Printf("SUCCESS: Counter value matches expected total\n")
|
|
}
|
|
|
|
// Print some statistics
|
|
opsPerSecond := float64(expectedTotal) / duration.Seconds()
|
|
fmt.Printf("\nStatistics:\n")
|
|
fmt.Printf("Operations per second: %.2f\n", opsPerSecond)
|
|
fmt.Printf("Average time per operation: %.2f ns\n",
|
|
float64(duration.Nanoseconds())/float64(expectedTotal))
|
|
}
|