/*---------------------------------------------------------------------------- ChucK Concurrent, On-the-fly Audio Programming Language Compiler and Virtual Machine Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved. http://chuck.stanford.edu/ http://chuck.cs.princeton.edu/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U.S.A.-----------------------------------------------------------------------------*///-----------------------------------------------------------------------------// file: chuck_stats.cpp// desc: statistics - for audicle//// author: Ge Wang (gewang@cs.princeton.edu)// Perry R. Cook (prc@cs.princeton.edu)// Philip Davidson (philipd@cs.princeton.edu)// Ananya Misra (amisra@cs.princeton.edu)// date: Autumn 2004//-----------------------------------------------------------------------------#include "chuck_stats.h"// tracking#if defined(__CHUCK_STAT_TRACK__)#include "chuck_vm.h"using namespace std;// static membersChuck_Stats * Chuck_Stats::our_instance = NULL;t_CKBOOL Chuck_Stats::activations_yes = FALSE;//-----------------------------------------------------------------------------// name: instance()// desc: ...//-----------------------------------------------------------------------------Chuck_Stats * Chuck_Stats::instance(){ if( !our_instance ) { our_instance = new Chuck_Stats; assert( our_instance ); } return our_instance;}//-----------------------------------------------------------------------------// name: add_shred()// desc: ...//-----------------------------------------------------------------------------void Chuck_Stats::add_shred( Chuck_VM_Shred * shred ){ assert( vm != NULL ); assert( shred->stat == NULL ); assert( shred->xid != 0 ); Shred_Stat * stat = new Shred_Stat; stat->xid = shred->xid; stat->parent = shred->parent ? shred->parent->xid : 0; stat->state = 0; // inactive stat->shred_ref = shred; stat->spork_time = shred->wake_time; stat->wake_time = shred->wake_time; stat->name = shred->name; stat->owner = "noone"; stat->source = "remote"; if( strncmp( shred->name.c_str(), "editor->", 8 ) == 0 ) { stat->name = shred->name.c_str() + 8; stat->source = "editor"; } if( shred->parent ) { Shred_Stat * another = shreds[shred->parent->xid]; another->mutex.acquire(); another->children.push_back( stat ); another->mutex.release(); } // attach to shred shred->stat = stat; // add mutex.acquire(); shreds[shred->xid] = stat; mutex.release();}//-----------------------------------------------------------------------------// name: activate_shred()// desc: ...//-----------------------------------------------------------------------------void Chuck_Stats::activate_shred( Chuck_VM_Shred * shred ){ assert( vm != NULL ); //assert( shred->stat != NULL ); //assert( shred->id != 0 ); Shred_Stat * stat = shred->stat; // set active state stat->state = 1; // active // increment activations stat->activations++; // set the active time stat->active_time = shred->wake_time;}//-----------------------------------------------------------------------------// name: advance_time()// desc: ...//-----------------------------------------------------------------------------void Chuck_Stats::advance_time( Chuck_VM_Shred * shred, t_CKTIME to ){ assert( vm != NULL ); Shred_Stat * stat = shred->stat; // set the wake_time stat->wake_time = to; // find the period t_CKDUR diff = stat->wake_time - stat->active_time; // add to diffs stat->diff_total += diff; // put in queue stat->diffs.push( diff ); // subtract if( stat->diffs.size() > stat->num_diffs ) { stat->diff_total -= stat->diffs.front(); stat->diffs.pop(); } // calculate average stat->average_ctrl = stat->diff_total / stat->diffs.size();}//-----------------------------------------------------------------------------// name: deactivate_shred()// desc: ...//-----------------------------------------------------------------------------void Chuck_Stats::deactivate_shred( Chuck_VM_Shred * shred ){ assert( vm != NULL ); Shred_Stat * stat = shred->stat; // get diff t_CKUINT diff = stat->cycles - stat->last_cycles; // set active state stat->state = 2; // find average stat->act_cycles.push( diff ); // add to total stat->act_cycles_total += diff; // subtract if( stat->act_cycles.size() > stat->num_diffs ) { stat->act_cycles_total -= stat->act_cycles.front(); stat->act_cycles.pop(); } // the average stat->average_cycles = (t_CKFLOAT)stat->act_cycles_total / stat->act_cycles.size(); // remember the cycle count stat->last_cycles = stat->cycles; if( activations_yes ) { stat->mutex.acquire(); stat->activationss.push_back( Shred_Activation( vm->shreduler()->now_system, diff ) ); stat->mutex.release(); }}//-----------------------------------------------------------------------------// name: remove_shred()// desc: ...//-----------------------------------------------------------------------------void Chuck_Stats::remove_shred( Chuck_VM_Shred * shred ){ assert( vm != NULL ); Shred_Stat * stat = shred->stat; // set state stat->state = 3; // deleted // set free time stat->free_time = vm->shreduler()->now_system; // remove mutex.acquire(); shreds.erase( shreds.find( stat->xid ) ); done.push_back( stat ); mutex.release();}//-----------------------------------------------------------------------------// name: get_shreds()// desc: ...//-----------------------------------------------------------------------------void Chuck_Stats::get_shreds( vector<Shred_Stat *> & out, map<Shred_Stat *, Shred_Stat *> & d ){ assert( vm != NULL ); map<t_CKUINT, Shred_Stat *>::iterator iter; out.clear(); mutex.acquire(); for( iter = shreds.begin(); iter != shreds.end(); iter++ ) out.push_back( (*iter).second ); for( int i = 0; i < done.size(); i++ ) d[done[i]] = done[i]; done.clear(); mutex.release();}//-----------------------------------------------------------------------------// name: Chuck_Stats()// desc: ...//-----------------------------------------------------------------------------Chuck_Stats::Chuck_Stats(){ vm = NULL;}//-----------------------------------------------------------------------------// name: ~Chuck_Stats()// desc: ...//-----------------------------------------------------------------------------Chuck_Stats::~Chuck_Stats(){}//-----------------------------------------------------------------------------// name: get_sporked()// desc: ...//-----------------------------------------------------------------------------void Shred_Stat::get_sporked( vector<Shred_Stat *> & out ){ out.clear(); mutex.acquire(); for( int i = 0; i < children.size(); i++ ) out.push_back( children[i] ); mutex.release();}//-----------------------------------------------------------------------------// name: get_activations()// desc: ...//-----------------------------------------------------------------------------void Shred_Stat::get_activations( vector<Shred_Activation> & out ){ out.clear(); mutex.acquire(); out = activationss; activationss.clear(); mutex.release();}#endif
/*----------------------------------------------------------------------------
ChucK Concurrent, On-the-fly Audio Programming Language
Compiler and Virtual Machine
Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
http://chuck.stanford.edu/
http://chuck.cs.princeton.edu/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
U.S.A.
-----------------------------------------------------------------------------*/
//-----------------------------------------------------------------------------
// file: chuck_stats.cpp
// desc: statistics - for audicle
//
// author: Ge Wang (gewang@cs.princeton.edu)
// Perry R. Cook (prc@cs.princeton.edu)
// Philip Davidson (philipd@cs.princeton.edu)
// Ananya Misra (amisra@cs.princeton.edu)
// date: Autumn 2004
//-----------------------------------------------------------------------------
#include "chuck_stats.h"
// tracking
#if defined(__CHUCK_STAT_TRACK__)
#include "chuck_vm.h"
using namespace std;
// static members
Chuck_Stats * Chuck_Stats::our_instance = NULL;
t_CKBOOL Chuck_Stats::activations_yes = FALSE;
//-----------------------------------------------------------------------------
// name: instance()
// desc: ...
//-----------------------------------------------------------------------------
Chuck_Stats * Chuck_Stats::instance()
{
if( !our_instance )
{
our_instance = new Chuck_Stats;
assert( our_instance );
}
return our_instance;
}
//-----------------------------------------------------------------------------
// name: add_shred()
// desc: ...
//-----------------------------------------------------------------------------
void Chuck_Stats::add_shred( Chuck_VM_Shred * shred )
{
assert( vm != NULL );
assert( shred->stat == NULL );
assert( shred->xid != 0 );
Shred_Stat * stat = new Shred_Stat;
stat->xid = shred->xid;
stat->parent = shred->parent ? shred->parent->xid : 0;
stat->state = 0; // inactive
stat->shred_ref = shred;
stat->spork_time = shred->wake_time;
stat->wake_time = shred->wake_time;
stat->name = shred->name;
stat->owner = "noone";
stat->source = "remote";
if( strncmp( shred->name.c_str(), "editor->", 8 ) == 0 )
{
stat->name = shred->name.c_str() + 8;
stat->source = "editor";
}
if( shred->parent )
{
Shred_Stat * another = shreds[shred->parent->xid];
another->mutex.acquire();
another->children.push_back( stat );
another->mutex.release();
}
// attach to shred
shred->stat = stat;
// add
mutex.acquire();
shreds[shred->xid] = stat;
mutex.release();
}
//-----------------------------------------------------------------------------
// name: activate_shred()
// desc: ...
//-----------------------------------------------------------------------------
void Chuck_Stats::activate_shred( Chuck_VM_Shred * shred )
{
assert( vm != NULL );
//assert( shred->stat != NULL );
//assert( shred->id != 0 );
Shred_Stat * stat = shred->stat;
// set active state
stat->state = 1; // active
// increment activations
stat->activations++;
// set the active time
stat->active_time = shred->wake_time;
}
//-----------------------------------------------------------------------------
// name: advance_time()
// desc: ...
//-----------------------------------------------------------------------------
void Chuck_Stats::advance_time( Chuck_VM_Shred * shred, t_CKTIME to )
{
assert( vm != NULL );
Shred_Stat * stat = shred->stat;
// set the wake_time
stat->wake_time = to;
// find the period
t_CKDUR diff = stat->wake_time - stat->active_time;
// add to diffs
stat->diff_total += diff;
// put in queue
stat->diffs.push( diff );
// subtract
if( stat->diffs.size() > stat->num_diffs )
{
stat->diff_total -= stat->diffs.front();
stat->diffs.pop();
}
// calculate average
stat->average_ctrl = stat->diff_total / stat->diffs.size();
}
//-----------------------------------------------------------------------------
// name: deactivate_shred()
// desc: ...
//-----------------------------------------------------------------------------
void Chuck_Stats::deactivate_shred( Chuck_VM_Shred * shred )
{
assert( vm != NULL );
Shred_Stat * stat = shred->stat;
// get diff
t_CKUINT diff = stat->cycles - stat->last_cycles;
// set active state
stat->state = 2;
// find average
stat->act_cycles.push( diff );
// add to total
stat->act_cycles_total += diff;
// subtract
if( stat->act_cycles.size() > stat->num_diffs )
{
stat->act_cycles_total -= stat->act_cycles.front();
stat->act_cycles.pop();
}
// the average
stat->average_cycles = (t_CKFLOAT)stat->act_cycles_total / stat->act_cycles.size();
// remember the cycle count
stat->last_cycles = stat->cycles;
if( activations_yes )
{
stat->mutex.acquire();
stat->activationss.push_back( Shred_Activation( vm->shreduler()->now_system, diff ) );
stat->mutex.release();
}
}
//-----------------------------------------------------------------------------
// name: remove_shred()
// desc: ...
//-----------------------------------------------------------------------------
void Chuck_Stats::remove_shred( Chuck_VM_Shred * shred )
{
assert( vm != NULL );
Shred_Stat * stat = shred->stat;
// set state
stat->state = 3; // deleted
// set free time
stat->free_time = vm->shreduler()->now_system;
// remove
mutex.acquire();
shreds.erase( shreds.find( stat->xid ) );
done.push_back( stat );
mutex.release();
}
//-----------------------------------------------------------------------------
// name: get_shreds()
// desc: ...
//-----------------------------------------------------------------------------
void Chuck_Stats::get_shreds( vector<Shred_Stat *> & out, map<Shred_Stat *, Shred_Stat *> & d )
{
assert( vm != NULL );
map<t_CKUINT, Shred_Stat *>::iterator iter;
out.clear();
mutex.acquire();
for( iter = shreds.begin(); iter != shreds.end(); iter++ )
out.push_back( (*iter).second );
for( int i = 0; i < done.size(); i++ )
d[done[i]] = done[i];
done.clear();
mutex.release();
}
//-----------------------------------------------------------------------------
// name: Chuck_Stats()
// desc: ...
//-----------------------------------------------------------------------------
Chuck_Stats::Chuck_Stats()
{
vm = NULL;
}
//-----------------------------------------------------------------------------
// name: ~Chuck_Stats()
// desc: ...
//-----------------------------------------------------------------------------
Chuck_Stats::~Chuck_Stats()
{
}
//-----------------------------------------------------------------------------
// name: get_sporked()
// desc: ...
//-----------------------------------------------------------------------------
void Shred_Stat::get_sporked( vector<Shred_Stat *> & out )
{
out.clear();
mutex.acquire();
for( int i = 0; i < children.size(); i++ )
out.push_back( children[i] );
mutex.release();
}
//-----------------------------------------------------------------------------
// name: get_activations()
// desc: ...
//-----------------------------------------------------------------------------
void Shred_Stat::get_activations( vector<Shred_Activation> & out )
{
out.clear();
mutex.acquire();
out = activationss;
activationss.clear();
mutex.release();
}
#endif