123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- {
- $Id$
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2000 by the Free Pascal development team.
- Multithreading implementation for OS/2
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- const
- ThreadVarBlockSize: dword = 0;
- type
- TThreadInfo = record
- F: TThreadFunc;
- P: pointer;
- end;
- PThreadInfo = ^TThreadInfo;
- PPointer = ^pointer;
- var
- (* Pointer to an allocated dword space within the local thread *)
- (* memory area. Pointer to the real memory block allocated for *)
- (* thread vars in this block is then stored in this dword. *)
- DataIndex: PPointer;
- { import the necessary stuff from the OS }
- function DosAllocThreadLocalMemory (Count: cardinal; var P: pointer): longint;
- cdecl; external 'DOSCALLS' index 454;
- function DosFreeThreadLocalMemory (P: pointer): longint; cdecl;
- external 'DOSCALLS' index 455;
- function DosCreateThread (var TID: longint; Address: TThreadEntry;
- aParam: pointer; Flags: longint; StackSize: longint): longint; cdecl;
- external 'DOSCALLS' index 311;
- procedure DosExit (Action, Result: longint); cdecl;
- external 'DOSCALLS' index 233;
- procedure Init_ThreadVar (var TVOffset: dword; Size: dword);
- [public, alias: 'FPC_INIT_THREADVAR'];
- begin
- TVOffset := ThreadVarBlockSize;
- Inc (ThreadVarBlockSize, Size);
- end;
- function Relocate_ThreadVar (TVOffset: dword): pointer;
- [public,alias: 'FPC_RELOCATE_THREADVAR'];
- begin
- Relocate_ThreadVar := DataIndex + TVOffset;
- end;
- procedure AllocateThreadVars;
- begin
- { we've to allocate the memory from the OS }
- { because the FPC heap management uses }
- { exceptions which use threadvars but }
- { these aren't allocated yet ... }
- { allocate room on the heap for the thread vars }
- if DosAllocMem (DataIndex^, ThreadVarBlockSize, ) <> 0 then RunError (8);
- end;
- procedure InitThread;
- begin
- InitFPU;
- { we don't need to set the data to 0 because we did this with }
- { the fillchar above, but it looks nicer }
- { ExceptAddrStack and ExceptObjectStack are threadvars }
- { so every thread has its on exception handling capabilities }
- InitExceptions;
- InOutRes := 0;
- ErrNo := 0;
- end;
- procedure DoneThread;
- begin
- { release thread vars }
- DosFreeMem (DataIndex^);
- end;
- function ThreadMain (Param: pointer): dword; cdecl
- var
- TI: TThreadInfo;
- begin
- {$ifdef DEBUG_MT}
- WriteLn ('New thread started, initialising ...');
- {$endif DEBUG_MT}
- AllocateThreadVars;
- InitThread;
- TI := PThreadInfo (Param)^;
- Dispose (PThreadInfo (Param));
- {$ifdef DEBUG_MT}
- WriteLn ('Jumping to thread function');
- {$endif DEBUG_MT}
- ThreadMain := TI.F (TI.P);
- end;
- function BeginThread (SA: pointer; StackSize: dword;
- ThreadFunction: TThreadFunc; P: pointer; CreationFlags: dword;
- var ThreadID: dword): dword;
- var
- TI: PThreadInfo;
- begin
- {$ifdef DEBUG_MT}
- WriteLn ('Creating new thread');
- {$endif DEBUG_MT}
- IsMultiThreaded := true;
- { the only way to pass data to the newly created thread }
- { in a MT safe way, is to use the heap }
- New (TI);
- TI^.F := ThreadFunction;
- TI^.P := P;
- {$ifdef DEBUG_MT}
- WriteLn ('Starting new thread');
- {$endif DEBUG_MT}
- BeginThread := CreateThread (sa,stacksize,@ThreadMain,ti,
- creationflags,threadid);
- end;
- function BeginThread (ThreadFunction: TThreadFunc): dword;
- var
- Dummy: dword;
- begin
- BeginThread := BeginThread (nil, 0, ThreadFunction, nil, 0, Dummy);
- end;
- function BeginThread (ThreadFunction: TThreadFunc; P: pointer): dword;
- var
- Dummy: dword;
- begin
- BeginThread := BeginThread (nil, 0, ThreadFunction, P, 0, Dummy);
- end;
- function BeginThread (ThreadFunction: TThreadFunc; P: pointer;
- var ThreadID: dword): dword;
- begin
- BeginThread := BeginThread (nil, 0, ThreadFunction, P, 0, ThreadID);
- end;
- procedure EndThread (ExitCode: dword);
- begin
- DoneThread;
- DosExit (0, ExitCode);
- end;
- procedure EndThread;
- begin
- EndThread (0);
- end;
- procedure InitCriticalSection (var cs : tcriticalsection);
- begin
- end;
- procedure DoneCriticalsection(var cs : tcriticalsection);
- begin
- end;
- procedure EnterCriticalsection(var cs : tcriticalsection);
- begin
- end;
- procedure LeaveCriticalsection(var cs : tcriticalsection);
- begin
- end;
- {
- $Log$
- Revision 1.1 2001-01-23 20:38:59 hajny
- + beginning of the OS/2 version
- Revision 1.1 2001/01/01 19:06:36 florian
- + initial release
- }
|