Coroutines for PB [Windows / Linux]

Share your advanced PureBasic knowledge/code with the community.
Justin
Addict
Addict
Posts: 948
Joined: Sat Apr 26, 2003 2:49 pm

Coroutines for PB [Windows / Linux]

Post by Justin »

Hi,

This has been a weekend project so it will need more documentation and testing, i wanted coroutines in PB.
Coroutines are resumable functions that can be paused and resumed, something like the async / await pattern.
I used libaco for linux:
https://github.com/hnes/libaco
And the fibers api for Windows:
https://learn.microsoft.com/en-us/windo ... ead/fibers

libaco should compile for macos but i haven't tried it.

Project at github:
https://github.com/omegakode/PBCoroutines

A coroutine procedure accepts a single paramter, the coroutine handle, that you use with the co_*() functions, a coroutine must be always exited with co_exit().
See example:

Code: Select all

;PBCoroutines_Test.pb

EnableExplicit

XIncludeFile "PBCoroutines.pb"

Procedure.l co_function(*co.co_handle)
	Protected.l x
	
	Debug "co_function start"
	
	x = 0
	
	For x = 1 To 5
		Debug "co_function " + Str(x)
		
		co_put_arg(*co, x)
		co_yield(*co) ;switch to main
	Next 
	
	Debug "co_function end"
	
	co_exit(*co)
EndProcedure

Procedure main()
	Protected.co_handle *mainCo, *co
	
	co_lib_init() ;init lib
	
	co_thread_init() ;init thread
	
	;main coroutine
	*mainCo = co_create(#Null, #Null, #Null)
	
	;child coroutine
	*co = co_create(*mainCo, @co_function(), 0)

	While Not co_ended(*co)
		co_resume(*co) ;switch to co_function
		
		If Not co_ended(*co) ;check if ended after last resume
			Debug "main " + Str(co_get_arg(*co))
		EndIf
	Wend 

	Debug "main done"
	
	co_destroy(*co)
	
	co_lib_shutdown() ;close lib
EndProcedure

main()
Justin
Addict
Addict
Posts: 948
Joined: Sat Apr 26, 2003 2:49 pm

Re: Coroutines for PB [Windows / Linux]

Post by Justin »

The file asm.pb was missing, now is fixed. i think it was idle who did these asm helpers.
User avatar
idle
Always Here
Always Here
Posts: 5888
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Coroutines for PB [Windows / Linux]

Post by idle »

Should be useful thanks for the share
Justin
Addict
Addict
Posts: 948
Joined: Sat Apr 26, 2003 2:49 pm

Re: Coroutines for PB [Windows / Linux]

Post by Justin »

For someone who knows asm should not be very difficult to implement it directly in PB without any lib, here is some explanation:
https://graphitemaster.github.io/fibers ... primitives
User avatar
idle
Always Here
Always Here
Posts: 5888
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Coroutines for PB [Windows / Linux]

Post by idle »

Justin wrote: Wed Feb 19, 2025 10:11 pm For someone who knows asm should not be very difficult to implement it directly in PB without any lib, here is some explanation:
https://graphitemaster.github.io/fibers ... primitives
Thanks, that's probably the clearest explanation of fibers I've read.
User avatar
Skipper
User
User
Posts: 54
Joined: Thu Dec 19, 2024 1:26 pm
Location: NW-Europe

Re: Coroutines for PB [Windows / Linux]

Post by Skipper »

Am I correct in assuming, since cooperative scheduling is used for fibres/coroutines task switching, that all fibres a single application creates exist on a single processor core only? As the coroutines exist on the application level only, the OS has no way to distribute the tasks over the available cores?
<< Win-11 (x64) / Mint linux (x64) / MacOS Monterey (x64) >>
User avatar
chi
Addict
Addict
Posts: 1087
Joined: Sat May 05, 2007 5:31 pm
Location: Austria

Re: Coroutines for PB [Windows / Linux]

Post by chi »

Detailed explanation of how coroutines work...

How Coroutines work on Assembly Level (FASM)
Assembly is Based, but has One Problem... (C)

Don't watch if you get easily offended :twisted:
Et cetera is my worst enemy
User avatar
idle
Always Here
Always Here
Posts: 5888
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Coroutines for PB [Windows / Linux]

Post by idle »

Skipper wrote: Thu Feb 20, 2025 10:20 am Am I correct in assuming, since cooperative scheduling is used for fibres/coroutines task switching, that all fibres a single application creates exist on a single processor core only? As the coroutines exist on the application level only, the OS has no way to distribute the tasks over the available cores?
The fibers you create run on the thread that created them and you control the context switch with a yield, so it's back to what we had with single core cpu's to some degree and as far as I understand it addresses the ABA problem of who came first. An example would be a lock free ring buffer, on a multicore it needs memory fences to avoid the ABA problem even for single writer and reader threads but if you did it on fibers the aba should go away.
you will still get speculative execution at branches which will run on a spare core.
Post Reply