mtpcpu.pas 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. {
  2. **********************************************************************
  3. This file is part of the Free Pascal run time library.
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the license.
  6. **********************************************************************
  7. System depending code for light weight threads.
  8. Copyright (C) 2008 Mattias Gaertner [email protected]
  9. }
  10. unit MTPCPU;
  11. {$mode objfpc}{$H+}
  12. {$inline on}
  13. interface
  14. {$IF defined(windows)}
  15. uses Windows;
  16. {$ELSEIF defined(freebsd) or defined(darwin)}
  17. uses ctypes, sysctl;
  18. {$ELSEIF defined(linux)}
  19. {$linklib c}
  20. uses ctypes;
  21. {$ENDIF}
  22. function GetSystemThreadCount: integer;
  23. procedure CallLocalProc(AProc, Frame: Pointer; Param1: PtrInt;
  24. Param2, Param3: Pointer); inline;
  25. implementation
  26. {$IFDEF Linux}
  27. const _SC_NPROCESSORS_ONLN = 84;
  28. function sysconf(i: cint): clong; cdecl; external name 'sysconf';
  29. {$ENDIF}
  30. function GetSystemThreadCount: integer;
  31. // returns a good default for the number of threads on this system
  32. {$IF defined(windows)}
  33. //returns total number of processors available to system including logical hyperthreaded processors
  34. var
  35. i: Integer;
  36. ProcessAffinityMask, SystemAffinityMask: DWORD_PTR;
  37. Mask: DWORD;
  38. SystemInfo: SYSTEM_INFO;
  39. begin
  40. if GetProcessAffinityMask(GetCurrentProcess, ProcessAffinityMask, SystemAffinityMask)
  41. then begin
  42. Result := 0;
  43. for i := 0 to 31 do begin
  44. Mask := DWord(1) shl i;
  45. if (ProcessAffinityMask and Mask)<>0 then
  46. inc(Result);
  47. end;
  48. end else begin
  49. //can't get the affinity mask so we just report the total number of processors
  50. GetSystemInfo(SystemInfo);
  51. Result := SystemInfo.dwNumberOfProcessors;
  52. end;
  53. end;
  54. {$ELSEIF defined(UNTESTEDsolaris)}
  55. begin
  56. t = sysconf(_SC_NPROC_ONLN);
  57. end;
  58. {$ELSEIF defined(freebsd) or defined(darwin)}
  59. type
  60. PSysCtl = {$IF FPC_FULLVERSION>=30200}pcint{$ELSE}pchar{$ENDIF};
  61. var
  62. mib: array[0..1] of cint;
  63. len: csize_t;
  64. t: cint;
  65. begin
  66. mib[0] := CTL_HW;
  67. mib[1] := HW_NCPU;
  68. len := sizeof(t);
  69. fpsysctl(PSysCtl(@mib), 2, @t, @len, Nil, 0);
  70. Result:=t;
  71. end;
  72. {$ELSEIF defined(linux)}
  73. begin
  74. Result:=sysconf(_SC_NPROCESSORS_ONLN);
  75. end;
  76. {$ELSE}
  77. begin
  78. Result:=1;
  79. end;
  80. {$ENDIF}
  81. procedure CallLocalProc(AProc, Frame: Pointer; Param1: PtrInt;
  82. Param2, Param3: Pointer); inline;
  83. type
  84. PointerLocal = procedure(_EBP: Pointer; Param1: PtrInt;
  85. Param2, Param3: Pointer);
  86. begin
  87. PointerLocal(AProc)(Frame, Param1, Param2, Param3);
  88. end;
  89. end.