On Tue, 12 Feb 2008, Ryszard Głąb wrote:
>   OK, hb_gcAlloc() can automatically lock the pointer however we
> still have to have hb_gcUnlock() function to unlock it distinctly
> after the assignment to the item stored inside the iternal VM 
> storages (local stack, statics, etc). If the item will remain 
> locked then it will be never released by the GC.

Yes of course. But hb_gcUnlock() will not have to be public API.
It can be covered by _HB_API_INTERNAL_ macro like hb_gcRefInc()
and similar functions.
And to be more precise I plan to add new function hb_gcAttach()
which will increase reference counter and unlock the GC block.

> Poiters cannot be indirectly unlocked during hb_itemPutPtrGC because
> using the following code:
> HB_ITEM item;
> item.type = HB_IT_NIL;
> hb_itemPutPtrGC( &item, hb_gcAlloc( size, someFunc ) );
> will end with an item storing an unlocked pointer that will be
> released prematurely by the GC.

1-st it's a code example I'm fighting to eliminate: code which creates
unknown for GC C level items. In last years I spent to much time helping
different people in locating bugs caused by such code.
2-nd in current GC it will not be release prematurely because
I added code which will detect such situation and will rise RT
error - exactly the same as Pritpal noticed recently and reported
here. This code was necessary to detect bugs in .prg destructors
and protect against internal memory corruption caused by such
wrong .prg destructors.

>   In summary, current code is safe if there is no call to 
> hb_gcCollect() in initialization code (in other words: between 
> hb_gcAlloc() and the assignment to an item known to the
> GC). If you plan to run the GC in separate thread then for sure
> hb_gcAlloc() should return locked pointer however the pointer
> will have to be unlocked distinctly by the call to hb_gcUnlock()
> after the asignment.
>   I don't understand what you mean writing 'automatic GC call' 
> then it is possible that we are talking aout different things but
> currently I will leave gcLock/gcUnlock as they are.

Automatic GC call means that it can be activated by any VM/RTL
function when some conditions will be passed, f.e. number of
GC blocks or total amount of allocated memory between GC passes
will reach some limit. It means that for sure hb_xgrab()/hb_gcAlloc()
can activate GC but maybe also some other places. I intentionally do
not want to document which exactly ones because I want to reserve such
decision for us for future updates.
The GC executed by separated thread it's also not a problem and it
can be implemented even without automatically locked hb_gcAlloc's
blocks. But ONLINE GC which can be executed without stopping other
threads and without mutex in time critical places in HVM code is
much more complicated thing. For sure I do not plan to introduce it
now. Maybe if it will be necessary in the future then I will think
about it but it will be necessary to change most of current GC code.

I want to reduce API functions which may cause internal errors
in different places when are used in wrong way. And hb_gcLock()/
hb_gcUnlock() are potentially such functions. Now I do not see any
code which may need it as long as it does not use some thicks like
unknown for GC HB_ITEMs.

> > BTW I would like to also ask about real usage of marksweep function.
> > I know what it does but is it still necessary for 3-rd party code
> > with current GC? Can someone who uses it say what is its exact job
> > in his code?
>   I have added this functionality to use it in future sql rdd. I am still
> at design phase but I plan to use a linked list of rows (or pages)
> returned by the sql client. Every row will store the HB_ITEM structure. 
> I don't want to use array because of reallocation problems. This linked
> list will be stored probably in workarea structure. Thus I need some method
> to prevent deallocation of values stored in this internal workarea space.

Array reallocation should not be a problem. Now we do not have any
preallocation code for arrays but it can be and for sure will be added
in the future. xHarbour already has such feature. it's few lines only.
You can even implement such feature yourself for SQL RDD by keeping
index to free raw in array in additional variable and multiple the
array size by 2 when the pointer reach limit. The cost of reallocation
will be n*log2(n)/2 where n is maximum array size - unimportant if
you compere it to cost of row creation. You can also keep raws in
items allocated by hb_itmeNew() and create list of such items though
here the cost will be bigger but you ill not need continuous memory
block. IMHO everything is better then touching item internals.

best regards,
Przemek
_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to