////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001-2023 Alexey Kuryakin daqgroup@mail.ru under MIT license //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// This file is part of the CRW-DAQ project by DaqGroup - component CRWLIB.   //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Purpose:                                                                   //
// Wrapper for using shared memory manager.                                   //
// NB: ALWAYS use this unit as first unit in USES clause list.                //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// History:                                                                   //
// 20230426 - Created, A.K.                                                   //
////////////////////////////////////////////////////////////////////////////////

unit _crw_sharemem; //  Wrapper for useing Shared Memory Manager.

{$I _crw_sysdef}

{$IFNDEF IS_EXE_UNIT}
 {$DEFINE IS_DLL_UNIT}
{$ENDIF}

{$IFDEF FPC}
 {$MODE Delphi}{$H+}
{$ENDIF}

{$WARN 5023 off : Unit "$1" not used in $2}

interface

uses
 {$IFDEF UNIX}
  cthreads, dl,
   {$IFDEF USES_SHAREMEM}
    {$IFNDEF IS_DLL_UNIT}
     {$IFDEF USES_SYNFPCX64MM} synfpcx64mm, {$ENDIF}
     {$IFDEF USES_NEWFPCX64MM} mormot.core.fpcx64mm, {$ENDIF}
    {$ENDIF}
   {$ENDIF}
 {$ENDIF}
 {$IFDEF WINDOWS}
  {$IFDEF USES_SHAREMEM}
   // sharemem, FastMM5,
   {$IFDEF USES_SYNFPCX64MM} synfpcx64mm, {$ENDIF}
   {$IFDEF USES_NEWFPCX64MM} mormot.core.fpcx64mm, {$ENDIF}
  {$ENDIF}
 {$ENDIF}
 sysutils;

var
 ShareMemStorage : record
  NewMM: TMemoryManager;
  OldMM: TMemoryManager;
  MainModuleHandle: Pointer;
  GetCommonMemoryManager: procedure(var aMemMgr: TMemoryManager);
 end;

implementation

procedure Init_crw_sharemem;
begin
 with ShareMemStorage do begin
  MainModuleHandle:=nil;
  GetMemoryManager(OldMM);
  GetMemoryManager(NewMM);
  GetCommonMemoryManager:=@GetMemoryManager;
  {$IFDEF USES_SHAREMEM}
   {$IFDEF UNIX}
    {$IFDEF IS_DLL_UNIT}
     MainModuleHandle:=dlopen(nil, RTLD_LAZY);
     GetCommonMemoryManager:=dlsym(MainModuleHandle,'GetMemoryManager');
     GetCommonMemoryManager(NewMM);
     GetMemoryManager(OldMM);
     SetMemoryManager(NewMM);
    {$ENDIF}
   {$ELSE}
    {$IFDEF FPC}
    // Uses fpcx64mm
    {$ELSE}
    if IsLibrary // Sharing MemoryManager
    then FastMM_AttemptToUseSharedMemoryManager
    else FastMM_ShareMemoryManager;
    {$ENDIF}
   {$ENDIF}
  {$ENDIF}
 end;
end;

procedure Free_crw_sharemem;
begin
 with ShareMemStorage do begin
  {$IFDEF USES_SHAREMEM}
   {$IFDEF UNIX}
    {$IFDEF IS_DLL_UNIT}
     SetMemoryManager(OldMM);
    {$ENDIF}
   {$ENDIF}
  {$ENDIF}
 end;
end;

initialization

 Init_crw_sharemem;

finalization

 Free_crw_sharemem;

end.

//////////////
// END OF FILE
//////////////

