mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 07:08:29 +02:00
167 lines
5.6 KiB
PHP
167 lines
5.6 KiB
PHP
{
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 2011 by Jonas Maebe,
|
|
member of the Free Pascal development team.
|
|
|
|
This file implements support routines for threadvarq with FPC/JVM
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
|
|
|
|
{ In Java, threadvars are represented by descendnts of java.lang.ThreadLocal.
|
|
This class has three important methods: set, get and initialValue.
|
|
|
|
If you call the "get" method of a JLThreadLocal instance in a thread for the
|
|
first time before calling "set", it will call the initialValue method and
|
|
return its result. After that, it will return whatever initialValue returned,
|
|
or the previous value instated by "set". A JLThreadLocal always keeps track of
|
|
a JLObject.
|
|
|
|
We don't want to translate accesses to threadvars into calls to get/set, since
|
|
that would mean that we would
|
|
a) have to generate different code in the compiler for read and write
|
|
accesses
|
|
b) no be able to pass threadvars to var-parameters etc
|
|
|
|
Instead, we add a method called getReadWriteReference to all of our
|
|
descendants classes that returns a pointer to the actual value of the
|
|
threadvar for this thread. This results in several cases:
|
|
a) For primitive types, we store an array of one element of that ordinal
|
|
type.
|
|
|
|
Their initialValue is simply an array of one element (automatically
|
|
initialized to 0).
|
|
|
|
The pointer returned is the "address" of element 0 (pointers to primitive
|
|
types are internally arrays pointing to element 0).
|
|
|
|
b) For non-dynamic arrays, we store that array itself (all arrays are
|
|
internally Java arrays, which descend from JLObject).
|
|
|
|
When initializing the threadvar on startup, we pass an empty copy of such
|
|
an array to the constructor and store it. Their initialValue is a deep
|
|
copy of this array, created by fpc_dynarray_copy (it accepts a number of
|
|
dimensions, because it also has to work for making a copy of dynamic
|
|
arrays whose elements are regular arrays).
|
|
|
|
The pointer returned is simply the address of the array.
|
|
|
|
c) For implicit pointer types other than regular arrays, we also store the
|
|
implicit pointer itself and keep an initialized empty instance around
|
|
that is passed to the constructor.
|
|
|
|
Their initialValue is a clone of this empty instance (can't use this for
|
|
arrays, since it would make a shallow copy of the array). Because of the
|
|
way the JLCloneable interface works, we have to call the clone method via
|
|
reflection.
|
|
|
|
The pointer returned is again simply the implicit pointer itself.
|
|
|
|
d) For all other types, we store an array of JLObject of one element,
|
|
similar as with primitive types.
|
|
|
|
Their initialValue is either nil, or optionally a value passed to the
|
|
constructor when creating the JLThreadLocal instance (e.g. an empty
|
|
string for unicodestring/ansistring, or the enum instance whose ordinal
|
|
value is 0)
|
|
|
|
The pointer returned is the address of element 0 of the array.
|
|
}
|
|
|
|
type
|
|
FpcImplicitPtrThreadVar = class(JLThreadLocal)
|
|
protected
|
|
{ all implicit pointer types are clonable }
|
|
fInstanceToClone: JLObject;
|
|
{ don't look up the clone method every time }
|
|
fCloneMethod: JLRMethod;
|
|
function initialValue: JLObject; override;
|
|
public
|
|
constructor create(initInstanceToClone: JLObject);
|
|
function getReadWriteReference: Pointer;
|
|
end;
|
|
|
|
|
|
FpcNormalArrayThreadVar = class sealed (FpcImplicitPtrThreadVar)
|
|
protected
|
|
fArrDim: longint;
|
|
fArrTyp: widechar;
|
|
function initialValue: JLObject; override;
|
|
public
|
|
constructor create(initInstanceToClone: JLObject; arrdim: longint; arrtyp: widechar);
|
|
end;
|
|
|
|
|
|
FpcBooleanThreadVar = class sealed (JLThreadLocal)
|
|
protected
|
|
function initialValue: JLObject; override;
|
|
public
|
|
function getReadWriteReference: PBoolean;
|
|
end;
|
|
|
|
FpcByteThreadVar = class sealed (JLThreadLocal)
|
|
protected
|
|
function initialValue: JLObject; override;
|
|
public
|
|
function getReadWriteReference: PShortint;
|
|
end;
|
|
|
|
FpcShortThreadVar = class sealed (JLThreadLocal)
|
|
protected
|
|
function initialValue: JLObject; override;
|
|
public
|
|
function getReadWriteReference: PSmallint;
|
|
end;
|
|
|
|
FpcIntThreadVar = class sealed (JLThreadLocal)
|
|
protected
|
|
function initialValue: JLObject; override;
|
|
public
|
|
function getReadWriteReference: PLongint;
|
|
end;
|
|
|
|
FpcLongThreadVar = class sealed (JLThreadLocal)
|
|
protected
|
|
function initialValue: JLObject; override;
|
|
public
|
|
function getReadWriteReference: PInt64;
|
|
end;
|
|
|
|
FpcCharThreadVar = class sealed (JLThreadLocal)
|
|
protected
|
|
function initialValue: JLObject; override;
|
|
public
|
|
function getReadWriteReference: PWideChar;
|
|
end;
|
|
|
|
FpcFloatThreadVar = class sealed (JLThreadLocal)
|
|
protected
|
|
function initialValue: JLObject; override;
|
|
public
|
|
function getReadWriteReference: PSingle;
|
|
end;
|
|
|
|
FpcDoubleThreadVar = class sealed (JLThreadLocal)
|
|
protected
|
|
function initialValue: JLObject; override;
|
|
public
|
|
function getReadWriteReference: PDouble;
|
|
end;
|
|
|
|
FpcPointerThreadVar = class sealed (JLThreadLocal)
|
|
protected
|
|
fInitVal: JLObject;
|
|
function initialValue: JLObject; override;
|
|
public
|
|
function getReadWriteReference: PPointer;
|
|
constructor create(initVal: JLObject);overload;
|
|
end;
|
|
|