From 4d11f83f706416c255374517efdcb82d37e42819 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 26 Nov 2024 13:57:00 -0500 Subject: Add some examples to the repo --- examples/threads/threads.tm | 106 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 examples/threads/threads.tm (limited to 'examples/threads/threads.tm') diff --git a/examples/threads/threads.tm b/examples/threads/threads.tm new file mode 100644 index 00000000..8be568cd --- /dev/null +++ b/examples/threads/threads.tm @@ -0,0 +1,106 @@ +use + +struct Mutex(_mutex:@Memory): + func new(->Mutex): + return Mutex( + inline C : @Memory { + pthread_mutex_t *mutex = new(pthread_mutex_t); + pthread_mutex_init(mutex, NULL); + GC_register_finalizer(mutex, (void*)pthread_mutex_destroy, NULL, NULL, NULL); + mutex + } + ) + + func do_locked(m:Mutex, fn:func(); inline): + inline C { + pthread_mutex_lock((pthread_mutex_t*)$m.$_mutex); + } + fn() + inline C { + pthread_mutex_unlock((pthread_mutex_t*)$m.$_mutex); + } + +struct ThreadCondition(_cond:@Memory): + func new(->ThreadCondition): + return ThreadCondition( + inline C : @Memory { + pthread_cond_t *cond = new(pthread_cond_t); + pthread_cond_init(cond, NULL); + GC_register_finalizer(cond, (void*)pthread_cond_destroy, NULL, NULL, NULL); + cond + } + ) + + func wait(c:ThreadCondition, m:Mutex; inline): + inline C { + pthread_cond_wait((pthread_cond_t*)$c.$_cond, (pthread_mutex_t*)$m.$_mutex); + } + + func signal(c:ThreadCondition; inline): + inline C { + pthread_cond_signal((pthread_cond_t*)$c.$_cond); + } + + func broadcast(c:ThreadCondition; inline): + inline C { + pthread_cond_broadcast((pthread_cond_t*)$c.$_cond); + } + +struct Guard(mutex=Mutex.new(), cond=ThreadCondition.new()): + func guarded(g:Guard, fn:func(); inline): + g.mutex:do_locked(fn) + g.cond:signal() + + func wait(g:Guard): + g.cond:wait(g.mutex) + +struct PThread(_thread:@Memory): + func new(fn:func() -> PThread): + return PThread( + inline C : @Memory { + pthread_t *thread = new(pthread_t); + pthread_create(thread, NULL, $fn.fn, $fn.userdata); + thread + } + ) + + func join(t:PThread): + inline C { + pthread_join(*(pthread_t*)$t.$_thread, NULL); + } + + func cancel(t:PThread): + inline C { + pthread_cancel(*(pthread_t*)$t.$_thread); + } + + func detatch(t:PThread): + inline C { + pthread_detach(*(pthread_t*)$t.$_thread); + } + +func main(): + g := Guard() + queue := @[10, 20] + + t := PThread.new(func(): + say("In another thread!") + item := @NONE:Int + while item[] != 30: + g:guarded(func(): + while queue.length == 0: + g:wait() + + item[] = queue[1] + queue:remove_at(1) + ) + say("Processing: $item") + sleep(0.01) + say("All done!") + ) + >> t + >> sleep(1) + >> g:guarded(func(): + queue:insert(30) + ) + >> t:join() -- cgit v1.2.3