feat: promote green threads from develop to main#15
Merged
Conversation
…, and async I/O Introduces cooperative multitasking to O²L: - `spawn <expr>` keyword: launches a new coroutine that runs cooperatively within the same OS thread (SpawnNode AST node, Lexer/Parser support) - `Scheduler` (singleton run-loop): drives coroutines via a ready_queue_, timer_queue_, suspended_ map, and thread-safe IO completion queue - `Coroutine`: owns body ASTNode + cloned Context; carries state (Ready/Running/Suspended/Completed/Failed) with block_resume_stack for nested block resumption - `ChannelInstance`: buffered/unbuffered channel for send/receive between coroutines; senders suspend when full, receivers suspend when empty - `ConcurrencyLibrary`: exposes `Channel.new(capacity)` and `io.sleep(ms)` / `io.yield()` to O²L programs - `IOThreadPool`: fixed thread pool offloading blocking I/O; uses thread-safe `enqueueReady` to post completions back to the scheduler - `Context::clone()`: deep-copies variable bindings for coroutine isolation - `CArray.fromList()`: copies a ListInstance into a CArrayInstance for FFI - BlockNode/WhileStatementNode: use block_resume_stack for correct nested coroutine resumption - Cross-platform: MSVC Value variant alias, unistd.h for macOS/Linux, holds_Int_Value/holds_Long_Value helpers, Windows socket defines All existing tests pass; adds 9 new concurrency test suites.
…lures - Parser: accept keyword 'new' as method name after '.' so Channel.new() parses correctly (fixes ConcurrencyTest.channel_basic and ConcurrencyTest.concurrency_advanced) - Scheduler: store root coroutine exception in root_exception_ and expose it via getRootException(); clear on reset() - Interpreter: rethrow root coroutine exception after scheduler.run() so EvaluationErrors propagate to callers (fixes IntegrationTest DemoAccessError and ErrorHandling)
…plementation - Fix YieldNode ODR violation between test_resume_logic.cpp and test_suspend_exception.cpp by wrapping each in anonymous namespaces (root cause of MSVC 0xc0000005 crash — linker picked wrong vtable) - Fix YieldNode to check hasResumeValue() before yielding to prevent infinite re-suspension on resume - Remove debug cerr prints from BlockNode, WhileStatementNode, Scheduler - Remove unused <iostream> includes from BlockNode and WhileStatementNode - Use EXPECT_EQ instead of assert in test_resume_logic - Parser: simplify Channel.new() member name token handling - Context::clone(): preserve this_stack_ for spawn inside object methods
- yield_in_false_loop: while(false) body never executes yield - yield_single_iteration: loop terminates on first resume (condition false) - yield_deeply_nested: 3 levels of BlockNode nesting exercises block_resume_stack depth
- root_exception_captured: root coroutine error stored in root_exception_, rethrowable - non_root_exception_ignored: non-root errors don't set root_exception_ - root_exception_null_on_success: successful root leaves root_exception_ null
…mption - error_after_resume: yield then throw on resume, verify root_exception_ captured - scheduler_clean_after_run: isActive()==false after success, error, and yield+error - error_in_condition_after_resume: condition throws after yield-resume cycle completes
- yield_nested_inner_loop: yield in inner while-while, 4 yields across 2*2 iterations - yield_nested_outer_body: yield in outer body after inner loop completes, 2 yields Both exercise block_resume_stack at 4+ nesting levels
- channel_producer_consumer_values: producer sends 3 values via channel, consumer sums them - three_coroutine_round_robin: 3 coroutines yield to shared log, verify deterministic order
- channel_multiple_producers: 2 producers send to one buffered channel - channel_multiple_consumers: 2 consumers receive from one buffered channel - channel_unbuffered_blocking: sender blocks until receiver is ready - channel_buffered_full: sender blocks when buffer at capacity
- suspend_for_io_basic: IO lambda result delivered to coroutine on resume - suspend_for_io_different_thread: IO work runs on a background thread - suspend_for_io_multiple: 3 concurrent IO suspensions all complete correctly
feat: add green threads (cooperative concurrency) with spawn, Channel, and async I/O
- Add return type `: Unit` on workerRoutine method - Add `@external` annotation for cross-object method access - Use `sleep()` instead of `io.sleep()` - Send Int values via channel instead of string concatenation - Verified: runs successfully, 3 workers communicate via channel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
developintomaindevelopdiverged from the currentmaintip (90207e2) and adds only green threads — zero conflictsspawn,Channel,Scheduler,Coroutine,IOThreadPool,ConcurrencyLibraryWhat's included
src/Runtime/Scheduler,Coroutine,CoroutineHandle,ChannelInstance,IOThreadPool,ConcurrencyLibrarysrc/AST/SpawnNode— new AST node forspawnkeywordspawnandChannelbuilt-intest_scheduler,test_channel_basic/edge_cases,test_io_thread_pool,test_root_exception,test_shared_state,test_concurrency_advanced, etc.)examples/concurrency.obq