コード例 #1
0
void ChaosRouter::_OutputAdvance( )
{
  Flit *f, *f2;
  Credit *c;
  bool advanced;
  int  mq;

  _crossbar_pipe->WriteAll( 0 );

  for ( int i = 0; i < _inputs; ++i ) {
    if ( ( ( _input_output_match[i] != -1 ) ||
	   ( _input_mq_match[i] != -1 ) ) &&
	 ( !_input_frame[i].empty( ) ) ) {
      
      advanced = false;
      f = _input_frame[i].front( );

      /*if ( ! ) {

      } else {
	cout << "Input = " << i 
	     << ", input_output_match = " << _input_output_match[i]
	     << ", input_mq_match = " << _input_mq_match[i] << endl;
	Error( "Input queue empty, but matched!" );
	}*/

      if ( _input_output_match[i] != -1 ) {
	if ( f->tail ) {
	  _output_matched[_input_output_match[i]] = false;
	}

	_crossbar_pipe->Write( f, _input_output_match[i] );
	
	if ( f->watch ) {
	  *gWatchOut << GetSimTime() << " | " << FullName() << " | "
		      << "Flit traversing crossbar from input queue " 
		      << i << " at " 
		      << FullName() << endl
		      << *f;
	}

	advanced = true;

      } else if ( !_MultiQueueFull( _input_mq_match[i] ) ) {

	mq = _input_mq_match[i];

	if ( f->head ) {
	  _rf( this, f, i, _mq_route[mq], false );
	  _mq_age[mq] = 0;

	  if ( _multi_state[mq] == empty ) {
	    _multi_state[mq] = filling;
	  } else if ( _multi_state[mq] == leaving ) {
	    _multi_state[mq] = shared;
	  } else {
	    Error( "Multi-queue received head while not empty or leaving!" );
	  }
	}
	
	if ( f->tail ) {
	  _mq_matched[mq] = false;

	  if ( _multi_state[mq] == filling ) {
	    _multi_state[mq] = full;
	  } else if ( _multi_state[mq] == cut_through ) {
	    _multi_state[mq] = leaving; 
	  } else {
	    Error( "Multi-queue received tail while not filling or cutting-through!" );
	  }
	}
	
	_multi_queue[mq].push( f );
	
	if ( f->watch ) {
	  *gWatchOut << GetSimTime() << " | " << FullName() << " | "
		      << "Flit stored in multiqueue at " 
		      << FullName() << endl
		      << "State = " << _multi_state[mq] << endl
		      << *f;
	}

	advanced = true;
      }

      if ( advanced ) {
	_input_frame[i].pop( );

	if ( f->tail ) { // last in packet, update state
	  if ( _input_state[i] == leaving ) {
	    _input_state[i] = empty;
	  } else if ( _input_state[i] == shared ) {
	    _input_state[i] = filling;
	    f2 = _input_frame[i].front( );
	    // update routes
	    _rf( this, f2, i, _input_route[i], false );
	  }
	  
	  _input_output_match[i] = -1;
	  _input_mq_match[i]     = -1;
	}
	
	c = Credit::New( );
	c->vc.insert(0);
	_credit_queue[i].push( c );
      }
    }
  }

  for ( int m = 0; m < _multi_queue_size; ++m ) {
    if ( _multi_match[m] != -1 ) {
      if ( !_multi_queue[m].empty( ) ) {
	f = _multi_queue[m].front( );
	_multi_queue[m].pop( );
      } else {
	cout << "State = " << _multi_state[m] << endl;
	Error( "Multi queue empty, but matched!" );
      }

      _crossbar_pipe->Write( f, _multi_match[m] );

      if ( f->watch ) {
	*gWatchOut << GetSimTime() << " | " << FullName() << " | "
		    << "Flit traversing crossbar from multiqueue slot "
		    << m << " at " 
		    << FullName() << endl
		    << *f;
      }

      if ( f->head ) {
	if ( _multi_state[m] == filling ) {
	  _multi_state[m] = cut_through;
	} else if ( _multi_state[m] == full ) {
	  _multi_state[m] = leaving;
	} else {
	  Error( "Multi-queue sent head while not filling or full!" );
	}
      }

      if ( f->tail ) {
	_output_matched[_multi_match[m]] = false;
	_multi_match[m] = -1;

	if ( _multi_state[m] == shared ) {
	  _multi_state[m] = filling;
	} else if ( _multi_state[m] == leaving ) {
	  _multi_state[m] = empty;
	} else {
	  cout << "State = " << _multi_state[m] << endl;
	  cout << *f;
	  Error( "Multi-queue sent tail while not leaving or shared!" );
	}
      }
    }

    _mq_age[m]++;
  }
}
コード例 #2
0
void ChaosRouter::ReadInputs( )
{
  Flit   *f;
  Credit *c;

  for ( int input = 0; input < _inputs; ++input ) { 
    f = _input_channels[input]->Receive();

    if ( f ) {
      _input_frame[input].push( f );

      if ( f->watch ) {
	*gWatchOut << GetSimTime() << " | " << FullName() << " | "
		    << "Flit arriving at " << FullName() 
		    << " on channel " << input << endl
		    << *f;
      }

      switch( _input_state[input] ) {
      case empty:
	if ( f->head ) {
	  if ( f->tail ) {
	    _input_state[input] = full;
	  } else {
	    _input_state[input] = filling;
	  }
	  _rf( this, f, input, _input_route[input], false );
	} else {
	  cout << *f;
	  Error( "Empty buffer received non-head flit!" );
	}
	break;

      case filling:
	if ( f->tail ) {
	  _input_state[input] = full;
	} else if ( f->head ) {
	  Error( "Input buffer received another head before previous tail!" );
	}
	break;
	
      case full:
	Error( "Received flit while full!" );
	break;

      case leaving:
	if ( f->head ) {
	  _input_state[input] = shared;

	  if ( f->tail ) {
	    Error( "Received single-flit packet in leaving state!" );
	  }
	} else {
	  cout << *f;
	  Error( "Received non-head flit while packet leaving!" );
	}
	break;

      case cut_through:
	if ( f->tail ) {
	  _input_state[input] = leaving;
	} 
	if ( f->head ) {
	  cout << *f;
	  Error( "Received head flit in cut through buffer!" );
	}
	break;

      case shared:
	if ( f->head ) {
	  Error( "Shared buffer received another head!" );
	} else if ( f->tail ) {
	  cout << "Input " << input << endl;
	  cout << *f;
	  Error( "Shared buffer received another tail!" );
	}
	break;
      }
    }
  }

  // Process incoming credits

  for ( int output = 0; output < _outputs; ++output ) {
    c = _output_credits[output]->Receive();
    
    if ( c ) {
      _next_queue_cnt[output]--;

      if ( _next_queue_cnt[output] < 0 ) {
	Error( "Next queue count fell below zero!" );
      }

      c->Free();
    }
  }
}
コード例 #3
0
EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {

    {
        Mutex::Autolock _rf(refLock);

        refs++;
        if (refs > 1) {
            if (major != NULL)
                *major = VERSION_MAJOR;
            if (minor != NULL)
                *minor = VERSION_MINOR;
            while(!eglIsInitialized) refCond.wait(refLock);
            return EGL_TRUE;
        }

        while(eglIsInitialized) refCond.wait(refLock);
    }

    {
        Mutex::Autolock _l(lock);

#if EGL_TRACE

        // Called both at early_init time and at this time. (Early_init is pre-zygote, so
        // the information from that call may be stale.)
        initEglTraceLevel();
        initEglDebugLevel();

#endif

        setGLHooksThreadSpecific(&gHooksNoContext);

        // initialize each EGL and
        // build our own extension string first, based on the extension we know
        // and the extension supported by our client implementation

        egl_connection_t* const cnx = &gEGLImpl;
        cnx->major = -1;
        cnx->minor = -1;
        if (cnx->dso) {
            EGLDisplay idpy = disp.dpy;
            if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
                //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
                //        idpy, cnx->major, cnx->minor, cnx);

                // display is now initialized
                disp.state = egl_display_t::INITIALIZED;

                // get the query-strings for this display for each implementation
                disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
                        EGL_VENDOR);
                disp.queryString.version = cnx->egl.eglQueryString(idpy,
                        EGL_VERSION);
                disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
                        EGL_EXTENSIONS);
                disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
                        EGL_CLIENT_APIS);

            } else {
                ALOGW("eglInitialize(%p) failed (%s)", idpy,
                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
            }
        }

        // the query strings are per-display
        mVendorString.setTo(sVendorString);
        mVersionString.setTo(sVersionString);
        mClientApiString.setTo(sClientApiString);

        mExtensionString.setTo(gBuiltinExtensionString);
        char const* start = gExtensionString;
        char const* end;
        do {
            // find the space separating this extension for the next one
            end = strchr(start, ' ');
            if (end) {
                // length of the extension string
                const size_t len = end - start;
                if (len) {
                    // NOTE: we could avoid the copy if we had strnstr.
                    const String8 ext(start, len);
                    if (findExtension(disp.queryString.extensions, ext.string(),
                            len)) {
                        mExtensionString.append(start, len+1);
                    }
                }
                // process the next extension string, and skip the space.
                start = end + 1;
            }
        } while (end);

        egl_cache_t::get()->initialize(this);

        char value[PROPERTY_VALUE_MAX];
        property_get("debug.egl.finish", value, "0");
        if (atoi(value)) {
            finishOnSwap = true;
        }

        property_get("debug.egl.traceGpuCompletion", value, "0");
        if (atoi(value)) {
            traceGpuCompletion = true;
        }

        if (major != NULL)
            *major = VERSION_MAJOR;
        if (minor != NULL)
            *minor = VERSION_MINOR;

        mHibernation.setDisplayValid(true);
    }

    {
        Mutex::Autolock _rf(refLock);
        eglIsInitialized = true;
        refCond.broadcast();
    }

    return EGL_TRUE;
}
コード例 #4
0
void GPUTrafficManager::_Step()
{
  bool flits_in_flight = false;
  for(int c = 0; c < _classes; ++c) {
    flits_in_flight |= !_total_in_flight_flits[c].empty();
  }
  if(flits_in_flight && (_deadlock_timer++ >= _deadlock_warn_timeout)){
    _deadlock_timer = 0;
    cout << "WARNING: Possible network deadlock.\n";
  }
  
  vector<map<int, Flit *> > flits(_subnets);
  
  for ( int subnet = 0; subnet < _subnets; ++subnet ) {
    for ( int n = 0; n < _nodes; ++n ) {
      Flit * const f = _net[subnet]->ReadFlit( n );
      if ( f ) {
        if(f->watch) {
          *gWatchOut << GetSimTime() << " | "
          << "node" << n << " | "
          << "Ejecting flit " << f->id
          << " (packet " << f->pid << ")"
          << " from VC " << f->vc
          << "." << endl;
        }

        if(g_hpcl_comp_config.hpcl_comp_en == 0) {
          g_icnt_interface->WriteOutBuffer(subnet, n, f);
          //added by kh(030816)
          g_hpcl_network_anal->add_sample(hpcl_network_anal::NORMAL_FLIT_NO, 1);
          ///

        } else {
	  //added by kh (030816)
	  //(2.1.a) all reply flits (even write reply) are injected to decompressor for maintaining the order of flits.
	  //coming from the same vc
	  //Decompression: WRITE_REPLY should go through decomp, although no data is compressed.
	  //READ_REPLY = {f1,f2,f3,f4,f5}, WRITE_REPLY = {f6}
	  //Problematic case queue: f1,f2,f6,f3,f4,f5.
	  if(f->type == Flit::READ_REPLY || f->type == Flit::WRITE_REPLY) {	//only sm receives

	    assert(g_hpcl_global_decomp_pl_2B[n]);
	    //inject a flit to decompressor
	    hpcl_comp_pl_data* pl_data = new hpcl_comp_pl_data;
	    pl_data->add_comp_pl_data(f);
	    g_hpcl_global_decomp_pl_2B[n]->set_input_data(pl_data);

	    //added by kh (030316)
	    //set vc info to compressed flits.
	    for(int i = 0; i < f->compressed_other_flits.size(); i++) {
	      Flit* cf = f->compressed_other_flits[i];
	      assert(cf);
	      cf->vc = f->vc;
	    }
	    ///
	    //delete pl_data;

	    //added by kh (030816)
	    g_hpcl_network_anal->add_sample(hpcl_network_anal::NORMAL_FLIT_NO, 1);

	    if(f->compressed_other_flits.size() > 0) {
	      g_hpcl_network_anal->add_sample(hpcl_network_anal::READ_REPLY_COMP_FLIT_NO, f->compressed_other_flits.size()+1);
	    } else {
	      g_hpcl_network_anal->add_sample(hpcl_network_anal::READ_REPLY_UNCOMP_FLIT_NO, 1);
	    }
	    ///

	  } else if(f->type == Flit::CTRL_MSG) {	//(2.2.a) all ctrl flits are injected to decompressor

	    //std::cout << "f->id " << f->id << " f->src " << f->src << " f->dest " << f->dest << " node " << n << std::endl;
	    hpcl_comp_pl_data* pl_data = new hpcl_comp_pl_data;
	    pl_data->add_comp_pl_data(f);
	    g_hpcl_global_decomp_pl_2B[n]->set_input_data(pl_data);

	    //added by kh (030816)
	    g_hpcl_network_anal->add_sample(hpcl_network_anal::CTRL_FLIT_NO,1);
	    ///

	  } else {

	    g_icnt_interface->WriteOutBuffer(subnet, n, f);

	    //added by kh (030816)
	    g_hpcl_network_anal->add_sample(hpcl_network_anal::NORMAL_FLIT_NO, 1);
	    ///

	  }
	  ///
        }
      }
      

      g_icnt_interface->Transfer2BoundaryBuffer(subnet, n);
      Flit* const ejected_flit = g_icnt_interface->GetEjectedFlit(subnet, n);
      if (ejected_flit) {
        if(ejected_flit->head)
          assert(ejected_flit->dest == n);
        if(ejected_flit->watch) {
          *gWatchOut << GetSimTime() << " | "
          << "node" << n << " | "
          << "Ejected flit " << ejected_flit->id
          << " (packet " << ejected_flit->pid
          << " VC " << ejected_flit->vc << ")"
          << "from ejection buffer." << endl;
        }
        flits[subnet].insert(make_pair(n, ejected_flit));
        if((_sim_state == warming_up) || (_sim_state == running)) {
          ++_accepted_flits[ejected_flit->cl][n];
          if(ejected_flit->tail) {
            ++_accepted_packets[ejected_flit->cl][n];
          }
        }
      }
    
      // Processing the credit From the network
      Credit * const c = _net[subnet]->ReadCredit( n );
      if ( c ) {
#ifdef TRACK_FLOWS
        for(set<int>::const_iterator iter = c->vc.begin(); iter != c->vc.end(); ++iter) {
          int const vc = *iter;
          assert(!_outstanding_classes[n][subnet][vc].empty());
          int cl = _outstanding_classes[n][subnet][vc].front();
          _outstanding_classes[n][subnet][vc].pop();
          assert(_outstanding_credits[cl][subnet][n] > 0);
          --_outstanding_credits[cl][subnet][n];
        }
#endif
        _buf_states[n][subnet]->ProcessCredit(c);
        c->Free();
      }
    }
    _net[subnet]->ReadInputs( );
  }


  if(g_hpcl_comp_config.hpcl_comp_en == 1)
  {
    //added by kh (030816)
    //(2.3) Decompressor
    for(int i = 0; i < g_hpcl_global_decomp_pl_2B.size(); i++)
    {
      if(!g_hpcl_global_decomp_pl_2B[i])	continue;

      g_hpcl_global_decomp_pl_2B[i]->run(getTime()+getTotalTime());
      hpcl_comp_pl_data* comp_pl_data = g_hpcl_global_decomp_pl_2B[i]->get_output_data();
      Flit* flit = comp_pl_data->get_flit_ptr();
      if(flit) {
	int subnet = 0;
	assert(flit->const_dest == i);
	//std::cout << "Flit " << flit->id << " type " << flit->type << " is out from decomp" << std::endl;
	/*
	std::cout << GetSimTime() << "| MYEJECT | node " << i << " Flit " << flit->id << " type " << flit->type << " tail " << flit->tail << " vc " << flit->vc;
	if(flit->type == Flit::ANY_TYPE)	std::cout << " ctrl " << std::endl;
	else				std::cout << " mf " << ((mem_fetch*)flit->data)->get_request_uid() << std::endl;
	*/

	//std::cout << "Flit " << flit->id << " enc_status " << flit->m_enc_status;
	#ifdef CORRECTNESS_CHECK
	if(flit->m_enc_status == 1) {
	  std::cout << "dec_status " << flit->check_correctness() << std::endl;
	  if(flit->check_correctness() == false) {

	    printf("flit %d has incorrect decoding!\n", flit->id);

	    printf("\traw_data = ");
	    for(int k = flit->raw_data.size()-1; k >=0; k--) {
		    printf("%02x", flit->raw_data[k]);
	    }
	    printf("\n");

	    printf("\tdec_data = ");
	    for(int k = flit->decomp_data.size()-1; k >=0; k--) {
		    printf("%02x", flit->decomp_data[k]);
	    }
	    printf("\n");
	  }
	}
	#endif

	g_icnt_interface->WriteOutBuffer(subnet, i, flit);
      }

      //reset output data
      g_hpcl_global_decomp_pl_2B[i]->reset_output_data();
    }
    ///


    //added by kh (030816)
    //(1.2.c) generate/inject ctrl flit is injected to NI injection buffer
    for(int i = 0; i < g_hpcl_global_comp_pl_2B.size(); i++)
    {
      if(!g_hpcl_global_comp_pl_2B[i])	continue;
      if(g_hpcl_global_comp_pl_2B[i]->has_out_dict_ctrl_msg() == false)	continue;
      if(g_hpcl_global_comp_pl_2B[i]->get_state() == hpcl_comp_pl<unsigned short>::HPCL_COMP_RUN)	continue;

      hpcl_dict_ctrl_msg<unsigned short>* ctrl_msg = g_hpcl_global_comp_pl_2B[i]->front_out_dict_ctrl_msg();
      int packet_size = 1;	//1 flit
      Flit::FlitType packet_type = Flit::CTRL_MSG;
      void* data = NULL;
      assert(ctrl_msg->get_dest_node()>=0);
      int subnet = 0;
      int response_size = 32; 	//32bytes

      //send ctrl from MC
      int sender_device_id = -1;
      if(g_mc_placement_config.is_mc_node(i)) {
	sender_device_id = g_mc_placement_config.get_mc_node_index(i) + 56;	//56 SMs and 8 MCs
      }
      assert(sender_device_id >= 0);

      int sender_node_id = i;
      int receiver_node_id = ctrl_msg->get_dest_node();
      int receiver_device_id = g_mc_placement_config.get_sm_node_index(receiver_node_id);

      assert(sender_node_id>=0);
      assert(receiver_node_id>=0);
      if(g_icnt_interface->HasBuffer(sender_device_id, response_size)) {
	//std::cout << getTime()+getTotalTime() << " | " << " PUSH2 | " << " input " << sender_device_id << " output " << receiver_device_id << " ctrl_msg " << ctrl_msg->get_id();
	//std::cout << std::endl;
	_GeneratePacket(sender_node_id, -1, 0, getTime(), subnet, packet_size, packet_type, ctrl_msg, receiver_node_id);
	g_hpcl_global_comp_pl_2B[i]->pop_out_dict_ctrl_msg();

  //      std::cout << "ctrl_msg | id " << ctrl_msg->get_id();
  //      std::cout << " | src_node " << ctrl_msg->get_src_node();
  //      std::cout << " | dest_node " << ctrl_msg->get_dest_node();
  //      std::cout << " | word_index " << ctrl_msg->get_word_index();
  //      std::cout << " | word " << ctrl_msg->get_new_word() << std::endl;;
  //
  //      g_hpcl_global_comp_pl_2B[i]->validate_word(ctrl_msg->get_dest_node(), ctrl_msg->get_word_index(), ctrl_msg->get_new_word());
      }
    }
    ///

  }

// GPGPUSim will generate/inject packets from interconnection interface
#if 0
  if ( !_empty_network ) {
    _Inject();
  }
#endif
  
  for(int subnet = 0; subnet < _subnets; ++subnet) {
    
    for(int n = 0; n < _nodes; ++n) {
      
      Flit * f = NULL;
      
      BufferState * const dest_buf = _buf_states[n][subnet];
      
      int const last_class = _last_class[n][subnet];
      
      int class_limit = _classes;
      
      if(_hold_switch_for_packet) {
        list<Flit *> const & pp = _input_queue[subnet][n][last_class];
        if(!pp.empty() && !pp.front()->head &&
           !dest_buf->IsFullFor(pp.front()->vc)) {
          f = pp.front();
          assert(f->vc == _last_vc[n][subnet][last_class]);
          
          // if we're holding the connection, we don't need to check that class
          // again in the for loop
          --class_limit;
        }
      }
      
      for(int i = 1; i <= class_limit; ++i) {
        
        int const c = (last_class + i) % _classes;
        
        list<Flit *> const & pp = _input_queue[subnet][n][c];
        
        if(pp.empty()) {
          continue;
        }
        
        Flit * const cf = pp.front();
        assert(cf);
        assert(cf->cl == c);
        assert(cf->subnetwork == subnet);

        if(g_hpcl_comp_config.hpcl_comp_en == 1) {
	  //added by kh (030816)
	  //If compressor is busy with compressing flits of a packet,
	  //don't inject a head flit of a new packet to the busy compressor
	  //compressor is only for read reply, but write reply goes through the compressor to avoid intermixed flits from different packets
	  //Thus, the following filtering is not restricted to read reply, thus we have no flit type checking to read reply.
	  if(g_mc_placement_config.is_mc_node(n) == true && cf->head == true) {
	    if(g_hpcl_global_comp_pl_2B[n] && g_hpcl_global_comp_pl_2B[n]->get_state() == hpcl_comp_pl<unsigned short>::HPCL_COMP_RUN) {
	      f = NULL;
	      break;
	    }
	  }
	  ///
        }

        if(f && (f->pri >= cf->pri)) {
          continue;
        }
        
        //KH: routing output port is decided here.
        if(cf->head && cf->vc == -1) { // Find first available VC
          
          //std::cout << "_Step is called!!!!" << std::endl;
          //assert(1 == 0);

          OutputSet route_set;
          _rf(NULL, cf, -1, &route_set, true);
          set<OutputSet::sSetElement> const & os = route_set.GetSet();
          assert(os.size() == 1);
          OutputSet::sSetElement const & se = *os.begin();
          assert(se.output_port == -1);
          int vc_start = se.vc_start;
          int vc_end = se.vc_end;
          int vc_count = vc_end - vc_start + 1;
          if(_noq) {
            assert(_lookahead_routing);
            const FlitChannel * inject = _net[subnet]->GetInject(n);
            const Router * router = inject->GetSink();
            assert(router);
            int in_channel = inject->GetSinkPort();
            

            // NOTE: Because the lookahead is not for injection, but for the
            // first hop, we have to temporarily set cf's VC to be non-negative
            // in order to avoid seting of an assertion in the routing function.
            cf->vc = vc_start;
            _rf(router, cf, in_channel, &cf->la_route_set, false);
            cf->vc = -1;
            
            if(cf->watch) {
              *gWatchOut << GetSimTime() << " | "
              << "node" << n << " | "
              << "Generating lookahead routing info for flit " << cf->id
              << " (NOQ)." << endl;
            }
            set<OutputSet::sSetElement> const sl = cf->la_route_set.GetSet();
            assert(sl.size() == 1);
            int next_output = sl.begin()->output_port;
            vc_count /= router->NumOutputs();
            vc_start += next_output * vc_count;
            vc_end = vc_start + vc_count - 1;
            assert(vc_start >= se.vc_start && vc_start <= se.vc_end);
            assert(vc_end >= se.vc_start && vc_end <= se.vc_end);
            assert(vc_start <= vc_end);
          }
          if(cf->watch) {
            *gWatchOut << GetSimTime() << " | " << FullName() << " | "
            << "Finding output VC for flit " << cf->id
            << ":" << endl;
          }
          for(int i = 1; i <= vc_count; ++i) {
            int const lvc = _last_vc[n][subnet][c];
            int const vc =
            (lvc < vc_start || lvc > vc_end) ?
            vc_start :
            (vc_start + (lvc - vc_start + i) % vc_count);
            assert((vc >= vc_start) && (vc <= vc_end));
            if(!dest_buf->IsAvailableFor(vc)) {
              if(cf->watch) {
                *gWatchOut << GetSimTime() << " | " << FullName() << " | "
                << "  Output VC " << vc << " is busy." << endl;
              }
            } else {
              if(dest_buf->IsFullFor(vc)) {
                if(cf->watch) {
                  *gWatchOut << GetSimTime() << " | " << FullName() << " | "
                  << "  Output VC " << vc << " is full." << endl;
                }
              } else {
                if(cf->watch) {
                  *gWatchOut << GetSimTime() << " | " << FullName() << " | "
                  << "  Selected output VC " << vc << "." << endl;
                }
                cf->vc = vc;
                break;
              }
            }
          }
        }
        
        if(cf->vc == -1) {
          if(cf->watch) {
            *gWatchOut << GetSimTime() << " | " << FullName() << " | "
            << "No output VC found for flit " << cf->id
            << "." << endl;
          }
        } else {
          if(dest_buf->IsFullFor(cf->vc)) {
            if(cf->watch) {
              *gWatchOut << GetSimTime() << " | " << FullName() << " | "
              << "Selected output VC " << cf->vc
              << " is full for flit " << cf->id
              << "." << endl;
            }
          } else {
            f = cf;
          }
        }
      }
      
      if(f) {
        
        assert(f->subnetwork == subnet);
        
        int const c = f->cl;
        
        if(f->head) {
          
          if (_lookahead_routing) {
            if(!_noq) {
              const FlitChannel * inject = _net[subnet]->GetInject(n);
              const Router * router = inject->GetSink();
              assert(router);
              int in_channel = inject->GetSinkPort();
              _rf(router, f, in_channel, &f->la_route_set, false);
              if(f->watch) {
                *gWatchOut << GetSimTime() << " | "
                << "node" << n << " | "
                << "Generating lookahead routing info for flit " << f->id
                << "." << endl;
              }
            } else if(f->watch) {
              *gWatchOut << GetSimTime() << " | "
              << "node" << n << " | "
              << "Already generated lookahead routing info for flit " << f->id
              << " (NOQ)." << endl;
            }
          } else {
            f->la_route_set.Clear();
          }
          
          dest_buf->TakeBuffer(f->vc);
          _last_vc[n][subnet][c] = f->vc;
        }
        
        _last_class[n][subnet] = c;
        
        _input_queue[subnet][n][c].pop_front();
        
#ifdef TRACK_FLOWS
        ++_outstanding_credits[c][subnet][n];
        _outstanding_classes[n][subnet][f->vc].push(c);
#endif
        

        if(g_hpcl_comp_config.hpcl_comp_en == 0) {
	  dest_buf->SendingFlit(f);
        } else {
	  //added by kh(030816)
	  //(1.1.a) send a head flit first: update buffer state
	  if(g_mc_placement_config.is_mc_node(n) == true && f->type == Flit::READ_REPLY) {
	      if(f->head)	dest_buf->SendingFlit(f);
	      //skip for other flits
	  } else {
	      dest_buf->SendingFlit(f);
	  }
	  ///
        }

        if(_pri_type == network_age_based) {
          f->pri = numeric_limits<int>::max() - _time;
          assert(f->pri >= 0);
        }
        
        if(f->watch) {
          *gWatchOut << GetSimTime() << " | "
          << "node" << n << " | "
          << "Injecting flit " << f->id
          << " into subnet " << subnet
          << " at time " << _time
          << " with priority " << f->pri
          << "." << endl;
        }
        f->itime = _time;
        
        // Pass VC "back"
        if(!_input_queue[subnet][n][c].empty() && !f->tail) {
          Flit * const nf = _input_queue[subnet][n][c].front();
          nf->vc = f->vc;
        }
        
        if((_sim_state == warming_up) || (_sim_state == running)) {
          ++_sent_flits[c][n];

          //added by kh(070215)
          ++_sent_flits_net[subnet][n];


          if(f->head) {
            ++_sent_packets[c][n];

            //added by kh(030816)
            if(f->type < Flit::ANY_TYPE) {
	      //added by kh(121715)
	      if(g_mc_placement_config.is_sm_node(n)) {
		  ((mem_fetch*)f->data)->set_status(HEAD_FLIT_INJECTED_TO_INJECT_BUF_IN_SM, _time);

		  //added by kh(122815)
		  double req_queuing_lat_in_sm = _time - ((mem_fetch*)f->data)->get_timestamp(HEAD_FLIT_INJECTED_TO_NI_INPUT_BUF_IN_SM);
		  g_hpcl_network_anal->add_sample(hpcl_network_anal::REQ_QUEUING_LAT_IN_SM, req_queuing_lat_in_sm);
		  ///

	      } else if(g_mc_placement_config.is_mc_node(n)) {
		  ((mem_fetch*)f->data)->set_status(HEAD_FLIT_INJECTED_TO_INJECT_BUF_IN_MEM, _time);
		  //added by kh(122815)
		  double rep_queuing_lat_in_mc = _time - ((mem_fetch*)f->data)->get_timestamp(HEAD_FLIT_INJECTED_TO_NI_INPUT_BUF_IN_MEM);
		  g_hpcl_network_anal->add_sample(hpcl_network_anal::REP_QUEUING_LAT_IN_MC, rep_queuing_lat_in_mc);
		  ///
	      }
	      ///
            }
          }
        }
        
#ifdef TRACK_FLOWS
        ++_injected_flits[c][n];
#endif
        
        if(g_hpcl_comp_config.hpcl_comp_en == 0) {

	  _net[subnet]->WriteFlit(f, n);

        } else {
	  //added by kh (021416)
	  //Compression
	  //(1.1.b) flits but a head flit are injected to the compressor
	  if(g_mc_placement_config.is_mc_node(n) == true && f->type == Flit::READ_REPLY) {

	     hpcl_comp_pl_data* pl_data = NULL;

	     //A head flit is found. It means other flits are in _input_queue now.
	     //flits move from _input_queue to compressor by force.
	     //Those flits are sent to network in different paths such that we set info for
	     //flit navigation here.
	     if(f->head == true) {
		assert(!_input_queue[subnet][n][c].empty());
		Flit * body_flit = _input_queue[subnet][n][c].front();
		_input_queue[subnet][n][c].pop_front();

		if(_pri_type == network_age_based) {
		  body_flit->pri = numeric_limits<int>::max() - _time;
		  assert(body_flit->pri >= 0);
		}
		body_flit->itime = _time;

		// Pass VC "back" for next flit
		if(!_input_queue[subnet][n][c].empty() && !body_flit->tail) {
		  Flit * const nf = _input_queue[subnet][n][c].front();
		  nf->vc = body_flit->vc;
		}

		++_sent_flits[c][n];
		++_sent_flits_net[subnet][n];

		pl_data = new hpcl_comp_pl_data;
		pl_data->add_comp_pl_data(body_flit);
		g_hpcl_global_comp_pl_2B[n]->set_input_data(pl_data);
		//delete pl_data;

		//(1.1.a)	send a head flit first
		_net[subnet]->WriteFlit(f, n);

	    } else {

		pl_data = new hpcl_comp_pl_data;
		pl_data->add_comp_pl_data(f);
		g_hpcl_global_comp_pl_2B[n]->set_input_data(pl_data);
		//delete pl_data;
	    }


	    //(1.2.a) words in a flit are pushed to a queue in a compressor
	    if(pl_data) {

		Flit* flit = pl_data->get_flit_ptr();
		assert(flit);

		//Use receiver's id as global dict index
		int global_dict_index = flit->const_dest;

		//Push words to be updated to word_queue (this is done at zero-time)
		vector<unsigned short> word_list;
		g_hpcl_global_comp_pl_2B[n]->decompose(flit->raw_data, word_list);
		for(int i = 0; i < word_list.size(); i++)
		  g_hpcl_global_comp_pl_2B[n]->push_word_to_queue(word_list[i], global_dict_index);

		delete pl_data;
	    }

	  } else if (g_mc_placement_config.is_mc_node(n) == true && f->type == Flit::CTRL_MSG) {


	      hpcl_dict_ctrl_msg<unsigned short>* ctrl_msg = (hpcl_dict_ctrl_msg<unsigned short>*)f->data;

	      /*
	      std::cout << "ctrl_msg | id " << ctrl_msg->get_id();
	      std::cout << " | src_node " << ctrl_msg->get_src_node();
	      std::cout << " | dest_node " << ctrl_msg->get_dest_node();
	      std::cout << " | word_index " << ctrl_msg->get_word_index();
	      std::cout << " | word " << ctrl_msg->get_new_word();
	      std::cout << " | n " << n;
	      std::cout << std::endl;;
	      */

	      g_hpcl_global_comp_pl_2B[n]->release_word(ctrl_msg->get_dest_node(), ctrl_msg->get_word_index(), ctrl_msg->get_new_word());
	      g_hpcl_global_comp_pl_2B[n]->validate_word(ctrl_msg->get_dest_node(), ctrl_msg->get_word_index(), ctrl_msg->get_new_word());

	      _net[subnet]->WriteFlit(f, n);

	  } else {

	      _net[subnet]->WriteFlit(f, n);
	  }
	  ///
        }
      }
    }
  }

  if(g_hpcl_comp_config.hpcl_comp_en == 1) {

    //added by kh(030816)
    //(1.3) Compression: Pipelined Compression
    for(int i = 0; i < g_hpcl_global_comp_pl_2B.size(); i++)
    {
      if(!g_hpcl_global_comp_pl_2B[i])	continue;

      //(1.2.b) words in the queue are updated to dictionary, when idle state
      //(1.2.d) ctrl msgs for words with frequency (>= threshold) are generated in compressor's run function, when idle state
      g_hpcl_global_comp_pl_2B[i]->run(getTime()+getTotalTime());
      hpcl_comp_pl_data* comp_pl_rsl = g_hpcl_global_comp_pl_2B[i]->get_output_data();
      Flit* flit = comp_pl_rsl->get_flit_ptr();
      if(flit) {
	//std::cout << "node " << i << " flit->id " << flit->id << std::endl;

	//(1.1.c) flits are injected from the compressor to an input buffer
	if(HasBufferSpace(i, flit)) {
	  SendFlitToBuffer(i, flit);		//for credit management.
	  SendFlitToNetwork(i, flit);
	  //std::cout << "\t" << " send flit " << flit->id << std::endl;

	  if(g_hpcl_global_comp_pl_2B[i]->get_comp_done() == true)
	  {
	      assert(g_hpcl_global_comp_pl_2B[i]->get_state() == hpcl_comp_pl<unsigned short>::HPCL_COMP_RUN);
	      g_hpcl_global_comp_pl_2B[i]->set_state(hpcl_comp_pl<unsigned short>::HPCL_COMP_IDLE);
	      g_hpcl_global_comp_pl_2B[i]->reset_comp_done();
	  }

	  //reset output data
	  g_hpcl_global_comp_pl_2B[i]->reset_output_data();

	} else {
	  //std::cout << "\t" << " cannot send flit " << flit->id << " due to no space!!!!!!!!!!" << std::endl;
	}
      }
    }
    ///

  }

  //Send the credit To the network
  for(int subnet = 0; subnet < _subnets; ++subnet) {
    for(int n = 0; n < _nodes; ++n) {
      map<int, Flit *>::const_iterator iter = flits[subnet].find(n);
      if(iter != flits[subnet].end()) {
        Flit * const f = iter->second;

        f->atime = _time;

        //added by kh(070715)
        if(f->tail) {

          //added by kh(030816)
	  if(f->type < Flit::ANY_TYPE) {
	    //added by kh(121715)
	    if(g_mc_placement_config.is_sm_node(n)) {
	      //std::cout << "mf's id: " << ((mem_fetch*)f->data)->get_request_uid() << ", time: " << _time << std::endl;
	      ((mem_fetch*)f->data)->set_status(TAIL_FLIT_EJECTED_FROM_EJECT_BUF_IN_SM, _time);
	      //added by kh(122815)
	      double rep_net_lat = _time - ((mem_fetch*)f->data)->get_timestamp(HEAD_FLIT_INJECTED_TO_INJECT_BUF_IN_MEM);
	      g_hpcl_network_anal->add_sample(hpcl_network_anal::REP_NET_LAT, rep_net_lat);
	      ///

	    } else if(g_mc_placement_config.is_mc_node(n)) {
	      ((mem_fetch*)f->data)->set_status(TAIL_FLIT_EJECTED_FROM_EJECT_BUF_IN_MEM, _time);

	      //added by kh(122815)
	      double req_net_lat = _time - ((mem_fetch*)f->data)->get_timestamp(HEAD_FLIT_INJECTED_TO_INJECT_BUF_IN_SM);
	      g_hpcl_network_anal->add_sample(hpcl_network_anal::REQ_NET_LAT, req_net_lat);
	      ///
	    }
          }
        }
        ///

        if(f->watch) {
          *gWatchOut << GetSimTime() << " | "
          << "node" << n << " | "
          << "Injecting credit for VC " << f->vc
          << " into subnet " << subnet
          << "." << endl;
        }
        

        if(g_hpcl_comp_config.hpcl_comp_en == 0) {

          Credit * const c = Credit::New();
	  c->vc.insert(f->vc);
	  _net[subnet]->WriteCredit(c, n);

        } else {
	  //added by kh(030816)
	  if(f->type == Flit::READ_REPLY) {
	      if(f->tail == false && f->m_enc_status == 1) {

	      } else {
		Credit * const c = Credit::New();
		c->vc.insert(f->vc);
		_net[subnet]->WriteCredit(c, n);
		//std::cout << "\tf->vc " << f->vc << " f->id " << f->id << std::endl;
	      }

	  } else {
	    Credit * const c = Credit::New();
	    c->vc.insert(f->vc);
	    _net[subnet]->WriteCredit(c, n);
	  }
	  ///
        }

#ifdef TRACK_FLOWS
        ++_ejected_flits[f->cl][n];
#endif
        
        _RetireFlit(f, n);
      }
    }
    flits[subnet].clear();
    // _InteralStep here
    _net[subnet]->Evaluate( );					//run router's pipeline
    _net[subnet]->WriteOutputs( );				//send flits..
  }
  
  ++_time;
  assert(_time);
  if(gTrace){
    cout<<"TIME "<<_time<<endl;
  }
  
}
コード例 #5
0
EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {

    {
        Mutex::Autolock _rf(refLock);

        refs++;
        if (refs > 1) {
            if (major != NULL)
                *major = VERSION_MAJOR;
            if (minor != NULL)
                *minor = VERSION_MINOR;
            while(!eglIsInitialized) refCond.wait(refLock);
            return EGL_TRUE;
        }

        while(eglIsInitialized) refCond.wait(refLock);
    }

    {
        Mutex::Autolock _l(lock);

        setGLHooksThreadSpecific(&gHooksNoContext);

        // initialize each EGL and
        // build our own extension string first, based on the extension we know
        // and the extension supported by our client implementation

        egl_connection_t* const cnx = &gEGLImpl;
        cnx->major = -1;
        cnx->minor = -1;
        if (cnx->dso) {
            EGLDisplay idpy = disp.dpy;
            if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
                //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
                //        idpy, cnx->major, cnx->minor, cnx);

                // display is now initialized
                disp.state = egl_display_t::INITIALIZED;

                // get the query-strings for this display for each implementation
                disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
                        EGL_VENDOR);
                disp.queryString.version = cnx->egl.eglQueryString(idpy,
                        EGL_VERSION);
                disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
                        EGL_EXTENSIONS);
                disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
                        EGL_CLIENT_APIS);

            } else {
                ALOGW("eglInitialize(%p) failed (%s)", idpy,
                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
            }
        }

        // the query strings are per-display
        mVendorString.setTo(sVendorString);
        mVersionString.setTo(sVersionString);
        mClientApiString.setTo(sClientApiString);

        mExtensionString.setTo(gBuiltinExtensionString);
        char const* start = gExtensionString;
        do {
            // length of the extension name
            size_t len = strcspn(start, " ");
            if (len) {
                // NOTE: we could avoid the copy if we had strnstr.
                const String8 ext(start, len);
                if (findExtension(disp.queryString.extensions, ext.string(),
                        len)) {
                    mExtensionString.append(ext + " ");
                }
                // advance to the next extension name, skipping the space.
                start += len;
                start += (*start == ' ') ? 1 : 0;
            }
        } while (*start != '\0');

        egl_cache_t::get()->initialize(this);

        char value[PROPERTY_VALUE_MAX];
        property_get("debug.egl.finish", value, "0");
        if (atoi(value)) {
            finishOnSwap = true;
        }

        property_get("debug.egl.traceGpuCompletion", value, "0");
        if (atoi(value)) {
            traceGpuCompletion = true;
        }

        if (major != NULL)
            *major = VERSION_MAJOR;
        if (minor != NULL)
            *minor = VERSION_MINOR;
    }

    {
        Mutex::Autolock _rf(refLock);
        eglIsInitialized = true;
        refCond.broadcast();
    }

    return EGL_TRUE;
}