Return to PyF95++.
Reference counting is a method of tracking the number of entities which currently have access to data so that when the data is no longer in use it may be deleted without causing invalid references. To accomplish this, we make use of the "modules as classes" pattern. This page will discuss the basic implementation of reference counting used in the PyF95++ project.
Basic Implementation Information
There are several important Fortran features which act as enablers for the reference counting pattern.
- Overridden operators
The pointer is particularly useful as it allows several variables to reference the same data. In implementing the pattern a module is created to contain the ref counted type. Inside are the definitions for two types, an internal type that holds the data and an external type that contains a pointer to the data, and a series of functions and subroutines which operate upon the external type. To illustrate this concept, consider the following module:
module class_MyType implicit none type MyType_ integer :: refCount=0 real(kind=8) :: value=0.d00 end type MyType_ type MyType type (MyType_), pointer :: shared => null() end type MyType contains ... end module class_MyType
In this module an internal type MyType_, denoted as internal in the PyF95++ STL by appending an "_" (underscore) character, is defined to house a double precision variable, value. An external type, MyType, contains a pointer to an internal type and is initialized to be a dissociated pointer. This is enough to begin to understand the pattern. When an external type is initialized an internal type is created which houses some data. More external types can be declared and pointed to this data --- and each time the refCount counter will be incremented. When one of the external types is deallocated the refCount of the internal type will be decreased, and, if it becomes zero any pointer or allocatable data could be deallocated.
Now, how does one ensure the counter is incremented and decremented appropriately?
Since we use Fortran modules as classes in the STL, we also use a standard set of names for functions and subroutines associated with the reference counting pattern. There are also a number of functions which must be implemented in order to use your ref-counted type with our STL containers (if you choose to make them refCounted).
- init --- function init(this) result(err)
- An initialization function for an external type. This creates an internal type and points the external type being initialized to that new internal type.
- delete --- function delete(this) result(err)
- A deallocation function for a reference counted type. This operates on the external type and may or may not cause the deallocation of internal data depending upon the resultant reference count.
- valid --- function(this) result(b)
- A function which returns true or false depending on whether or not the external type has a non-null pointer.
- refCount --- function refCount(this) result(cnt)
- A function to return the current reference count of the internal type pointed to by the external type, 'this'.
- operator(=) --- subroutine(this,other)
- A subroutine must be created which allows reference counter incrementation when the equals operator is used.
- operator(.is.) --- function(this,other) result(b)
- A function which compares two external types to determine if they are pointing to the same internal type.
Putting It All Together
Some example implementation and additional information is given at PyF95++/STL/Reference_Counting. That page specifically is meant to give the user an understanding of how to interact with and manipulate a reference counted object.
 Car, D., "A Reference Counting Implementation in Fortran 95/2003," ACM SIGPLAN Fortran Forum, Volume 29 Issue 1, April 2010.
List and Car