Multiplatform coroutines in C and also in FreeBasic

General discussion for topics related to the FreeBASIC project or its community.
angros47
Posts: 2323
Joined: Jun 21, 2005 19:04

Multiplatform coroutines in C and also in FreeBasic

Post by angros47 »

I found this:
https://github.com/higan-emu/higan/tree/master/libco


Also:
https://github.com/canonical/libco
https://github.com/Wizcorp/byuu-web/tree/master/libco


I guess it can be ported to FreeBasic. Or perhaps it can be integrated in the runtime and compiler? (in the past I remember someone wanted to add coroutine support in FB)
Last edited by angros47 on Nov 24, 2020 11:37, edited 2 times in total.
angros47
Posts: 2323
Joined: Jun 21, 2005 19:04

Re: Multiplatform coroutines in C and also in FreeBasic

Post by angros47 »

Ok, it works in FreeBasic, too.
First of all, you need to download the files, and compile the library with:

Code: Select all

gcc -c libco.c
You should get the file libco.o (it can be done in DOS, in Windows and in Linux)

Then, the header for FreeBasic (that must be saved as "libco.bi") is:

Code: Select all

'  libco v20 (2019-10-16)
'  author: byuu
'  license: ISC

declare function co_active cdecl alias "co_active" () as any ptr
declare function co_derive cdecl alias "co_derive" (p as any ptr, b as unsigned integer, s as sub) as any ptr
declare function co_create cdecl alias "co_create" (b as unsigned integer, s as sub) as any ptr
declare sub co_delete cdecl alias "co_delete" (t as any ptr)
declare sub co_switch cdecl alias "co_switch" (t as any ptr)
declare function co_serializable cdecl alias "co_serializable" as integer

And now, to use it in FreeBasic:

Code: Select all

#include "libco.bi"

dim shared as any ptr t0,t1

sub task
	dim z as integer
	do
		z+=1
		print "this is the thread, iteration ";z
		co_switch(t0)
	loop

end sub




t0=co_active()
t1=co_create(65536,@task)


for i as integer=1 to 50
	print "this is main"
	co_switch(t1)
next
The "do..loop" cycle in the subroutine "task" and the "for...next" loop in the main section of the program will be executed at the same time, although it will happen in a single thread, with no need to set mutex or semaphores, and each iteration of one cycle will match with an iteration of the other one (the loop in "task" will do exactly 50 iterations)
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Multiplatform coroutines in C and also in FreeBasic

Post by dodicat »

I tested this angros47

Code: Select all

this is main
this is the thread, iteration  1
this is main
this is the thread, iteration  2
this is main
this is the thread, iteration  3
this is main
this is the thread, iteration  4
this is main
this is the thread, iteration  5  
. . .
. . .

Since I have 32 bit minGW on path I just made the .a file from the .o file.
Thank you.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Multiplatform coroutines in C and also in FreeBasic

Post by paul doe »

Mmm, this could prove tremendously useful, thanks. I guess that it can also be built-in in the dialect itself (fork/yield/join?)
angros47
Posts: 2323
Joined: Jun 21, 2005 19:04

Re: Multiplatform coroutines in C and also in FreeBasic

Post by angros47 »

I would like if it could be integrated in the language. I can already see an use for OpenGL programs (since OpenGL is not thread safe, and it can be accessed only by the thread that created the context). The keyword "fork" should not be used for that, anyway, since it would create confusion with the "fork" instruction that on Linux (and in general on Posix systems) creates a new process
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Multiplatform coroutines in C and also in FreeBasic

Post by Tourist Trap »

Just for those who may want to test this, more precision:
The thing may have to be compiled this way in a batch file:

Code: Select all

@echo on

"C:\Program Files (x86)\FreeBasic\Freebasic7\FreeBASIC-1.07.1-win64/fbc" libco.o test.bas

test.exe

pause
No need of any include here. Just put every declaration at top:

