cthreads.pp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2002 by Peter Vreman,
  5. member of the Free Pascal development team.
  6. Linux (pthreads) threading support implementation
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. {$mode objfpc}
  14. {$ifdef linux}
  15. {$define dynpthreads} // Useless on BSD, since they are in libc
  16. {$endif}
  17. unit cthreads;
  18. interface
  19. {$S-}
  20. {$ifndef dynpthreads} // If you have problems compiling this on FreeBSD 5.x
  21. {$linklib c} // try adding -Xf
  22. {$ifndef Darwin}
  23. {$linklib pthread}
  24. {$endif darwin}
  25. {$endif}
  26. Procedure SetCThreadManager;
  27. implementation
  28. Uses
  29. systhrds,
  30. BaseUnix,
  31. unix,
  32. unixtype,
  33. sysutils
  34. {$ifdef dynpthreads}
  35. ,dl
  36. {$endif}
  37. ;
  38. {*****************************************************************************
  39. Generic overloaded
  40. *****************************************************************************}
  41. { Include OS specific parts. }
  42. {$i pthread.inc}
  43. Type PINTRTLEvent = ^TINTRTLEvent;
  44. TINTRTLEvent = record
  45. condvar: pthread_cond_t;
  46. mutex: pthread_mutex_t;
  47. end;
  48. {*****************************************************************************
  49. Threadvar support
  50. *****************************************************************************}
  51. {$ifdef HASTHREADVAR}
  52. const
  53. threadvarblocksize : dword = 0;
  54. var
  55. TLSKey : pthread_key_t;
  56. procedure CInitThreadvar(var offset : dword;size : dword);
  57. begin
  58. {$ifdef cpusparc}
  59. threadvarblocksize:=align(threadvarblocksize,16);
  60. {$endif cpusparc}
  61. {$ifdef cpupowerpc}
  62. threadvarblocksize:=align(threadvarblocksize,8);
  63. {$endif cpupowerc}
  64. {$ifdef cpui386}
  65. threadvarblocksize:=align(threadvarblocksize,8);
  66. {$endif cpui386}
  67. {$ifdef cpuarm}
  68. threadvarblocksize:=align(threadvarblocksize,4);
  69. {$endif cpuarm}
  70. {$ifdef cpum68k}
  71. threadvarblocksize:=align(threadvarblocksize,2);
  72. {$endif cpum68k}
  73. {$ifdef cpux86_64}
  74. threadvarblocksize:=align(threadvarblocksize,16);
  75. {$endif cpux86_64}
  76. offset:=threadvarblocksize;
  77. inc(threadvarblocksize,size);
  78. end;
  79. function CRelocateThreadvar(offset : dword) : pointer;
  80. begin
  81. CRelocateThreadvar:=pthread_getspecific(tlskey)+Offset;
  82. end;
  83. procedure CAllocateThreadVars;
  84. var
  85. dataindex : pointer;
  86. begin
  87. { we've to allocate the memory from system }
  88. { because the FPC heap management uses }
  89. { exceptions which use threadvars but }
  90. { these aren't allocated yet ... }
  91. { allocate room on the heap for the thread vars }
  92. DataIndex:=Pointer(Fpmmap(nil,threadvarblocksize,3,MAP_PRIVATE+MAP_ANONYMOUS,-1,0));
  93. FillChar(DataIndex^,threadvarblocksize,0);
  94. pthread_setspecific(tlskey,dataindex);
  95. end;
  96. procedure CReleaseThreadVars;
  97. begin
  98. {$ifdef ver1_0}
  99. Fpmunmap(longint(pthread_getspecific(tlskey)),threadvarblocksize);
  100. {$else}
  101. Fpmunmap(pointer(pthread_getspecific(tlskey)),threadvarblocksize);
  102. {$endif}
  103. end;
  104. { Include OS independent Threadvar initialization }
  105. {$endif HASTHREADVAR}
  106. {*****************************************************************************
  107. Thread starting
  108. *****************************************************************************}
  109. type
  110. pthreadinfo = ^tthreadinfo;
  111. tthreadinfo = record
  112. f : tthreadfunc;
  113. p : pointer;
  114. stklen : cardinal;
  115. end;
  116. procedure DoneThread;
  117. begin
  118. { Release Threadvars }
  119. {$ifdef HASTHREADVAR}
  120. CReleaseThreadVars;
  121. {$endif HASTHREADVAR}
  122. end;
  123. function ThreadMain(param : pointer) : pointer;cdecl;
  124. var
  125. ti : tthreadinfo;
  126. {$ifdef DEBUG_MT}
  127. // in here, don't use write/writeln before having called
  128. // InitThread! I wonder if anyone ever debugged these routines,
  129. // because they will have crashed if DEBUG_MT was enabled!
  130. // this took me the good part of an hour to figure out
  131. // why it was crashing all the time!
  132. // this is kind of a workaround, we simply write(2) to fd 0
  133. s: string[100]; // not an ansistring
  134. {$endif DEBUG_MT}
  135. begin
  136. {$ifdef DEBUG_MT}
  137. s := 'New thread started, initing threadvars'#10;
  138. fpwrite(0,s[1],length(s));
  139. {$endif DEBUG_MT}
  140. {$ifdef HASTHREADVAR}
  141. { Allocate local thread vars, this must be the first thing,
  142. because the exception management and io depends on threadvars }
  143. CAllocateThreadVars;
  144. {$endif HASTHREADVAR}
  145. { Copy parameter to local data }
  146. {$ifdef DEBUG_MT}
  147. s := 'New thread started, initialising ...'#10;
  148. fpwrite(0,s[1],length(s));
  149. {$endif DEBUG_MT}
  150. ti:=pthreadinfo(param)^;
  151. dispose(pthreadinfo(param));
  152. { Initialize thread }
  153. InitThread(ti.stklen);
  154. { Start thread function }
  155. {$ifdef DEBUG_MT}
  156. writeln('Jumping to thread function');
  157. {$endif DEBUG_MT}
  158. ThreadMain:=pointer(ti.f(ti.p));
  159. DoneThread;
  160. pthread_detach(pthread_t(pthread_self()));
  161. end;
  162. function CBeginThread(sa : Pointer;stacksize : dword;
  163. ThreadFunction : tthreadfunc;p : pointer;
  164. creationFlags : dword; var ThreadId : THandle) : DWord;
  165. var
  166. ti : pthreadinfo;
  167. thread_attr : pthread_attr_t;
  168. begin
  169. {$ifdef DEBUG_MT}
  170. writeln('Creating new thread');
  171. {$endif DEBUG_MT}
  172. { Initialize multithreading if not done }
  173. if not IsMultiThread then
  174. begin
  175. {$ifdef HASTHREADVAR}
  176. { We're still running in single thread mode, setup the TLS }
  177. pthread_key_create(@TLSKey,nil);
  178. InitThreadVars(@CRelocateThreadvar);
  179. {$endif HASTHREADVAR}
  180. IsMultiThread:=true;
  181. end;
  182. { the only way to pass data to the newly created thread
  183. in a MT safe way, is to use the heap }
  184. new(ti);
  185. ti^.f:=ThreadFunction;
  186. ti^.p:=p;
  187. ti^.stklen:=stacksize;
  188. { call pthread_create }
  189. {$ifdef DEBUG_MT}
  190. writeln('Starting new thread');
  191. {$endif DEBUG_MT}
  192. pthread_attr_init(@thread_attr);
  193. pthread_attr_setinheritsched(@thread_attr, PTHREAD_EXPLICIT_SCHED);
  194. // will fail under linux -- apparently unimplemented
  195. pthread_attr_setscope(@thread_attr, PTHREAD_SCOPE_PROCESS);
  196. // don't create detached, we need to be able to join (waitfor) on
  197. // the newly created thread!
  198. //pthread_attr_setdetachstate(@thread_attr, PTHREAD_CREATE_DETACHED);
  199. if pthread_create(@threadid, @thread_attr, @ThreadMain,ti) <> 0 then begin
  200. threadid := 0;
  201. end;
  202. CBeginThread:=threadid;
  203. {$ifdef DEBUG_MT}
  204. writeln('BeginThread returning ',CBeginThread);
  205. {$endif DEBUG_MT}
  206. end;
  207. procedure CEndThread(ExitCode : DWord);
  208. begin
  209. DoneThread;
  210. pthread_detach(pthread_t(pthread_self()));
  211. pthread_exit(pointer(ptrint(ExitCode)));
  212. end;
  213. {$warning threadhandle can be larger than a dword}
  214. function CSuspendThread (threadHandle : dword) : dword;
  215. begin
  216. {$Warning SuspendThread needs to be implemented}
  217. end;
  218. {$warning threadhandle can be larger than a dword}
  219. function CResumeThread (threadHandle : dword) : dword;
  220. begin
  221. {$Warning ResumeThread needs to be implemented}
  222. end;
  223. procedure CThreadSwitch; {give time to other threads}
  224. begin
  225. {extern int pthread_yield (void) __THROW;}
  226. {$Warning ThreadSwitch needs to be implemented}
  227. end;
  228. {$warning threadhandle can be larger than a dword}
  229. function CKillThread (threadHandle : dword) : dword;
  230. begin
  231. pthread_detach(pthread_t(threadHandle));
  232. CKillThread := pthread_cancel(pthread_t(threadHandle));
  233. end;
  234. {$warning threadhandle can be larger than a dword}
  235. function CWaitForThreadTerminate (threadHandle : dword; TimeoutMs : longint) : dword; {0=no timeout}
  236. var
  237. LResultP: Pointer;
  238. LResult: DWord;
  239. begin
  240. LResult := 0;
  241. LResultP := @LResult;
  242. pthread_join(pthread_t(threadHandle), @LResultP);
  243. CWaitForThreadTerminate := LResult;
  244. end;
  245. {$warning threadhandle can be larger than a dword}
  246. function CThreadSetPriority (threadHandle : dword; Prio: longint): boolean; {-15..+15, 0=normal}
  247. begin
  248. {$Warning ThreadSetPriority needs to be implemented}
  249. end;
  250. {$warning threadhandle can be larger than a dword}
  251. function CThreadGetPriority (threadHandle : dword): Integer;
  252. begin
  253. {$Warning ThreadGetPriority needs to be implemented}
  254. end;
  255. {$warning threadhandle can be larger than a dword}
  256. function CGetCurrentThreadId : dword;
  257. begin
  258. CGetCurrentThreadId:=dword(pthread_self());
  259. end;
  260. {*****************************************************************************
  261. Delphi/Win32 compatibility
  262. *****************************************************************************}
  263. procedure CInitCriticalSection(var CS);
  264. var
  265. MAttr : pthread_mutexattr_t;
  266. res: longint;
  267. begin
  268. res:=pthread_mutexattr_init(@MAttr);
  269. if res=0 then
  270. begin
  271. res:=pthread_mutexattr_settype(@MAttr,longint(_PTHREAD_MUTEX_RECURSIVE));
  272. if res=0 then
  273. res := pthread_mutex_init(@CS,@MAttr)
  274. else
  275. { No recursive mutex support :/ }
  276. res := pthread_mutex_init(@CS,NIL);
  277. end
  278. else
  279. res:= pthread_mutex_init(@CS,NIL);
  280. pthread_mutexattr_destroy(@MAttr);
  281. if res <> 0 then
  282. runerror(6);
  283. end;
  284. procedure CEnterCriticalSection(var CS);
  285. begin
  286. if pthread_mutex_lock(@CS) <> 0 then
  287. runerror(6);
  288. end;
  289. procedure CLeaveCriticalSection(var CS);
  290. begin
  291. if pthread_mutex_unlock(@CS) <> 0 then
  292. runerror(6)
  293. end;
  294. procedure CDoneCriticalSection(var CS);
  295. begin
  296. if pthread_mutex_destroy(@CS) <> 0 then
  297. runerror(6);
  298. end;
  299. {*****************************************************************************
  300. Heap Mutex Protection
  301. *****************************************************************************}
  302. var
  303. HeapMutex : pthread_mutex_t;
  304. procedure PThreadHeapMutexInit;
  305. begin
  306. pthread_mutex_init(@heapmutex,nil);
  307. end;
  308. procedure PThreadHeapMutexDone;
  309. begin
  310. pthread_mutex_destroy(@heapmutex);
  311. end;
  312. procedure PThreadHeapMutexLock;
  313. begin
  314. pthread_mutex_lock(@heapmutex);
  315. end;
  316. procedure PThreadHeapMutexUnlock;
  317. begin
  318. pthread_mutex_unlock(@heapmutex);
  319. end;
  320. const
  321. PThreadMemoryMutexManager : TMemoryMutexManager = (
  322. MutexInit : @PThreadHeapMutexInit;
  323. MutexDone : @PThreadHeapMutexDone;
  324. MutexLock : @PThreadHeapMutexLock;
  325. MutexUnlock : @PThreadHeapMutexUnlock;
  326. );
  327. procedure InitHeapMutexes;
  328. begin
  329. SetMemoryMutexManager(PThreadMemoryMutexManager);
  330. end;
  331. type
  332. TPthreadMutex = pthread_mutex_t;
  333. Tbasiceventstate=record
  334. FSem: Pointer;
  335. FManualReset: Boolean;
  336. FEventSection: TPthreadMutex;
  337. end;
  338. plocaleventstate = ^tbasiceventstate;
  339. // peventstate=pointer;
  340. Const
  341. wrSignaled = 0;
  342. wrTimeout = 1;
  343. wrAbandoned= 2;
  344. wrError = 3;
  345. function IntBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  346. var
  347. MAttr : pthread_mutexattr_t;
  348. res : cint;
  349. begin
  350. new(plocaleventstate(result));
  351. plocaleventstate(result)^.FManualReset:=AManualReset;
  352. plocaleventstate(result)^.FSem:=New(PSemaphore); //sem_t.
  353. // plocaleventstate(result)^.feventsection:=nil;
  354. res:=pthread_mutexattr_init(@MAttr);
  355. if res=0 then
  356. begin
  357. res:=pthread_mutexattr_settype(@MAttr,longint(_PTHREAD_MUTEX_RECURSIVE));
  358. if Res=0 then
  359. Res:=pthread_mutex_init(@plocaleventstate(result)^.feventsection,@MAttr)
  360. else
  361. res:=pthread_mutex_init(@plocaleventstate(result)^.feventsection,nil);
  362. end
  363. else
  364. res:=pthread_mutex_init(@plocaleventstate(result)^.feventsection,nil);
  365. pthread_mutexattr_destroy(@MAttr);
  366. if res <> 0 then
  367. runerror(6);
  368. if sem_init(psem_t(plocaleventstate(result)^.FSem),ord(False),Ord(InitialState)) <> 0 then
  369. runerror(6);
  370. end;
  371. procedure Intbasiceventdestroy(state:peventstate);
  372. begin
  373. sem_destroy(psem_t( plocaleventstate(state)^.FSem));
  374. end;
  375. procedure IntbasiceventResetEvent(state:peventstate);
  376. begin
  377. While sem_trywait(psem_t( plocaleventstate(state)^.FSem))=0 do
  378. ;
  379. end;
  380. procedure IntbasiceventSetEvent(state:peventstate);
  381. Var
  382. Value : Longint;
  383. begin
  384. pthread_mutex_lock(@plocaleventstate(state)^.feventsection);
  385. Try
  386. sem_getvalue(plocaleventstate(state)^.FSem,@value);
  387. if Value=0 then
  388. sem_post(psem_t( plocaleventstate(state)^.FSem));
  389. finally
  390. pthread_mutex_unlock(@plocaleventstate(state)^.feventsection);
  391. end;
  392. end;
  393. function IntbasiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  394. begin
  395. If TimeOut<>Cardinal($FFFFFFFF) then
  396. result:=wrError
  397. else
  398. begin
  399. sem_wait(psem_t(plocaleventstate(state)^.FSem));
  400. result:=wrSignaled;
  401. if plocaleventstate(state)^.FManualReset then
  402. begin
  403. pthread_mutex_lock(@plocaleventstate(state)^.feventsection);
  404. Try
  405. intbasiceventresetevent(State);
  406. sem_post(psem_t( plocaleventstate(state)^.FSem));
  407. Finally
  408. pthread_mutex_unlock(@plocaleventstate(state)^.feventsection);
  409. end;
  410. end;
  411. end;
  412. end;
  413. function intRTLEventCreate: PRTLEvent;
  414. var p:pintrtlevent;
  415. begin
  416. new(p);
  417. pthread_cond_init(@p^.condvar, nil);
  418. pthread_mutex_init(@p^.mutex, nil);
  419. result:=PRTLEVENT(p);
  420. end;
  421. procedure intRTLEventDestroy(AEvent: PRTLEvent);
  422. var p:pintrtlevent;
  423. begin
  424. p:=pintrtlevent(aevent);
  425. pthread_cond_destroy(@p^.condvar);
  426. pthread_mutex_destroy(@p^.mutex);
  427. dispose(p);
  428. end;
  429. procedure intRTLEventSetEvent(AEvent: PRTLEvent);
  430. var p:pintrtlevent;
  431. begin
  432. p:=pintrtlevent(aevent);
  433. pthread_mutex_lock(@p^.mutex);
  434. pthread_cond_signal(@p^.condvar);
  435. pthread_mutex_unlock(@p^.mutex);
  436. end;
  437. procedure intRTLEventStartWait(AEvent: PRTLEvent);
  438. var p:pintrtlevent;
  439. begin
  440. p:=pintrtlevent(aevent);
  441. pthread_mutex_lock(@p^.mutex);
  442. end;
  443. procedure intRTLEventWaitFor(AEvent: PRTLEvent);
  444. var p:pintrtlevent;
  445. begin
  446. p:=pintrtlevent(aevent);
  447. pthread_cond_wait(@p^.condvar, @p^.mutex);
  448. pthread_mutex_unlock(@p^.mutex);
  449. end;
  450. type tthreadmethod = procedure of object;
  451. var
  452. { event that happens when gui thread is done executing the method}
  453. ExecuteEvent: PRtlEvent;
  454. { guard for synchronization variables }
  455. SynchronizeCritSect: TRtlCriticalSection;
  456. { method to execute }
  457. SynchronizeMethod: TThreadMethod;
  458. { caught exception in gui thread, to be raised in calling thread }
  459. SynchronizeException: Exception;
  460. procedure CheckSynchronize;
  461. { assumes being called from GUI thread }
  462. begin
  463. if SynchronizeMethod = nil then
  464. exit;
  465. try
  466. SynchronizeMethod;
  467. except
  468. SynchronizeException := Exception(AcquireExceptionObject);
  469. end;
  470. RtlEventSetEvent(ExecuteEvent);
  471. end;
  472. procedure intRTLEventsync(thrdmethd: tmethod;synchronizemethodproc:TProcedure);
  473. var LocalSyncException : Exception;
  474. begin
  475. EnterCriticalSection(SynchronizeCritSect);
  476. SynchronizeMethod := tthreadmethod(thrdmethd);
  477. SynchronizeException := nil;
  478. RtlEventStartWait(ExecuteEvent);
  479. SynchronizeMethodProc;
  480. // wait infinitely
  481. RtlEventWaitFor(ExecuteEvent);
  482. SynchronizeMethod := nil;
  483. LocalSyncException := SynchronizeException;
  484. LeaveCriticalSection(SynchronizeCritSect);
  485. if LocalSyncException <> nil then
  486. raise LocalSyncException;
  487. end;
  488. Function CInitThreads : Boolean;
  489. begin
  490. {$ifdef DEBUG_MT}
  491. Writeln('Entering InitThreads.');
  492. {$endif}
  493. {$ifndef dynpthreads}
  494. Result:=True;
  495. {$else}
  496. Result:=LoadPthreads;
  497. {$endif}
  498. ThreadID := SizeUInt (pthread_self);
  499. {$ifdef DEBUG_MT}
  500. Writeln('InitThreads : ',Result);
  501. {$endif DEBUG_MT}
  502. {$ifndef ver1_0}
  503. InitCriticalSection(SynchronizeCritSect);
  504. ExecuteEvent := RtlEventCreate;
  505. SynchronizeMethod := nil;
  506. {$endif}
  507. end;
  508. Function CDoneThreads : Boolean;
  509. begin
  510. {$ifndef ver1_0}
  511. DoneCriticalSection(SynchronizeCritSect);
  512. RtlEventDestroy(ExecuteEvent);
  513. {$endif}
  514. {$ifndef dynpthreads}
  515. Result:=True;
  516. {$else}
  517. Result:=UnloadPthreads;
  518. {$endif}
  519. end;
  520. Var
  521. CThreadManager : TThreadManager;
  522. Procedure SetCThreadManager;
  523. begin
  524. With CThreadManager do
  525. begin
  526. InitManager :=@CInitThreads;
  527. DoneManager :=@CDoneThreads;
  528. BeginThread :=@CBeginThread;
  529. EndThread :=@CEndThread;
  530. SuspendThread :=@CSuspendThread;
  531. ResumeThread :=@CResumeThread;
  532. KillThread :=@CKillThread;
  533. ThreadSwitch :=@CThreadSwitch;
  534. WaitForThreadTerminate :=@CWaitForThreadTerminate;
  535. ThreadSetPriority :=@CThreadSetPriority;
  536. ThreadGetPriority :=@CThreadGetPriority;
  537. GetCurrentThreadId :=@CGetCurrentThreadId;
  538. InitCriticalSection :=@CInitCriticalSection;
  539. DoneCriticalSection :=@CDoneCriticalSection;
  540. EnterCriticalSection :=@CEnterCriticalSection;
  541. LeaveCriticalSection :=@CLeaveCriticalSection;
  542. {$ifdef hasthreadvar}
  543. InitThreadVar :=@CInitThreadVar;
  544. RelocateThreadVar :=@CRelocateThreadVar;
  545. AllocateThreadVars :=@CAllocateThreadVars;
  546. ReleaseThreadVars :=@CReleaseThreadVars;
  547. {$endif}
  548. BasicEventCreate :=@intBasicEventCreate;
  549. BasicEventDestroy :=@intBasicEventDestroy;
  550. BasicEventResetEvent :=@intBasicEventResetEvent;
  551. BasicEventSetEvent :=@intBasicEventSetEvent;
  552. BasiceventWaitFor :=@intBasiceventWaitFor;
  553. rtlEventCreate :=@intrtlEventCreate;
  554. rtlEventDestroy :=@intrtlEventDestroy;
  555. rtlEventSetEvent :=@intrtlEventSetEvent;
  556. rtlEventStartWait :=@intrtlEventStartWait;
  557. rtleventWaitFor :=@intrtleventWaitFor;
  558. rtleventsync :=trtleventsynchandler(@intrtleventsync);
  559. rtlchksyncunix :=@checksynchronize;
  560. end;
  561. SetThreadManager(CThreadManager);
  562. InitHeapMutexes;
  563. end;
  564. initialization
  565. SetCThreadManager;
  566. finalization
  567. end.
  568. {
  569. $Log$
  570. Revision 1.19 2004-12-28 14:20:03 marco
  571. * tthread patch from neli
  572. Revision 1.18 2004/12/27 15:28:40 marco
  573. * checksynchronize now in interface win32 uses the default impl.
  574. unix uses systhrds, rest empty implementation.
  575. Revision 1.17 2004/12/23 20:20:30 michael
  576. + Fixed tmt1 test bug
  577. Revision 1.16 2004/12/23 15:08:59 marco
  578. * 2nd synchronize attempt. cthreads<->systhrds difference was not ok, but
  579. only showed on make install should be fixed now.
  580. Revision 1.15 2004/12/22 21:29:24 marco
  581. * rtlevent kraam. Checked (compile): Linux, FreeBSD, Darwin, Windows
  582. Check work: ask Neli.
  583. Revision 1.14 2004/12/12 14:30:27 peter
  584. * x86_64 updates
  585. Revision 1.13 2004/10/14 17:39:33 florian
  586. + added system.align
  587. + threadvars are now aligned
  588. Revision 1.12 2004/09/09 20:29:06 jonas
  589. * fixed definition of pthread_mutex_t for non-linux targets (and for
  590. linux as well, actually).
  591. * base libpthread definitions are now in ptypes.inc, included in unixtype
  592. They sometimes have an extra underscore in front of their name, in
  593. case they were also exported by the packages/base/pthreads unit, so
  594. they can keep their original name there
  595. * cthreadds unit now imports systuils, because it uses exceptions (it
  596. already did so before as well)
  597. * fixed many linux definitions of libpthread functions in pthrlinux.inc
  598. (integer -> cint etc)
  599. + added culonglong type to ctype.inc
  600. Revision 1.11 2004/05/23 15:30:42 marco
  601. * basicevent, still untested.
  602. Revision 1.10 2004/03/03 22:00:28 peter
  603. * $ifdef debug code
  604. Revision 1.9 2004/02/22 16:48:39 florian
  605. * several 64 bit issues fixed
  606. Revision 1.8 2004/02/15 16:33:32 marco
  607. * linklibs fixed for new pthread mechanism on FreeBSD
  608. Revision 1.7 2004/01/20 23:13:53 hajny
  609. * ExecuteProcess fixes, ProcessID and ThreadID added
  610. Revision 1.6 2004/01/07 17:40:56 jonas
  611. * Darwin does not have a lib_r, libc itself is already reentrant
  612. Revision 1.5 2003/12/16 09:43:04 daniel
  613. * Use of 0 instead of nil fixed
  614. Revision 1.4 2003/11/29 17:34:14 michael
  615. + Removed dummy variable from SetCthreadManager
  616. Revision 1.3 2003/11/27 20:24:53 michael
  617. + Compiles on BSD too now
  618. Revision 1.2 2003/11/27 20:16:59 michael
  619. + Make works with 1.0.10 too
  620. Revision 1.1 2003/11/26 20:10:59 michael
  621. + New threadmanager implementation
  622. Revision 1.20 2003/11/19 10:54:32 marco
  623. * some simple restructures
  624. Revision 1.19 2003/11/18 22:36:12 marco
  625. * Last patch was ok, problem was somewhere else. Moved *BSD part of pthreads to freebsd/pthreads.inc
  626. Revision 1.18 2003/11/18 22:35:09 marco
  627. * Last patch was ok, problem was somewhere else. Moved *BSD part of pthreads to freebsd/pthreads.inc
  628. Revision 1.17 2003/11/17 10:05:51 marco
  629. * threads for FreeBSD. Not working tho
  630. Revision 1.16 2003/11/17 08:27:50 marco
  631. * pthreads based ttread from Johannes Berg
  632. Revision 1.15 2003/10/01 21:00:09 peter
  633. * GetCurrentThreadHandle renamed to GetCurrentThreadId
  634. Revision 1.14 2003/10/01 20:53:08 peter
  635. * GetCurrentThreadId implemented
  636. Revision 1.13 2003/09/20 12:38:29 marco
  637. * FCL now compiles for FreeBSD with new 1.1. Now Linux.
  638. Revision 1.12 2003/09/16 13:17:03 marco
  639. * Wat cleanup, ouwe syscalls nu via baseunix e.d.
  640. Revision 1.11 2003/09/16 13:00:02 marco
  641. * small BSD gotcha removed (typing mmap params)
  642. Revision 1.10 2003/09/15 20:08:49 marco
  643. * small fixes. FreeBSD now cycles
  644. Revision 1.9 2003/09/14 20:15:01 marco
  645. * Unix reform stage two. Remove all calls from Unix that exist in Baseunix.
  646. Revision 1.8 2003/03/27 17:14:27 armin
  647. * more platform independent thread routines, needs to be implemented for unix
  648. Revision 1.7 2003/01/05 19:11:32 marco
  649. * small changes originating from introduction of Baseunix to FreeBSD
  650. Revision 1.6 2002/11/11 21:41:06 marco
  651. * syscall.inc -> syscallo.inc
  652. Revision 1.5 2002/10/31 13:45:21 carl
  653. * threadvar.inc -> threadvr.inc
  654. Revision 1.4 2002/10/26 18:27:52 marco
  655. * First series POSIX calls commits. Including getcwd.
  656. Revision 1.3 2002/10/18 18:05:06 marco
  657. * $I pthread.inc instead of pthreads.inc
  658. Revision 1.2 2002/10/18 12:19:59 marco
  659. * Fixes to get the generic *BSD RTL compiling again + fixes for thread
  660. support. Still problems left in fexpand. (inoutres?) Therefore fixed
  661. sysposix not yet commited
  662. Revision 1.1 2002/10/16 06:22:56 michael
  663. Threads renamed from threads to systhrds
  664. Revision 1.1 2002/10/14 19:39:17 peter
  665. * threads unit added for thread support
  666. }