% USED by test_shared.sh

:- ensure_loaded(qtest).
:- ensure_loaded(db).
:- ensure_loaded(persistent_term_index).
:- ensure_loaded(persistence).

clear :-
	% not done with shell_format, because of the risk of a mistake
	shell('rm -rf ./test_persistence.dir').	
app_configmt_db_dir, './test_persistence.dir').


init :-
	app_db_init,
	persistent_term_index_open.

go :-   % only works once per run, since we don't close the db
	clear,
	init,
	passert(pflag(turn, 1)), 
	passert(pflag(count, 0)), 
	% checkr,
	write('thread rotation: '),
	flush_output,
	thread_create(rotate(1,2), _, [alias(t1), detached(false)]),
	thread_create(rotate(2,3), _, [alias(t2), detached(false)]),
	thread_create(rotate(3,4), _, [alias(t3), detached(false)]),
	thread_create(rotate(4,1), _, [alias(t4), detached(false)]),
	thread_join(t1, _S1),
	thread_join(t2, _S2),
	thread_join(t3, _S3),
	thread_join(t4, _S4),
	%format('status: ~q ~q ~q ~q', [S1, S2, S3, S4]),
	pflag(count, 44).

:- persistent(shared/2, [duplicates(false)]).
:- persistent(pflag/2, [duplicates(false)]).

gox(Id) :-
	get_time(StartTime),
	EndTime is StartTime + 2.0,
	(   repeat,
	    get_time(Now),
	    flag(c, Count, Count+1),
	    passert(shared(Id, Count)),
	    passert(shared(0, Id)),
	    Now > EndTime
	;   true
	).

rotate(Id, Next) :-
	passert(pflag(me(Id), 0)),
	repeat,
	wait(Id),
	write(Id), flush_output,
	pflag(count, Old),
	Count is Old + 1,
	%format(user_error, 'rotate(~w, ~w) old=~w ~n', [Id, Next, Old]),
	%checkr,
	passert(pflag(count, Count)),
	pflag(me(Id), OldMe),
	NewMe is OldMe + 1,
	passert(pflag(me(Id), NewMe)),
	passert(pflag(turn, Next)),
	Count > 40,
	% format('[x~w]', Id),
	!,
	pflag(me(Id), MeCount),
	MeCount = 11.   %  count-limit / threads + 1
	%format('[~w=~w]', [Id, MeCount]).

wait(Id) :-
	repeat,
	sleep(0.001),
	pflag(turn, Id).

wait_count(N) :-
	repeat,
	sleep(0.001),
	pflag(count, Count),
	Count > N.

check :-
	forall(  shared(Key, Value),
		 format('shared(~w, ~w).  ', [Key, Value])
	      ),
	nl.


checkr :-
	forall(  pflag(Key, Value),
		 format('pflag(~w, ~w).  ', [Key, Value])
	      ),
	nl.

	    
	    
