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:
Przemyslaw Czerpak
2009-11-26 02:46:11 +00:00
parent 626faad80c
commit e1ba8c6f23
9 changed files with 144 additions and 22 deletions

View File

@@ -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

View File

@@ -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_

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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? */

View File

@@ -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$