Khimenko Victor wrote:
The relevant hooks are GetMemPtr etc., declared in the GPC unit. You need them if you want to switch between different allocators.
Hmm. It'll require locks in multithreaded program and will be not very convenient.
I see. BTW, are the normal malloc()/free() routines and Boehm's GC thread-safe, do they do their own locking? I can't guarantee that GPC's heap handling routines are thread-safe as I haven't used threads. At first sight, I'd say they are as long as you don't use Mark/Release, but if you want to check them (or other RTS routines) more throughly, you have the source...
Perhaps we can hide it over clever #define ? Let's try:
-- cut -- uses gpc; #define gc_alloc(x) (begin var res:^x; save_ptr:GetMemType; save_ptr:=GetMemPtr; GetMemPtr:=GC_alloc; res:=new(x); GetMemPtr:=save_ptr; end)
Since the variables are declared within a statement part, you'd need a second `var' before save_ptr. Also, Pascal's `New' is syntactically different from C's malloc(). `New' is only meant for typed pointers (simple types, schemata, objects), while `GetMem' takes a memory size, but will not initialize any fields of the structure. The correspondence is `p = malloc (n)' -> `GetMem (p, n)'.
Oops. Is it possible to use compound statement as expression in GPC somehow ?
Not AFAIK. Only as an inline function. The following should work, but as I said, it will not initialize any fields, so it won't work for strings, schemata, files and other types that require initialization (but you could write a second routine specialized for strings, as shown).
inline function GCAlloc (x : SizeType) = Res : Pointer; var save_ptr : GetMemType; begin save_ptr := GetMemPtr; GetMemPtr := @GC_alloc; GetMem (Res, x); GetMemPtr := save_ptr end;
function GCAllocString (const s : String) = Res : PString; var save_ptr : GetMemType; begin save_ptr := GetMemPtr; GetMemPtr := @GC_alloc; New (Res, Length (s)); Res^ := s; GetMemPtr := save_ptr end;
var i : ^Integer; s : PString;
begin i := GCAlloc (SizeOf (Integer)); s := GCAllocString ('foo'); Writeln (s^); end.
Of course, you could then hide then `SizeOf' in a macro with something like:
{$define gc_alloc(x) GCAlloc (SizeOf (x))}
And BTW how I can continue #define on next line (C's \ in the end of line does not work).
{$define ...} can span multiple lines without any `'.
Peter Gerwinski wrote:
Khimenko Victor wrote:
Hmm. It'll require locks in multithreaded program and will be not very convenient. Perhaps we can hide it over clever #define ? Let's try: [...] You need to EXPLICITLY change new strategy every time :-(( Especially annoying since you want to use GC_malloc_atomic for plain strings... [...]
What about introducing a second `New' that allows the user to pass an additional parameter to the allocator?
Might be a solution. (Not that the syntax of `New' isn't already complicated enough... :-/)
Frank