cthreads.pp 20 KB

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