Beispiel #1
0
void FullMasterCM::_checkConsistency() const
{
#ifndef NDEBUG
    EQASSERT( !_instanceDatas.empty( ));
    EQASSERT( _object->isAttached() );

    if( _version == VERSION_NONE )
        return;

    uint128_t version = _version;
    for( InstanceDataDeque::const_reverse_iterator i = _instanceDatas.rbegin();
         i != _instanceDatas.rend(); ++i )
    {
        const InstanceData* data = *i;
        EQASSERT( data->os.getVersion() != VERSION_NONE );
        EQASSERTINFO( data->os.getVersion() == version,
                      data->os.getVersion() << " != " << version );
        if( data != _instanceDatas.front( ))
        {
            EQASSERTINFO( data->commitCount + _nVersions >= _commitCount,
                          data->commitCount << ", " << _commitCount << " [" <<
                          _nVersions << "]" );
        }
        --version;
    }
#endif
}
Beispiel #2
0
bool DataIStreamQueue::addDataPacket( const uint128_t& key, Command& command )
{
    EQ_TS_THREAD( _thread );
    EQASSERTINFO( _pending.size() < 100, "More than 100 pending commits");

    ObjectDataIStream* istream = 0;
    PendingStreams::iterator i = _pending.find( key );
    if( i == _pending.end( ))
        istream = _iStreamCache.alloc();
    else
        istream = i->second;

    istream->addDataPacket( command );
    if( istream->isReady( ))
    {
        if( i != _pending.end( ))
            _pending.erase( i );

        _queued.push( QueuedStream( key, istream ));
        EQASSERTINFO( _queued.getSize() < 100, "More than 100 queued commits" );
        //EQLOG( LOG_OBJECTS ) << "Queued commit " << key << std::endl;
        return true;
    }

    if( i == _pending.end( ))
    {
        _pending[ key ] = istream;
        //EQLOG( LOG_OBJECTS ) << "New incomplete commit " << key << std::endl;
        return false;
    }

    //EQLOG(LOG_OBJECTS) << "Add data to incomplete commit " << key <<std::endl;
    return false;
}
Beispiel #3
0
bool LocalNode::connect( NodePtr node )
{
    EQASSERTINFO( _state == STATE_LISTENING, _state );
    if( node->_state == STATE_CONNECTED || node->_state == STATE_LISTENING )
        return true;

    EQASSERT( node->_state == STATE_CLOSED );

    // try connecting using the given descriptions
    const ConnectionDescriptions& cds = node->getConnectionDescriptions();
    if( node->getConnectionDescriptions().empty( ))
        EQWARN << "Can't connect to a node with no listening connections"
               << std::endl;
    for( ConnectionDescriptions::const_iterator i = cds.begin();
        i != cds.end(); ++i )
    {
        ConnectionDescriptionPtr description = *i;
        if( description->type >= CONNECTIONTYPE_MULTICAST )
            continue; // Don't use multicast for primary connections

        ConnectionPtr connection = Connection::create( description );
        if( !connection || !connection->connect( ))
            continue;

        return _connect( node, connection );
    }
    return false;
}
Beispiel #4
0
bool LocalNode::close() 
{ 
    if( _state != STATE_LISTENING )
        return false;

    NodeStopPacket packet;
    send( packet );

    EQCHECK( _receiverThread->join( ));
    _cleanup();

    EQINFO << _incoming.getSize() << " connections open after close"
           << std::endl;
#ifndef NDEBUG
    const Connections& connections = _incoming.getConnections();
    for( Connections::const_iterator i = connections.begin();
         i != connections.end(); ++i )
    {
        EQINFO << "    " << *i << std::endl;
    }
#endif

    EQASSERTINFO( !hasPendingRequests(),
                  *static_cast< base::RequestHandler* >( this ));
    return true;
}
Beispiel #5
0
bool LocalNode::_connect( NodePtr node, ConnectionPtr connection )
{
    EQASSERT( connection.isValid( ));
    EQASSERT( node->getNodeID() != getNodeID( ));

    if( !node.isValid() || _state != STATE_LISTENING ||
        !connection->isConnected() || node->_state != STATE_CLOSED )
    {
        return false;
    }

    _addConnection( connection );

    // send connect packet to peer
    NodeConnectPacket packet;
    packet.requestID = registerRequest( node.get( ));
    packet.nodeID    = _id;
    packet.nodeType  = getType();
    connection->send( packet, serialize( ));

    bool connected = false;
    if( !waitRequest( packet.requestID, connected, 10000 /*ms*/ ))
    {
        EQWARN << "Node connection handshake timeout - peer not a Collage node?"
               << std::endl;
        return false;
    }
    if( !connected )
        return false;

    EQASSERT( node->_id != NodeID::ZERO );
    EQASSERTINFO( node->_id != _id, _id );
    EQINFO << node << " connected to " << *(Node*)this << std::endl;
    return true;
}
Beispiel #6
0
void Thread::untrack()
{
    EQASSERTINFO( std::string( "Watchdog" ) ==
                  std::string( Log::instance().getThreadName( )),
                  "Are you sure you want to call this method?" );
    --_numThreads();
}
Beispiel #7
0
void ObjectStore::_attachObject( Object* object, const base::UUID& id, 
                                 const uint32_t inInstanceID )
{
    EQASSERT( object );
    EQ_TS_THREAD( _receiverThread );

    uint32_t instanceID = inInstanceID;
    if( inInstanceID == EQ_INSTANCE_INVALID )
        instanceID = _genNextID( _instanceIDs );

    object->attach( id, instanceID );

    {
        base::ScopedMutex< base::SpinLock > mutex( _objects );
        Objects& objects = _objects.data[ id ];
        EQASSERTINFO( !object->isMaster() || objects.empty(),
            "Attaching master " << *object << ", " << objects.size() <<
            " attached objects with same ID, first is: " << *objects[0] );
        objects.push_back( object );
    }

    _localNode->flushCommands(); // redispatch pending commands

    EQLOG( LOG_OBJECTS ) << "attached " << *object << " @" 
                         << static_cast< void* >( object ) << std::endl;
}
Beispiel #8
0
size_t Command::alloc_( NodePtr node, LocalNodePtr localNode,
                        const uint64_t size )
{
    EQ_TS_THREAD( _writeThread );
    EQASSERT( _refCount == 0 );
    EQASSERTINFO( !_func.isValid(), *this );

    size_t allocated = 0;
    if( !_data )
    {
        _dataSize = EQ_MAX( Packet::minSize, size );
        _data = static_cast< Packet* >( malloc( _dataSize ));
        allocated = _dataSize;
    }
    else if( size > _dataSize )
    {
        allocated =  size - _dataSize;
        _dataSize = EQ_MAX( Packet::minSize, size );
        free( _data );
        _data = static_cast< Packet* >( malloc( _dataSize ));
    }

    _node = node;
    _localNode = localNode;
    _refCountMaster = 0;
    _func.clear();
    _packet = _data;
    _packet->size = size;

    return allocated;
}
/*  Begin kd-tree setup, go through full range starting with x axis.  */
void VertexBufferRoot::setupTree( VertexData& data )
{
    // data is VertexData, _data is VertexBufferData
    _data.clear();

    const Axis axis = data.getLongestAxis( 0, data.triangles.size() );

    VertexBufferNode::setupTree( data, 0, data.triangles.size(), 
                                 axis, 0, _data );
    VertexBufferNode::updateBoundingSphere();
    VertexBufferNode::updateRange();

#if 0
    // re-test all points to be in the bounding sphere
    Vertex center( _boundingSphere.array );
    float  radius        = _boundingSphere.w();
    float  radiusSquared =  radius * radius;
    for( size_t offset = 0; offset < _data.vertices.size(); ++offset )
    {
        const Vertex& vertex = _data.vertices[ offset ];
        
        const Vertex centerToPoint   = vertex - center;
        const float  distanceSquared = centerToPoint.squared_length();
        EQASSERTINFO( distanceSquared <= radiusSquared,
                      distanceSquared << " > " << radiusSquared );
    }
#endif
}
Beispiel #10
0
void ROITracker::updateDelay( const PixelViewports& pvps,
                              const uint8_t* ticket )
{
    EQASSERT( _needsUpdate );
    EQASSERTINFO( ticket == _ticket, "Wrong ticket" );

    if( ticket != _ticket )
    {
        EQERROR << "Wrong ticket" << std::endl;
        return;
    }

    uint32_t totalAreaFound = 0;
    for( uint32_t i = 0; i < pvps.size(); i++ )
        totalAreaFound += pvps[ i ].getArea();

    Area& area = (*_curFrame)[ _lastStage ].areas.back();
    if( totalAreaFound < area.pvp.getArea()*4/5 )
    {
        // ROI cutted enough, reset failure statistics
        area.lastSkip = 0;
    }else
    {
        // disable ROI for next frames, if it was failing before, 
        // increase number of frames to skip
        area.lastSkip = EQ_MIN( area.lastSkip*2 + 1, 64 );
        area.skip     = area.lastSkip;
    }
    _needsUpdate = false;
}
Beispiel #11
0
void LoadEqualizer::_assign( Compound* compound, const Viewport& vp,
                             const Range& range )
{
    EQASSERTINFO( vp == Viewport::FULL || range == Range::ALL,
                  "Mixed 2D/DB load-balancing not implemented" );

    compound->setViewport( vp );
    compound->setRange( range );
    EQLOG( LOG_LB2 ) << compound->getChannel()->getName() << " set " << vp
                     << ", " << range << std::endl;

    // save data for later use
    Data data;
    data.vp      = vp;
    data.range   = range;
    data.channel = compound->getChannel();
    data.taskID  = compound->getTaskID();

    const Compound* destCompound = getCompound();
    if( destCompound->getChannel() == compound->getChannel( ))
        data.destTaskID  = destCompound->getTaskID();

    EQASSERT( data.taskID > 0 );

    if( !vp.hasArea() || !range.hasData( )) // will not render
        data.time = 0;

    LBFrameData& frameData = _history.back();
    LBDatas& items = frameData.second;

    items.push_back( data );
}
Beispiel #12
0
uint128_t& uint128_t::operator = ( const std::string& from )
{
    char* next = 0;
#ifdef _MSC_VER
    _high = ::_strtoui64( from.c_str(), &next, 16 );
#else
    _high = ::strtoull( from.c_str(), &next, 16 );
#endif
    EQASSERT( next != from.c_str( ));
    if( *next == '\0' ) // short representation, high was 0
    {
        _low = _high;
        _high = 0;
    }
    else
    {
        EQASSERTINFO( *next == ':', from << ", " << next );
        ++next;
#ifdef _MSC_VER
        _low = ::_strtoui64( next, 0, 16 );
#else
        _low = ::strtoull( next, 0, 16 );
#endif
    }
    return *this;
}
Beispiel #13
0
void Config::setupServerConnections( const char* connectionData )
{
    std::string data = connectionData;
    co::ConnectionDescriptions descriptions;
    EQCHECK( co::deserialize( data, descriptions ));
    EQASSERTINFO( data.empty(), data << " left from " << connectionData );

    for( co::ConnectionDescriptions::const_iterator i = descriptions.begin();
         i != descriptions.end(); ++i )
    {
        co::ConnectionPtr connection = co::Connection::create( *i );
        if( !connection )
        {
            EQWARN << "Unsupported connection: " << *i << std::endl;
            continue;
        }

        if( connection->listen( ))
        {
            _connections.push_back( connection );
            getClient()->addListener( connection );
        }
        else
        {
            // TODO: Multi-config handling when same connections are spec'd
            EQASSERT( connection->isListening( ));
        }
    }
}
Beispiel #14
0
MasterCM::~MasterCM()
{
    EQASSERTINFO( _pendingDeltas.empty(), "Incomplete slave commits pending" );
    EQASSERTINFO( _queuedDeltas.isEmpty(), _queuedDeltas.getSize() <<
                  " unapplied slave commits on " << typeid( *_object ).name( ));

    while( !_pendingDeltas.empty( ))
    {
        delete _pendingDeltas.back().second;
        _pendingDeltas.pop_back();
    }

    ObjectDataIStream* is = 0;
    while( _queuedDeltas.tryPop( is ))
        delete is;
    _slaves.clear();
}
Beispiel #15
0
void Connection::setDescription( ConnectionDescriptionPtr description )
{
    EQASSERT( description.isValid( ));
    EQASSERTINFO( _description->type == description->type,
                  "Wrong connection type in description" );
    _description = description;
    EQASSERT( description->bandwidth > 0 );
}
Beispiel #16
0
void Thread::cancel()
{
    EQASSERTINFO( !isCurrent(), "Thread::cancel called from child thread" );

    EQINFO << "Canceling thread " << className( this ) << std::endl;
    _state = STATE_STOPPING;

    pthread_cancel( _id._data->pthread );
}
Beispiel #17
0
void Config::notifyAttached()
{
    fabric::Object::notifyAttached();
    EQASSERT( !_appNode )
    EQASSERT( getAppNodeID().isGenerated() )
    co::LocalNodePtr localNode = getLocalNode();
    _appNode = localNode->connect( getAppNodeID( ));
    EQASSERTINFO( _appNode, "Connection to application node failed -- " <<
                            "misconfigured connections on appNode?" );
}
Beispiel #18
0
void MasterCM::_apply( ObjectDataIStream* is )
{
    EQASSERT( !is->hasInstanceData( ));
    _object->unpack( *is );
    EQASSERTINFO( is->getRemainingBufferSize() == 0 && 
                  is->nRemainingBuffers()==0,
                  "Object " << base::className( _object ) <<
                  " did not unpack all data" );
    is->reset();
    _iStreamCache.release( is );
}
Beispiel #19
0
void Thread::exit()
{
    EQASSERTINFO( isCurrent(), "Thread::exit not called from child thread" );
    EQINFO << "Exiting thread " << className( this ) << std::endl;
    Log::instance().forceFlush();
    Log::instance().exit();

    _state = STATE_STOPPING;
    pthread_exit( 0 );
    EQUNREACHABLE;
}
Beispiel #20
0
//---------------------------------------------------------------------------
// update
//---------------------------------------------------------------------------
void Channel::_setupRenderContext( const uint128_t& frameID,
                                   RenderContext& context )
{
    context.frameID = frameID;
    context.pvp = getPixelViewport();
    context.view = _view;
    context.vp = getViewport();
    EQASSERTINFO( getNativeContext().view == context.view, 
                  getNativeContext().view << " != " << context.view << " " <<
                  getName( ));
}
Beispiel #21
0
void MessagePump::_initReceiverQueue()
{
    if( !_receiverQueue )
    {
        _receiverQueue = GetCurrentEventQueue();
        _needGlobalLock = ( _receiverQueue == GetMainEventQueue( ));
        EQASSERT( _receiverQueue );
    }

    EQASSERTINFO( _receiverQueue == GetCurrentEventQueue(),
                  "MessagePump::dispatch() called from two different threads" );
}
Beispiel #22
0
co::Object* Renderer::createObject( const uint32_t type )
{
    switch( type )
    {
      case seq::OBJECTTYPE_FRAMEDATA:
          return new eqPly::FrameData;

      default:
          EQASSERTINFO( false, "Object type " << type << " unknown" );
          return 0;
    }
}
Beispiel #23
0
DataIStreamQueue::~DataIStreamQueue()
{
    EQASSERTINFO( _pending.empty(), "Incomplete commits pending" );
    EQASSERTINFO( _queued.isEmpty(), _queued.getSize() << " unapplied commits" )

    for( PendingStreamsCIter i = _pending.begin(); i != _pending.end(); ++i )
        delete i->second;
    _pending.clear();

    QueuedStream stream;
    while( _queued.tryPop( stream ))
        delete stream.second;
}
Beispiel #24
0
Command& CommandCache::alloc( NodePtr node, LocalNodePtr localNode, 
                              const uint64_t size )
{
    EQ_TS_THREAD( _thread );
    EQASSERTINFO( size < EQ_BIT48,
                  "Out-of-sync network stream: packet size " << size << "?" );

    const Cache which = (size > Packet::minSize) ? CACHE_BIG : CACHE_SMALL;

    _compact( which );
    Command& command = _newCommand( which );
    command.alloc_( node, localNode, size );
    return command;
}
Beispiel #25
0
Object::~Object()
{
    EQASSERTINFO( !isAttached(),
                  "Object " << _id << " is still attached to node " <<
                  _localNode->getNodeID());
    
    if( _localNode.isValid() )
        _localNode->releaseObject( this );
    _localNode = 0;

    if( _cm != ObjectCM::ZERO )
        delete _cm;
    _cm = 0;
}
void UnbufferedMasterCM::removeSlave( NodePtr node )
{
    EQ_TS_THREAD( _cmdThread );
    // remove from subscribers
    const NodeID& nodeID = node->getNodeID();
    EQASSERTINFO( _slavesCount[ nodeID ] != 0, base::className( _object ));

    --_slavesCount[ nodeID ];
    if( _slavesCount[ nodeID ] == 0 )
    {
        Nodes::iterator i = find( _slaves.begin(), _slaves.end(), node );
        EQASSERT( i != _slaves.end( ));
        _slaves.erase( i );
        _slavesCount.erase( nodeID );
    }
}
Beispiel #27
0
void LocalNode::_removeConnection( ConnectionPtr connection )
{
    EQASSERT( connection.isValid( ));

    _incoming.removeConnection( connection );

    void* buffer( 0 );
    uint64_t bytes( 0 );
    connection->getRecvData( &buffer, &bytes );
    EQASSERTINFO( !connection->isConnected() || buffer, *connection );
    EQASSERT( !buffer || bytes == sizeof( uint64_t ));

    if( !connection->isClosed( ))
        connection->close(); // cancels pending IO's
    delete reinterpret_cast< uint64_t* >( buffer );
}
Beispiel #28
0
void LoadEqualizer::_clearTree( Node* node )
{
    if( !node )
        return;

    if( node->compound )
    {
        Channel* channel = node->compound->getChannel();
        EQASSERTINFO( channel, node->compound );
        channel->removeListener( this );
    }
    else
    {
        _clearTree( node->left );
        _clearTree( node->right );
    }
}
Beispiel #29
0
void Channel::_updateNearFar( const mesh::BoundingSphere& boundingSphere )
{
    // compute dynamic near/far plane of whole model
    const FrameData& frameData = _getFrameData();

    const eq::Matrix4f& rotation     = frameData.getCameraRotation();
    const eq::Matrix4f headTransform = getHeadTransform() * rotation;

    eq::Matrix4f modelInv;
    compute_inverse( headTransform, modelInv );

    const eq::Vector3f zero  = modelInv * eq::Vector3f::ZERO;
    eq::Vector3f       front = modelInv * eq::Vector3f( 0.0f, 0.0f, -1.0f );

    front -= zero;
    front.normalize();
    front *= boundingSphere.w();

    const eq::Vector3f center =  
        frameData.getCameraPosition().get_sub_vector< 3 >() -
        boundingSphere.get_sub_vector< 3 >();
    const eq::Vector3f nearPoint  = headTransform * ( center - front );
    const eq::Vector3f farPoint   = headTransform * ( center + front );

    if( useOrtho( ))
    {
        EQASSERTINFO( fabs( farPoint.z() - nearPoint.z() ) > 
                      std::numeric_limits< float >::epsilon(),
                      nearPoint << " == " << farPoint );
        setNearFar( -nearPoint.z(), -farPoint.z() );
    }
    else
    {
        // estimate minimal value of near plane based on frustum size
        const eq::Frustumf& frustum = getFrustum();
        const float width  = fabs( frustum.right() - frustum.left() );
        const float height = fabs( frustum.top() - frustum.bottom() );
        const float size   = EQ_MIN( width, height );
        const float minNear = frustum.near_plane() / size * .001f;

        const float zNear = EQ_MAX( minNear, -nearPoint.z() );
        const float zFar  = EQ_MAX( zNear * 2.f, -farPoint.z() );

        setNearFar( zNear, zFar );
    }
}
Beispiel #30
0
void WindowSystem::_chooseImpl( const std::string& name )
{
    EQASSERTINFO( _stack, "no window system available" );

    for( WindowSystemIF* ws = _stack; ws; ws = ws->_next )
    {
        // TODO: maybe we should do case insesitive comparision?
        if( ws->getName() == name )
        {
            _impl = ws;
            return;
        }
    }

    _impl = _stack;
    EQWARN << "Window system " << name << " not supported, " << "using "
           << _impl->getName() << " instead." << std::endl;
}