[fpc-devel] Shootout

Daniël Mantione daniel.mantione at freepascal.org
Fri Sep 29 21:36:34 CEST 2006


Hi,

Encouraged by Vincent I made an attempt to implement the Chameneos 
benchmark of the Shootout. It turned out to be really hard, because we 
don't have real semafores (which makes it for example impossible to 
translate the C version).

However, with the RTLevent* routines, it is possible to implement it.
I have a final problem I'm unable to solve at this time. When all threads 
exit, one of the threads still hangs in a RTLeventwaitfor call. We don't 
know which one.

The trick is to get it out of its wait state in a safe way. My currect 
solution (a set event call when the end is eached) sometimes fails,
depending on the weather or something.

If anyone wants to take a look, the source is attached.

Daniël
-------------- next part --------------
program chameneos;

uses sysutils
{$ifdef unix}
     ,cthreads
{$endif};

type colour=(blue,red,yellow,fade);

     chamid=0..3;

var complement:array[colour,colour] of colour=
       ((blue,yellow,red,fade),
        (yellow,red,blue,fade),
        (red,blue,yellow,fade),
        (fade,fade,fade,fade));

    meet_event:PRTLevent;
    tid:array[chamid] of Tthreadid;

const cham_colours:array[chamid] of colour=(blue,red,yellow,blue);
      meetings:longint=0;
      meetings_left:longint=1000000;
      first_call:boolean=true;
      state:longint=0;

var first,second:colour;

function other_creatures_colour(id:chamid;c:colour):colour;

begin
  other_creatures_colour:=fade;
  if meetings_left<>0 then
    begin
      if interlockedincrement(state) and 1<>0 then
        begin
          other_creatures_colour:=first;
          second:=c;
          RTLeventsetevent(meet_event);
          dec(meetings_left);
        end
      else
        begin
          RTLeventstartwait(meet_event);
          first:=c;
          RTLeventwaitfor(meet_event);
          other_creatures_colour:=second;
        end
    end
  else
    RTLeventsetevent(meet_event); {!!! Not trusted!}
end;

function chameneos(parameter:pointer):ptrint;

var id:chamid;
    other:colour;

begin
  id:=ptrint(parameter);
  while cham_colours[id]<>fade do
    begin
      other:=other_creatures_colour(id,cham_colours[id]);
      if other=fade then
        cham_colours[id]:=fade
      else
        begin
          cham_colours[id]:=complement[cham_colours[id],other];
          inc(meetings);
        end;
    end;
  chameneos:=0;
end;

var i:chamid;

begin
  if paramcount>=1 then
    val(paramstr(1),meetings_left);
  meet_event:=RTLeventcreate;  
  for i:=low(chamid) to high(chamid) do
    tid[i]:=beginthread(@chameneos,pointer(ptrint(i)));
  for i:=low(chamid) to high(chamid) do
    waitforthreadterminate(tid[i],0);
  RTLeventdestroy(meet_event);
  writeln(meetings);
end.


More information about the fpc-devel mailing list