Browse Source

+ Added memory manager section

michael 25 years ago
parent
commit
8c686201c5
1 changed files with 209 additions and 6 deletions
  1. 209 6
      docs/prog.tex

+ 209 - 6
docs/prog.tex

@@ -3253,6 +3253,207 @@ ReleaseTempHeap;
 {All allocated memory is now freed, except for the memory pointed to by 'P' }
 {All allocated memory is now freed, except for the memory pointed to by 'P' }
 ...
 ...
 \end{verbatim}
 \end{verbatim}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Debugging the heap
+\subsection{Debugging the heap}
+
+\fpc provides a unit that allows you to trace allocation and deallocation
+of heap memory: \file{heaptrc}. 
+
+If you specify the \var{-gh} switch on the command-line, or if you include 
+\var{heaptrc} as the first unit in your uses clause, the memory manager 
+will trace what is allocated and deallocated, and on exit of your program,
+a summary will be sent to standard output.
+
+More information on using the \var{heaptrc} mechanism can be found in the 
+\userref and \unitsref.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Writing your own memory manager.
+\subsection{Writing your own memory manager}
+
+\fpc allows you to write and use your own memory manager. The standard
+functions \var{GetMem}, \var{FreeMem}, \var{ReallocMem} and \var{Maxavail}
+use a special record in the system unit to do the actual memory management.
+The system unit initializes this record with the system unit's own memory
+manager, but you can read and set this record using the
+\var{GetMemoryManager} and \var{SetMemoryManager} calls:
+\begin{verbatim}
+procedure GetMemoryManager(var MemMgr: TMemoryManager);
+procedure SetMemoryManager(const MemMgr: TMemoryManager);
+\end{verbatim}
+
+the \var{TMemoryManager} record is defined as follows:
+\begin{verbatim}
+  TMemoryManager = record
+    Getmem      : Function(Size:Longint):Pointer;
+    Freemem     : Function(var p:pointer):Longint;
+    FreememSize : Function(var p:pointer;Size:Longint):Longint;
+    AllocMem    : Function(Size:longint):Pointer;
+    ReAllocMem  : Function(var p:pointer;Size:longint):Pointer;
+    MemSize     : function(p:pointer):Longint;
+    MemAvail    : Function:Longint;
+    MaxAvail    : Function:Longint;
+    HeapSize    : Function:Longint;
+  end;
+\end{verbatim}
+
+As you can see, the elements of this record are procedural variables.
+The system unit does nothing but call these various variables when you
+allocate or deallocate memory.
+
+Each of these functions corresponds to the corresponding call in the system 
+unit. We'll describe each one of them:
+\begin{description}
+\item[Getmem] This function allocates a new block on the heap. The block
+should be \var{Size} bytes long. The return value is a pointer to the newly
+allocated block.
+\item[Freemem] should release a previously allocated block. The pointer
+\var{P} points to a previously allocated block. The Memory manager should
+implement a mechanism to determine what the size of the memory block is
+\footnote{By storing it's size at a negative offset for instance.} The
+return value is optional, and can be used to return the size of the freed
+memory.
+\item[FreememSize] This function should release the memory pointed to by
+\var{P}. The argument \var{Size} is the expected size of the memory block
+pointed to by P. This should be disregarded, but can be used to check the
+behaviour of the program.
+\item[AllocMem] Is the same as getmem, only the allocated memory should 
+be filled with zeroes before the call returns.
+\item[ReAllocMem] Should allocate a memory block \var{Size} bytes large,
+and should fill it with the contents of the memory block pointed to by
+\var{P}, truncating this to the new size of needed. After that, the memory
+pointed to by P may be deallocated. The return value is a pointer to the 
+new memory block.
+\item[MemSize] should return the total amount of memory available for
+allocation. This function may return zero if the memory manager does not 
+allow to determine this information.
+\item[MaxAvail] should return the size of the largest block of memory that
+is still available for allocation. This function may return zero if the 
+memory manager does not allow to determine this information.
+\item[HeapSize] should return the total size of the heap. This may be zero
+is the memory manager does not allow to determine this information.
+\end{description}
+To implement your own memory manager, it is sufficient to construct such a
+record and to issue a call to \var{SetMemoryManager}. 
+
+To avoid conflicts with the system memory manager, setting the memory 
+manager should happen as soon as possible in the initialization of your 
+program, i.e. before any call to \var{getmem} is processed. 
+
+This means in practice that the unit implementing the memory manager should
+be the first in the \var{uses} clause of your program or library, since it
+will then be initialized before all other units (except of the system unit)
+
+This also means that it is not possible to use the \file{heaptrc} unit in
+combination with a custom memory manager, since the \file{heaptrc} unit uses
+the system memory manager to do all it's allocation. Putting the 
+\file{heaptrc} unit after the unit implementing the memory manager would 
+overwrite the memory manager record installed by the custom memory manager,
+and vice versa.
+
+The following unit shows a straightforward implementation of a custom
+memory manager using the memory manager of the \var{C} library. It is
+distributed  as a package with \fpc.
+\begin{verbatim}
+unit cmem;
+
+{$mode objfpc}
+
+interface
+
+Function Malloc (Size : Longint) : Pointer;cdecl; 
+  external 'c' name 'malloc';
+Procedure Free (P : pointer); cdecl; external 'c' name 'free';
+Procedure FreeMem (P : Pointer); cdecl; external 'c' name 'free';
+function ReAlloc (P : Pointer; Size : longint) : pointer; cdecl;
+  external 'c' name 'realloc';
+Function CAlloc (unitSize,UnitCount : Longint) : pointer;cdecl;
+  external 'c' name 'calloc';
+
+implementation
+
+Function CGetMem  (Size : Longint) : Pointer;
+
+begin
+  result:=Malloc(Size);
+end;
+
+Function CFreeMem (Var P : pointer) : Longint;
+
+begin
+  Free(P);
+  Result:=0;
+end;
+
+Function CFreeMemSize(var p:pointer;Size:Longint):Longint;
+
+begin
+  Result:=CFreeMem(P);
+end;
+
+Function CAllocMem(Size : Longint) : Pointer;
+
+begin
+  Result:=calloc(Size,1); 
+end;
+
+Function CReAllocMem (var p:pointer;Size:longint):Pointer;
+
+begin
+  Result:=realloc(p,size);
+end;
+
+Function CMemSize (p:pointer): Longint;
+
+begin
+  Result:=0;
+end;
+
+Function CMemAvail : Longint;
+
+begin
+  Result:=0;
+end;
+
+Function CMaxAvail: Longint;
+
+begin
+  Result:=0;
+end;
+
+Function CHeapSize : Longint;
+
+begin
+  Result:=0;
+end;
+                    
+
+Const
+ CMemoryManager : TMemoryManager =
+    (
+      GetMem : CGetmem;
+      FreeMem : CFreeMem;
+      FreememSize : CFreememSize;
+      AllocMem : CAllocMem;
+      ReallocMem : CReAllocMem;
+      MemSize : CMemSize;
+      MemAvail : CMemAvail;
+      MaxAvail : MaxAvail;
+      HeapSize : CHeapSize;
+    );
+  
+Var 
+  OldMemoryManager : TMemoryManager;
+
+Initialization
+  GetMemoryManager (OldMemoryManager);
+  SetMemoryManager (CmemoryManager);
+  
+Finalization
+  SetMemoryManager (OldMemoryManager);
+end.
+\end{verbatim}
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Accessing DOS memory under the GO32 extender
 % Accessing DOS memory under the GO32 extender
@@ -3310,6 +3511,8 @@ After using the selector, you must free it again using the
 More information on all this can be found in the \unitsref, the chapter on
 More information on all this can be found in the \unitsref, the chapter on
 the \file{GO32} unit.
 the \file{GO32} unit.
 
 
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Resource strings
 % Resource strings
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -4017,7 +4220,7 @@ also possible to use a windows resource compiler like \gnu
 The usage of windres is straightforward; it reads an input file
 The usage of windres is straightforward; it reads an input file
 describing the resources to create and outputs a resource file.
 describing the resources to create and outputs a resource file.
 
 
-A typical invocation of windres would be
+A typical invocation of \file{windres} would be
 \begin{verbatim}
 \begin{verbatim}
 windres -i mystrings.rc -o mystrings.res
 windres -i mystrings.rc -o mystrings.res
 \end{verbatim}
 \end{verbatim}
@@ -4039,7 +4242,7 @@ windows API calls.
 \end{description}
 \end{description}
 
 
 Some of these will be described below.
 Some of these will be described below.
-\begin{Using string tables.}
+\section{Using string tables.}
 String tables can be used to store and retrieve large collections of
 String tables can be used to store and retrieve large collections of
 strings in your application. 
 strings in your application. 
 
 
@@ -4085,8 +4288,8 @@ which can then be used. Both calls are in the windows unit.
 
 
 \section{Inserting version information}
 \section{Inserting version information}
 
 
-The win32 API allows to store versioninformation in your binaries.
-This information can be made visible with the windows Explorer, by
+The win32 API allows to store version information in your binaries.
+This information can be made visible with the \windows Explorer, by
 right-clicking on the executable or library, and selecting the
 right-clicking on the executable or library, and selecting the
 'Properties' menu. In the tab 'Version' the version information will
 'Properties' menu. In the tab 'Version' the version information will
 be displayed.
 be displayed.
@@ -4126,11 +4329,11 @@ explorer.
 The Free Component Library comes with a unit (\file{fileinfo}) that allows
 The Free Component Library comes with a unit (\file{fileinfo}) that allows
 to extract and view version information in a straightforward and easy manner;
 to extract and view version information in a straightforward and easy manner;
 the demo program that comes with it (\file{showver}) shows version information
 the demo program that comes with it (\file{showver}) shows version information
-on an arbitrary executable or DLL.
+for an arbitrary executable or DLL.
 
 
 \section{Inserting an application icon}
 \section{Inserting an application icon}
 
 
-When windows shows an executable in the explorer, it looks for an icon
+When \windows shows an executable in the Explorer, it looks for an icon
 in the executable to show in front of the filename, the application
 in the executable to show in front of the filename, the application
 icon.
 icon.