Skip to content

Commit

Permalink
re-add VM prune_ugens() as part of detach_ugens()
Browse files Browse the repository at this point in the history
  • Loading branch information
gewang committed Nov 21, 2024
1 parent 01efb5a commit 3a09e40
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 46 deletions.
105 changes: 59 additions & 46 deletions src/core/chuck_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1904,6 +1904,7 @@ void Chuck_VM_Shred::detach_ugens()
{
// get iterator to our map
map<Chuck_UGen *, Chuck_UGen *>::iterator iter = m_ugen_map.begin();
// iterate over ugen attached to this shred
while( iter != m_ugen_map.end() )
{
// get the ugen
Expand All @@ -1914,10 +1915,11 @@ void Chuck_VM_Shred::detach_ugens()
ugen->setOriginShred( NULL );
// disconnect
ugen->disconnect( TRUE );

// advance the iterator
iter++;
}
// prune
prune_ugens();
// clear map
m_ugen_map.clear();
}
Expand All @@ -1934,51 +1936,62 @@ void Chuck_VM_Shred::detach_ugens()
// 1.5.4.2 (ge) NOTE this is no longer necessary as the new UGen/shred
// semantics have been updated for these types of checks to happen on
// a per-UGen level
//-----------------------------------------------------------------------------
//void Chuck_VM_Shred::prune_ugens()
//{
// // check if we have anything in ugen map for this shred
// if( !m_ugen_map.size() )
// return;
//
// // ugens to release
// std::vector<Chuck_UGen *> release_v;
//
// // get iterator to our map
// map<Chuck_UGen *, Chuck_UGen *>::iterator iter = m_ugen_map.begin();
// while( iter != m_ugen_map.end() )
// {
// // get the ugen
// Chuck_UGen * ugen = iter->first;
//
// // verify
// assert( ugen->refcount() > 0 );
// // check for ugens with only one reference (to this shred)
// if( ugen->refcount() == 1 ) release_v.push_back( ugen );
//
// // advance the iterator
// iter++;
// }
//
// // check if anything to prune
// if( release_v.size() )
// {
// // log
// EM_log( CK_LOG_FINE, "pruning '%ld' ugen(s) from shred: %x...", release_v.size(), this );
//
// // loop over vector
// for( vector<Chuck_UGen *>::iterator rvi = release_v.begin();
// rvi != release_v.end(); rvi++ )
// {
// // remove from map
// m_ugen_map.erase( *rvi );
// // release the ugen
// CK_SAFE_RELEASE( *rvi );
// }
// // clear the release vector
// release_v.clear();
// }
//}
// 1.5.4.2 (ge) okay maybe we still do need this for OTF operations,
// e.g., remove / replace, since currently those do not properly unwind
// the execution contexts (see TODO below)
// NOTE: this does not cover cases where a UGen has multiple variables
// referencing it on this shred; currently there is no mechanism to know
// if references are within a shred's context or outside of it
//-----------------------------------------------------------------------------
// TODO: the right way to handle this would be to carefully unwind the
// execution context: function call stacks and stmt-level releases
// possibly letting the current stmt finish if there is memory to be released
// AND then unwinding the call stack and releasing things along the way
//-----------------------------------------------------------------------------
void Chuck_VM_Shred::prune_ugens()
{
// check if we have anything in ugen map for this shred
if( !m_ugen_map.size() )
return;

// ugens to release
std::vector<Chuck_UGen *> release_v;

// get iterator to our map
map<Chuck_UGen *, Chuck_UGen *>::iterator iter = m_ugen_map.begin();
while( iter != m_ugen_map.end() )
{
// get the ugen
Chuck_UGen * ugen = iter->first;

// verify
assert( ugen->refcount() > 0 );
// check for ugens with only one reference (to this shred)
if( ugen->refcount() == 1 ) release_v.push_back( ugen );

// advance the iterator
iter++;
}

// check if anything to prune
if( release_v.size() )
{
// log
EM_log( CK_LOG_FINE, "pruning '%ld' ugen(s) from shred: %x...", release_v.size(), this );

// loop over vector
for( vector<Chuck_UGen *>::iterator rvi = release_v.begin();
rvi != release_v.end(); rvi++ )
{
// remove from map
m_ugen_map.erase( *rvi );
// release the ugen
CK_SAFE_RELEASE( *rvi );
}
// clear the release vector
release_v.clear();
}
}



Expand Down
2 changes: 2 additions & 0 deletions src/core/chuck_vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ struct Chuck_VM_Shred : public Chuck_Object
t_CKBOOL remove( Chuck_UGen * ugen );
// detach all associate ugens | 1.5.1.5 (ge) added
void detach_ugens();
// remove all attached ugen, releasing ones without external reference
void prune_ugens();

public:
// manually trigger a per-shred garbage collection pass | 1.5.2.0 (ge) added
Expand Down

0 comments on commit 3a09e40

Please sign in to comment.