Code: Select all

'  libco v20 (2019-10-16)
'  author: byuu
'  license: ISC
declare function co_active cdecl alias "co_active" () as any ptr
declare function co_derive cdecl alias "co_derive" (p as any ptr, b as unsigned integer, s as sub) as any ptr
declare function co_create cdecl alias "co_create" (b as unsigned integer, s as sub) as any ptr
declare sub co_delete cdecl alias "co_delete" (t as any ptr)
declare sub co_switch cdecl alias "co_switch" (t as any ptr)
declare function co_serializable cdecl alias "co_serializable" as integer

dim shared as any ptr t0,t1
sub task
   dim z as integer
   do
      z+=1
      print "this is the thread, iteration ";z
      co_switch(t0)
   loop
end sub
t0=co_active()
t1=co_create(65536,@task)

for i as integer=1 to 50
   print "this is main"
   co_switch(t1)
next
To find GCC, I have one in my Octave installation, so I guess everyone has one somewhere in its system, in order to make the .o file.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Multiplatform coroutines in C and also in FreeBasic

Post by dodicat »

You can get a minGW from the NEWS section (the latest fb compilers).
Just unpack it and set the bin folder on the system path.
You have gcc and g++ (C++) compilers, Fortran, gendef (for dll work), nm to look into libraries and many other handy things.
angros47
Posts: 2323
Joined: Jun 21, 2005 19:04

Re: Multiplatform coroutines in C and also in FreeBasic

Post by angros47 »

I replaced the link, the old link didn't work anymore
angros47
Posts: 2323
Joined: Jun 21, 2005 19:04

Re: Multiplatform coroutines in C and also in FreeBasic

Post by angros47 »

Added two more links, because they provide one version for risc64, and one for emscripten.

