2009-11-26 03:45 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapi.h
* harbour/include/hbvm.h
* harbour/include/hbvmpub.h
* harbour/include/hbstack.h
* harbour/src/vm/hvm.c
* harbour/src/vm/estack.c
* harbour/src/vm/fm.c
* harbour/src/vm/garbage.c
+ added new function hb_xclean() executed by GC just before resuming
suspended threads - it can be used by memory manager to clean
internal structures and release unused memory to OS.
% release unused memory to OS in hb_xclean() when DLMALLOC is used
% release unused memory in all mspaces to OS in hb_xclean() when
HB_FM_DLMT_ALLOC is used
% release unused memory in mspace when last thread detach it
% balance used mspaces between threads in hb_xclean() when
HB_FM_DLMT_ALLOC is used
This commit is contained in:
@@ -17,6 +17,25 @@
|
||||
past entries belonging to author(s): Viktor Szakats.
|
||||
*/
|
||||
|
||||
2009-11-26 03:45 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/include/hbapi.h
|
||||
* harbour/include/hbvm.h
|
||||
* harbour/include/hbvmpub.h
|
||||
* harbour/include/hbstack.h
|
||||
* harbour/src/vm/hvm.c
|
||||
* harbour/src/vm/estack.c
|
||||
* harbour/src/vm/fm.c
|
||||
* harbour/src/vm/garbage.c
|
||||
+ added new function hb_xclean() executed by GC just before resuming
|
||||
suspended threads - it can be used by memory manager to clean
|
||||
internal structures and release unused memory to OS.
|
||||
% release unused memory to OS in hb_xclean() when DLMALLOC is used
|
||||
% release unused memory in all mspaces to OS in hb_xclean() when
|
||||
HB_FM_DLMT_ALLOC is used
|
||||
% release unused memory in mspace when last thread detach it
|
||||
% balance used mspaces between threads in hb_xclean() when
|
||||
HB_FM_DLMT_ALLOC is used
|
||||
|
||||
2009-11-26 02:25 UTC+0200 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt)
|
||||
* harbour/contrib/hbwin/axcore.c
|
||||
* harbour/contrib/hbwin/olecore.c
|
||||
|
||||
@@ -497,6 +497,7 @@ extern HB_EXPORT void hb_xsetinfo( const char * szValue );
|
||||
#ifdef _HB_API_INTERNAL_
|
||||
extern void hb_xinit_thread( void );
|
||||
extern void hb_xexit_thread( void );
|
||||
extern void hb_xclean( void );
|
||||
#endif
|
||||
|
||||
#ifdef _HB_API_INTERNAL_
|
||||
|
||||
@@ -345,6 +345,7 @@ extern void * hb_stackGetI18N( void );
|
||||
extern void hb_stackSetI18N( void * );
|
||||
|
||||
extern void hb_stackIsStackRef( void *, PHB_TSD_FUNC );
|
||||
extern void hb_stackUpdateAllocator( void *, PHB_ALLOCUPDT_FUNC, int );
|
||||
|
||||
#if defined( HB_MT_VM )
|
||||
extern void * hb_stackList( void );
|
||||
|
||||
@@ -108,6 +108,9 @@ extern HB_EXPORT PHB_SYMB hb_vmProcessDynLibSymbols( PHB_SYMB pSymbols, USHORT u
|
||||
|
||||
extern void hb_vmEnumRelease( PHB_ITEM pBase, PHB_ITEM pValue );
|
||||
extern BOOL hb_vmMsgReference( PHB_ITEM pObject, PHB_DYNS pMessage, PHB_DYNS pAccMsg ); /* create extended message reference */
|
||||
|
||||
extern void hb_vmUpdateAllocator( PHB_ALLOCUPDT_FUNC pFunc, int iCount );
|
||||
|
||||
#endif
|
||||
|
||||
extern void hb_vmSetExceptionHandler( void );
|
||||
|
||||
@@ -225,6 +225,8 @@ typedef struct _HB_SYMB
|
||||
#define HB_DYNS_FUNC( hbfunc ) BOOL hbfunc( PHB_DYNS pDynSymbol, void * Cargo )
|
||||
typedef HB_DYNS_FUNC( PHB_DYNS_FUNC );
|
||||
|
||||
typedef void * ( * PHB_ALLOCUPDT_FUNC )( void *, int );
|
||||
|
||||
typedef void (*HB_INIT_FUNC)(void *);
|
||||
/* List of functions used by hb_vmAtInit()/hb_vmAtExit() */
|
||||
typedef struct _HB_FUNC_LIST
|
||||
|
||||
@@ -1312,3 +1312,21 @@ void hb_stackIsStackRef( void * pStackId, PHB_TSD_FUNC pCleanFunc )
|
||||
|
||||
hb_gtIsGtRef( pStack->hGT );
|
||||
}
|
||||
|
||||
void hb_stackUpdateAllocator( void * pStackId, PHB_ALLOCUPDT_FUNC pFunc, int iCount )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_stackUpdateAllocator(%p, %p, %d)", pStackId, pFunc, iCount));
|
||||
|
||||
#if defined( HB_MT_VM )
|
||||
{
|
||||
PHB_STACK pStack = ( PHB_STACK ) pStackId;
|
||||
|
||||
if( pStack->allocator )
|
||||
pStack->allocator = pFunc( pStack->allocator, iCount );
|
||||
}
|
||||
#else
|
||||
HB_SYMBOL_UNUSED( pStackId );
|
||||
HB_SYMBOL_UNUSED( pFunc );
|
||||
HB_SYMBOL_UNUSED( iCount );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
#include "hbmemory.ch"
|
||||
#include "hbdate.h"
|
||||
#include "hbset.h"
|
||||
#include "hbvm.h"
|
||||
#if defined( HB_MT_VM )
|
||||
# include "hbthread.h"
|
||||
# include "hbatomic.h"
|
||||
@@ -393,6 +394,42 @@ static mspace hb_mspace( void )
|
||||
return s_gm;
|
||||
}
|
||||
|
||||
static PHB_MSPACE hb_mspace_alloc( void )
|
||||
{
|
||||
if( s_mspool[ 0 ].ms == NULL && s_gm )
|
||||
{
|
||||
s_mspool[ 0 ].count = 1;
|
||||
s_mspool[ 0 ].ms = s_gm;
|
||||
return &s_mspool[ 0 ];
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, imin = 0;
|
||||
for( i = 1; i < HB_MSPACE_COUNT; ++i )
|
||||
{
|
||||
if( s_mspool[ i ].count < s_mspool[ imin ].count )
|
||||
imin = i;
|
||||
}
|
||||
if( s_mspool[ imin ].ms == NULL )
|
||||
s_mspool[ imin ].ms = create_mspace( 0, 1 );
|
||||
s_mspool[ imin ].count++;
|
||||
return &s_mspool[ imin ];
|
||||
}
|
||||
}
|
||||
|
||||
static void * hb_mspace_update( void * pAlloc, int iCount )
|
||||
{
|
||||
PHB_MSPACE pm = ( PHB_MSPACE ) pAlloc;
|
||||
|
||||
if( pm->count > iCount )
|
||||
{
|
||||
pAlloc = ( void * ) hb_mspace_alloc();
|
||||
pm->count--;
|
||||
}
|
||||
|
||||
return pAlloc;
|
||||
}
|
||||
|
||||
static void hb_mspace_cleanup( void )
|
||||
{
|
||||
int i;
|
||||
@@ -446,25 +483,7 @@ void hb_xinit_thread( void )
|
||||
if( hb_stack.allocator == NULL )
|
||||
{
|
||||
HB_FM_LOCK
|
||||
if( s_mspool[ 0 ].ms == NULL && s_gm )
|
||||
{
|
||||
s_mspool[ 0 ].count = 1;
|
||||
s_mspool[ 0 ].ms = s_gm;
|
||||
hb_stack.allocator = ( void * ) &s_mspool[ 0 ];
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, imin = 0;
|
||||
for( i = 1; i < HB_MSPACE_COUNT; ++i )
|
||||
{
|
||||
if( s_mspool[ i ].count < s_mspool[ imin ].count )
|
||||
imin = i;
|
||||
}
|
||||
if( s_mspool[ imin ].ms == NULL )
|
||||
s_mspool[ imin ].ms = create_mspace( 0, 1 );
|
||||
s_mspool[ imin ].count++;
|
||||
hb_stack.allocator = ( void * ) &s_mspool[ imin ];
|
||||
}
|
||||
hb_stack.allocator = ( void * ) hb_mspace_alloc();
|
||||
HB_FM_UNLOCK
|
||||
}
|
||||
#endif
|
||||
@@ -474,16 +493,49 @@ void hb_xexit_thread( void )
|
||||
{
|
||||
#if defined( HB_FM_DLMT_ALLOC )
|
||||
HB_STACK_TLS_PRELOAD
|
||||
if( hb_stack.allocator != NULL )
|
||||
PHB_MSPACE pm = ( PHB_MSPACE ) hb_stack.allocator;
|
||||
|
||||
if( pm )
|
||||
{
|
||||
HB_FM_LOCK
|
||||
( ( PHB_MSPACE ) hb_stack.allocator )->count--;
|
||||
hb_stack.allocator = NULL;
|
||||
HB_FM_LOCK
|
||||
if( --pm->count == 0 )
|
||||
mspace_trim( pm->ms, 0 );
|
||||
HB_FM_UNLOCK
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void hb_xclean( void )
|
||||
{
|
||||
#if defined( HB_FM_DLMT_ALLOC )
|
||||
HB_FM_LOCK
|
||||
{
|
||||
int i, imax, icount;
|
||||
|
||||
if( s_gm )
|
||||
mspace_trim( s_gm, 0 );
|
||||
|
||||
for( i = imax = icount = 0; i < HB_MSPACE_COUNT; ++i )
|
||||
{
|
||||
icount += s_mspool[ i ].count;
|
||||
if( imax < s_mspool[ i ].count )
|
||||
imax = s_mspool[ i ].count;
|
||||
mspace_trim( s_mspool[ i ].ms, 0 );
|
||||
}
|
||||
icount = ( icount + HB_MSPACE_COUNT - 1 ) / HB_MSPACE_COUNT;
|
||||
if( imax > icount )
|
||||
{
|
||||
/* balance mspaces between running threads */
|
||||
hb_vmUpdateAllocator( hb_mspace_update, icount );
|
||||
}
|
||||
}
|
||||
HB_FM_UNLOCK
|
||||
#elif defined( HB_FM_DL_ALLOC )
|
||||
dlmalloc_trim( 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void hb_xsetfilename( const char * szValue )
|
||||
{
|
||||
#ifdef HB_FM_STATISTICS
|
||||
|
||||
@@ -705,6 +705,11 @@ void hb_gcCollectAll( BOOL fForce )
|
||||
s_ulBlocksMarked = s_ulBlocks;
|
||||
#endif
|
||||
|
||||
|
||||
/* call memory manager cleanup function */
|
||||
hb_xclean();
|
||||
|
||||
/* resume suspended threads */
|
||||
hb_vmResumeThreads();
|
||||
|
||||
/* do we have any deleted blocks? */
|
||||
|
||||
@@ -11399,6 +11399,27 @@ void hb_vmIsStackRef( void )
|
||||
#endif /* HB_MT_VM */
|
||||
}
|
||||
|
||||
void hb_vmUpdateAllocator( PHB_ALLOCUPDT_FUNC pFunc, int iCount )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_vmUpdateAllocator(%p, %d)", pFunc, int iCount));
|
||||
|
||||
#if defined( HB_MT_VM )
|
||||
if( s_vmStackLst )
|
||||
{
|
||||
PHB_THREADSTATE pStack = s_vmStackLst;
|
||||
do
|
||||
{
|
||||
if( pStack->pStackId )
|
||||
hb_stackUpdateAllocator( pStack->pStackId, pFunc, iCount );
|
||||
pStack = pStack->pNext;
|
||||
}
|
||||
while( pStack != s_vmStackLst );
|
||||
}
|
||||
#else
|
||||
hb_stackUpdateAllocator( hb_stackId(), pFunc, iCount );
|
||||
#endif /* HB_MT_VM */
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* $Doc$
|
||||
|
||||
Reference in New Issue
Block a user