thread_ring.pp 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. { The Computer Language Shootout
  2. http://shootout.alioth.debian.org
  3. contributed by Marc Weustink
  4. }
  5. program thread_ring;
  6. {$mode objfpc}{$h-}{$i-}
  7. uses
  8. PThreads;
  9. var
  10. SemList: array[1..503] of TSemaphore;
  11. ThreadAttr: TThreadAttr;
  12. ThreadFuncAddr: TStartRoutine;
  13. FinishedSem: TSemaphore;
  14. Count: Integer;
  15. function ThreadFunc(AIndex: PtrInt): Pointer; cdecl;
  16. var
  17. MySem, NextSem: PSemaphore;
  18. Id: TThreadID;
  19. begin
  20. MySem := @SemList[AIndex];
  21. if AIndex < High(SemList)
  22. then begin
  23. NextSem := MySem+1;
  24. sem_init(NextSem, 0, 0);
  25. pthread_create(@Id, @ThreadAttr, ThreadFuncAddr, Pointer(AIndex+1));
  26. end
  27. else NextSem := @SemList[Low(SemList)];
  28. repeat
  29. sem_wait(MySem);
  30. if Count = 0 then begin
  31. WriteLn(Aindex);
  32. sem_post(FinishedSem);
  33. end
  34. else begin
  35. Dec(Count);
  36. sem_post(NextSem);
  37. end;
  38. until False;
  39. end;
  40. var
  41. n: Integer;
  42. Id: TThreadId;
  43. begin
  44. Val(paramstr(1), count, n);
  45. if n <> 0 then exit;
  46. sem_init(SemList[Low(SemList)], 0, 1);
  47. sem_init(FinishedSem, 0, 0);
  48. pthread_attr_init(@ThreadAttr);
  49. pthread_attr_setdetachstate(@ThreadAttr, 1);
  50. pthread_attr_setstacksize(@ThreadAttr, 1024 * 16);
  51. ThreadFuncAddr := TStartRoutine(@ThreadFunc);
  52. pthread_create(@Id, @ThreadAttr, ThreadFuncAddr, Pointer(PtrUInt(Low(SemList))));
  53. sem_wait(FinishedSem);
  54. end.