I wonder if they should be integrated in the runtime library (and made available only when the header is included: so they should not pollute namespace, neither add overhead when not used, but users won't need to compile them from c source)
angros47
Posts: 2323
Joined: Jun 21, 2005 19:04

Re: Multiplatform coroutines in C and also in FreeBasic

Post by angros47 »

Tested the emscripten version (only in C for now): they work perfectly but require the ASYNCIFY mode
exagonx
Posts: 315
Joined: Mar 20, 2009 17:03
Location: Italy
Contact:

Re: Multiplatform coroutines in C and also in FreeBasic

Post by exagonx »

angros47 wrote: Nov 24, 2020 15:24
Its a way to pass inside the sub routine without terminate it ?

Apologies but I dont understand if are like a thread that work in background with main code active or just task who can be switched
angros47
Posts: 2323
Joined: Jun 21, 2005 19:04

Re: Multiplatform coroutines in C and also in FreeBasic

Post by angros47 »

Yes, it is. It is possible, for example, to start a subroutine, leave it while in the middle of a loop, and resume it from the same point, continuing the loop.

The concept is similar to a thread, but it doesn't work in background: only one of them is active at the same time, and it's up to the programmer to decide when to switch to another
SARG
Posts: 1765
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Multiplatform coroutines in C and also in FreeBasic

Post by SARG »

Just for fun, without any lib, entirely in freebasic. Only 64bit.
CAUTION : never directly call the procedure and never go to its end. No warranty it works in all cases.

Code: Select all

#macro co_int(varname)
	#ifndef prv
		dim shared as integer prv
	#endif

	asm mov qword ptr [varname], rsp
	asm sub qword ptr [varname], 8
	asm	mov rax, [varname]
	asm mov [prv], rax
	asm mov qword ptr [rsp-8], 0 'proc address 0 for main
	asm mov qword ptr [rsp-16], 0 ' rsp
	asm sub rsp, 8+17*8
#EndMacro

#macro co_create(varname,procadr)
	asm mov qword ptr [varname], rsp
	asm sub qword ptr [varname], 8
	asm lea rax, procadr
	asm mov qword ptr [rsp-8], rax 'proc address
	asm mov qword ptr [rsp-16], 0 ' rsp
	asm sub rsp, 8+17*8 'adr task,registers saved, stack size
#EndMacro

#macro co_switch(varname)
	asm
		'save current registers
		mov rax, [prv]
		mov [rax-8],  rsp
		mov [rax-24], rax
		mov [rax-32], rbx
		mov [rax-40], rcx
		mov [rax-48], rdx
		mov [rax-56], rsi
		mov [rax-64], rdi
		mov [rax-72], rbp
		mov [rax-80], r8
		mov [rax-88], r9
		mov [rax-96], r10
		mov [rax-104], r11
		mov [rax-112], r12
		mov [rax-120], r13
		mov [rax-128], r14
		mov [rax-136], r15
		
		lea rbx, label01##varname#__FUNCTION_NQ__ 	'return adress 	
		mov [rax-16], rbx	

		mov rax, [varname]
		mov [prv], rax
		cmp qword ptr [rax-8], 0 ' first jmp ?
		je label02##varname#__FUNCTION_NQ__
		'restore target registers
		'mov rsp, [rax-8]
		mov rax, [rax-24]
		mov rbx, [rax-32]
		mov rcx, [rax-40]
		mov rdx, [rax-48]
		mov rsi, [rax-56]
		mov rdi, [rax-64]
		mov rbp, [rax-72]
		mov r8, [rax-80]
		mov r9, [rax-88]
		mov r10, [rax-96]
		mov r11, [rax-104]
		mov r12, [rax-112]
		mov r13, [rax-120]
		mov r14, [rax-128]
		mov r15, [rax-136]
		jmp qword ptr [rax-16]
		
		label02##varname#__FUNCTION_NQ__:
		jmp qword ptr [rax]
		label01##varname#__FUNCTION_NQ__:
	End Asm
	
#EndMacro

dim shared as any ptr tt0,tt1,tt2

co_int(tt0) 'should be before any co_switch

sub ttask2()
	dim z as integer
	z+=1
	print "thread 2, iteration ";z
	co_switch(tt1)
end sub

sub ttask1()
	dim z as integer
	do
		z+=1
		if z<=1 then co_switch(tt2) 'executed only one time
		print "thread 1, iteration ";z
		co_switch(tt0)
	loop

end sub


co_create(tt1,ttask1)
co_create(tt2,ttask2)


for i as integer=1 to 5
	print "main"
	co_switch(tt1)
next
print "end"
sleep
exagonx
Posts: 315
Joined: Mar 20, 2009 17:03
Location: Italy
Contact:

Re: Multiplatform coroutines in C and also in FreeBasic

Post by exagonx »

SARG wrote: Nov 28, 2022 22:56 Just for fun, without any lib, entirely in freebasic. Only 64bit.
The usefull things are threading in DOS 16 bit ( where you can make a app who can work with a very little of ammount of memory
With the help of another guy I was able to load MSDOS 6.22 in a Simbian system, actually I can have many of this things for cheap cost, if I can write a good managment software I can resell like portable palm to make order in restaurants or for control a robot system, I really dont like Arduino its hard for make something where I can upgrade directly without conenct to a PC
SARG
Posts: 1765
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Multiplatform coroutines in C and also in FreeBasic

Post by SARG »

exagonx wrote: Nov 29, 2022 6:12 The usefull things are threading in DOS 16 bit ( where you can make a app who can work with a very little of ammount of memory
With the help of another guy I was able to load MSDOS 6.22 in a Simbian system, actually I can have many of this things for cheap cost, if I can write a good managment software I can resell like portable palm to make order in restaurants or for control a robot system, I really dont like Arduino its hard for make something where I can upgrade directly without conenct to a PC
Do you mean that you want the same for 16bit programs ?
I suppose It would possible using only 16bit registers but not sure about the result and I can't test.
Post Reply