L1VM - course 17

multithreading

Here I want to show how to do multihreading in Brackets. To do this I need to explain something about my language Brackets. You can’t call a function multiple times each one as a new thread. The second thread would overwrite the firsts thread variables! This is because in Brackets there are only global variables. You can set a variable name ending by #var:

(bar func)
	#var ~ bar
    
	(set int64 1 foo~ 42)
	print_i (foo~)
	print_n
(funcend)

So here we get the full variable name: foobar! To use this function muliple times we need to copy the code and replace the variables to another name.

What happens if you launch a new thread? It will load a fresh CPU core with the registers set to zeroes. And the stack will be copied into it. So you can get call variables from the stack.

Here is a full example: It is also available in my prog directory on GitHub!

// hello-thread-3.l1com
// Brackets - Hello world! threads
//
// This is an exammple how to launch threads using the new compiler opcode "loadl".
// In this example I used the "intr.l1h" include to use the new interrupt macros.
//
#include <intr.l1h>
#include <misc-macros.l1h>
(main func)
	(set int64 1 zero 0)
	(set int64 1 one 1)
	(set int64 1 two 2)
	(set int64 1 three 3)
	(set int64 1 four 4)
	(set int64 1 run 0)
	(set int64 1 f 0)
	(set int64 1 delay 4000)
	(set int64 1 cpu_number 0)
	(set string s messagestr "starting...")
	// run the two threads
	get_cpu (cpu_number)
	(((cpu_number zero ==) f =) f if)
		print_s (messagestr)
		print_n
		(:start_thr !)
		detime (delay)
		(one run =)
	(endif)
	exit (zero)
(funcend)
(hello_a func)
	#var ~ @hello_a
	(set string s hellostr~ "Hello world! Thread 1")
	(set int64 1 delay~ 2000)
	print_s (hellostr~)
	print_n
	detime (delay~)
	threadexit (zero)
(funcend)
(hello_b func)
	#var ~ @hello_b
	(set string s hellostr~ "Hello world! Thread 2")
	(set int64 1 delay~ 2000)
	print_s (hellostr~)
	print_n
	detime (delay~)
	threadexit (zero)
(funcend)
(start_thr func)
	(set int64 1 run_th 0)
	(set int64 1 lab_hello_one 0)
	(set int64 1 lab_hello_two 0)
	(set int64 1 zero_th 0)
	(set int64 1 one_th 1)
	(set int64 1 f_th 0)
	(set int64 1 delay_th 2500)
	(set int64 1 loop 0)
	(set int64 1 maxloop 25)
	(reset-reg)
	(:hello_a lab_hello_one loadl)
	(:hello_b lab_hello_two loadl)
	pull_int64_var (lab_hello_one)
	pull_int64_var (lab_hello_two)
	(((run_th zero_th ==) f_th =) f_th if)
		// run threads
		thread (lab_hello_one)
		thread (lab_hello_two)
		(one_th run_th =)
	(endif)
	detime (delay_th)
	join
	exit (zero)
(funcend)