threadvr.inc 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt
  4. member of the Free Pascal development team
  5. Threadvar support, platform independent part
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {*****************************************************************************
  13. Threadvar support
  14. *****************************************************************************}
  15. type
  16. pltvInitEntry = ^ltvInitEntry;
  17. ltvInitEntry = packed record
  18. varaddr : pdword;
  19. size : longint;
  20. end;
  21. TltvInitTablesTable = packed record
  22. count : dword;
  23. tables : packed array [1..32767] of pltvInitEntry;
  24. end;
  25. var
  26. ThreadvarTablesTable : TltvInitTablesTable; external name 'FPC_THREADVARTABLES';
  27. procedure init_unit_threadvars (tableEntry : pltvInitEntry);
  28. begin
  29. while tableEntry^.varaddr <> nil do
  30. begin
  31. CurrentTM.InitThreadvar (tableEntry^.varaddr^, tableEntry^.size);
  32. inc (pchar (tableEntry), sizeof (tableEntry^));
  33. end;
  34. end;
  35. procedure init_all_unit_threadvars;
  36. var
  37. i : integer;
  38. begin
  39. {$ifdef DEBUG_MT}
  40. WriteLn ('init_all_unit_threadvars (',ThreadvarTablesTable.count,') units');
  41. {$endif}
  42. for i := 1 to ThreadvarTablesTable.count do
  43. init_unit_threadvars (ThreadvarTablesTable.tables[i]);
  44. end;
  45. procedure copy_unit_threadvars (tableEntry : pltvInitEntry);
  46. var
  47. oldp,
  48. newp : pointer;
  49. begin
  50. while tableEntry^.varaddr <> nil do
  51. begin
  52. newp:=CurrentTM.RelocateThreadVar(tableEntry^.varaddr^);
  53. oldp:=pointer(pchar(tableEntry^.varaddr)+sizeof(pointer));
  54. move(oldp^,newp^,tableEntry^.size);
  55. inc (pchar (tableEntry), sizeof (tableEntry^));
  56. end;
  57. end;
  58. procedure copy_all_unit_threadvars;
  59. var
  60. i : integer;
  61. begin
  62. {$ifdef DEBUG_MT}
  63. WriteLn ('copy_all_unit_threadvars (',ThreadvarTablesTable.count,') units');
  64. {$endif}
  65. for i := 1 to ThreadvarTablesTable.count do
  66. copy_unit_threadvars (ThreadvarTablesTable.tables[i]);
  67. end;
  68. procedure InitThreadVars(RelocProc : Pointer);
  69. begin
  70. { initialize threadvars }
  71. init_all_unit_threadvars;
  72. { allocate mem for main thread threadvars }
  73. CurrentTM.AllocateThreadVars;
  74. { copy main thread threadvars }
  75. copy_all_unit_threadvars;
  76. { install threadvar handler }
  77. fpc_threadvar_relocate_proc:=RelocProc;
  78. end;