cthreads.pp 23 KB

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