\ $Id: prodcons.gforth,v 1.1 2001/06/20 20:55:44 doug Exp $
\ http://www.bagley.org/~doug/shootout/
\ from Bernd Paysan

require tasker.fs

\ read NUM from last command line argument
0. argc @ 1- arg >number 2drop drop constant NUM

Variable pcount
Variable data
Variable produced
Variable consumed

\ note: no mutex is needed here. bigFORTH's tasker is cooperative
\ and switches tasks only with PAUSE.

: producer 
  next-task swap 2 $1000 NewTask pass
  0 ?DO
     BEGIN  pcount @ 1 =  WHILE  pause  REPEAT
     1 pcount ! I data !
     1 produced +!
  LOOP wake ;

: consumer 
  next-task swap 2 $1000 NewTask pass
  0 swap 0 ?DO
     BEGIN  pcount @ 0=  WHILE  pause  REPEAT
     0 pcount ! drop data @
     1 consumed +!
  LOOP drop wake ;

NUM producer
NUM consumer

\ There is no "main" task - to synchronize, each of the two new
\ threads get the task address of the starting task, and wake it
\ when they are done. The main task therefore has to stop twice
\ (and wait to be woken up)

stop stop

produced @ .
consumed @ 1 u.r cr

bye \ th-th-that's all folks!