示例#1
0
void World::GetPersistentData(std::vector<PersistentDataItem> *vec, const std::string &key, bool prefix)
{
    vec->clear();

    if (!BuildPersistentCache())
        return;

    auto eqrange = persistent_index.equal_range(key);

    if (prefix)
    {
        if (key.empty())
        {
            eqrange.first = persistent_index.begin();
            eqrange.second = persistent_index.end();
        }
        else
        {
            std::string bound = key;
            if (bound[bound.size()-1] != '/')
                bound += "/";
            eqrange.first = persistent_index.lower_bound(bound);

            bound[bound.size()-1]++;
            eqrange.second = persistent_index.lower_bound(bound);
        }
    }

    for (auto it = eqrange.first; it != eqrange.second; ++it)
    {
        auto hfig = df::historical_figure::find(-it->second);
        if (hfig && hfig->name.has_name)
            vec->push_back(dataFromHFig(hfig));
    }
}
示例#2
0
std::vector<std::multimap<ReducedFraction, MidiChord>::const_iterator>
findChordsForTimeRange(
            int voice,
            const ReducedFraction &onTime,
            const ReducedFraction &offTime,
            const std::multimap<ReducedFraction, MidiChord> &chords,
            const ReducedFraction &maxChordLength)
      {
      std::vector<std::multimap<ReducedFraction, MidiChord>::const_iterator> result;

      if (chords.empty())
            return result;

      auto it = chords.lower_bound(offTime);
      if (it == chords.begin())
            return result;
      --it;

      while (it->first + maxChordLength > onTime) {
            const MidiChord &chord = it->second;
            if (chord.voice == voice) {
                  const auto chordInterval = std::make_pair(it->first, maxNoteOffTime(chord.notes));
                  const auto durationInterval = std::make_pair(onTime, offTime);

                  if (MidiTuplet::haveIntersection(chordInterval, durationInterval))
                        result.push_back(it);
                  }
            if (it == chords.begin())
                  break;
            --it;
            }

      return result;
      }
示例#3
0
文件: Main.cpp 项目: HeIIoween/FLHook
void __stdcall GFGoodSell(const struct SGFGoodSellInfo &gsi, unsigned int iClientID)
{
	returncode = DEFAULT_RETURNCODE;

	uint iBase;
	pub::Player::GetBase(iClientID, iBase);

	multimap<uint, CARGO_MISSION>::iterator start = set_mapCargoMissions.lower_bound(iBase);
	multimap<uint, CARGO_MISSION>::iterator end = set_mapCargoMissions.upper_bound(iBase);
	for (; start != end; ++start)
	{
		if (start->second.item == gsi.iArchID)
		{
			if (start->second.curr_amount < start->second.required_amount)
			{
				int needed = start->second.required_amount - start->second.curr_amount;
				if (needed > gsi.iCount)
				{
					start->second.curr_amount += gsi.iCount;
					needed = start->second.required_amount - start->second.curr_amount;
					PrintUserCmdText(iClientID, L"%d units remaining to complete mission objective", needed);
				}
				else
				{
					PrintUserCmdText(iClientID, L"Mission objective completed",needed);
				}
			}
		}
	}
}
示例#4
0
void *MemoryPool::pop(size_t s, int loc) {
    void *addr = nullptr;

    if ((s > MIN_BLOCK_SIZE) && (s < MAX_BLOCK_SIZE)) {
        locker_.lock();

        // find MemoryPool block which is not smaller than demand size
        auto pt = pool_.lower_bound(s);

        if (pt != pool_.end()) {
            size_t ts = 0;
            std::tie(ts, addr) = *pt;
            if (ts < s * 2) {
                s = ts;
                pool_.erase(pt);
                pool_depth_ -= s;
            } else {
                addr = nullptr;
            }
        }
        locker_.unlock();
    }

    if (addr == nullptr) {
        try {
#ifdef __CUDA__
            SP_DEVICE_CALL(cudaMallocManaged(&addr, s));
#else
            addr = malloc(s);
#endif
        } catch (std::bad_alloc const &error) { THROW_EXCEPTION_BAD_ALLOC(s); }
    }
    return addr;
}
    void search(const std::string &now, const std::string &end, const std::vector<std::string> &path, const std::multimap<std::string, std::string> &word_map, std::vector<std::vector<std::string> > &ans, int min_size)
    {
		if (now == end)
		{
			ans.push_back(path);
			if (path.size() < min_size)
			{
				min_size = path.size();
			}
			return;
		}
		if (path.size() > min_size)
		{
			return;
		}
		std::multimap<std::string, std::string>::const_iterator low = word_map.lower_bound(now);
		std::multimap<std::string, std::string>::const_iterator up = word_map.upper_bound(now);
		for (std::multimap<std::string, std::string>::const_iterator it = low; it != up; ++ it)
		{
			if (std::find(path.begin(), path.end(), it->second) == path.end())
			{
				std::vector<std::string> mypath = path;
				mypath.push_back(it->second);
				search(it->second, end, mypath, word_map, ans, min_size);
			}
		}
	}
static void LoadLadspaEffect(wxSortedArrayString &uniq, wxString fname,
                             DL_Array &dls)
{
   wxLogNull logNo;
   LADSPA_Descriptor_Function mainFn = NULL;

   // Since we now have builtin VST support, ignore the VST bridge as it
   // causes duplicate menu entries to appear.
   wxFileName f(fname);
   if (f.GetName().CmpNoCase(wxT("vst-bridge")) == 0) {
      return;
   }

   // As a courtesy to some plug-ins that might be bridges to
   // open other plug-ins, we set the current working
   // directory to be the plug-in's directory.

   wxString saveOldCWD = ::wxGetCwd();
   wxString prefix = ::wxPathOnly(fname);
   ::wxSetWorkingDirectory(prefix);

   wxDynamicLibrary* pDLL = new wxDynamicLibrary();
   dls.push_back(pDLL);
   if (pDLL && pDLL->Load(fname, wxDL_LAZY)) {
      mainFn = (LADSPA_Descriptor_Function)(pDLL->GetSymbol(wxT(descriptorFnName)));
   }

   if (mainFn) {
      int index = 0;
      const LADSPA_Descriptor *data;

      data = mainFn(index);
      while(data) {

         wxString uniqid = wxString::Format(wxT("%08x-%s"), data->UniqueID, LAT1CTOWX(data->Label).c_str());
         if (uniq.Index(uniqid) == wxNOT_FOUND) {
            uniq.Add(uniqid);
            std::set<wxString> categories;

#if defined(USE_LIBLRDF) && defined(EFFECT_CATEGORIES)
            std::multimap<unsigned long, wxString>::const_iterator iter;
            iter = gPluginCategories.lower_bound(data->UniqueID);
            for ( ; (iter != gPluginCategories.end() &&
                     iter->first == data->UniqueID); ++iter)
               categories.insert(iter->second);
#endif

            LadspaEffect *effect = new LadspaEffect(data, categories);
            EffectManager::Get().RegisterEffect(effect);
         }
            
         // Get next plugin
         index++;
         data = mainFn(index);            
      }
   }

   ::wxSetWorkingDirectory(saveOldCWD);
}
示例#7
0
 int query(float min_price, float max_price, time_t min_timestamp, time_t max_timestamp) {
      std::multimap<float, Row*>::iterator it1 = price_row_mulmap.lower_bound(min_price);
      std::multimap<float, Row*>::iterator it2 = price_row_mulmap.upper_bound(max_price);
      int count = 0;
      for(; it1 != it2; it1++) {
          if(it1->second->timestamp >= min_timestamp && it1->second->timestamp <= max_timestamp) count++;
      }
      return count;
 }  
示例#8
0
std::multimap<ReducedFraction, MidiChord>::const_iterator
findFirstChordInRange(const std::multimap<ReducedFraction, MidiChord> &chords,
                      const ReducedFraction &startRangeTick,
                      const ReducedFraction &endRangeTick)
      {
      auto iter = chords.lower_bound(startRangeTick);
      if (iter != chords.end() && iter->first >= endRangeTick)
            iter = chords.end();
      return iter;
      }
示例#9
0
// starting form a list of elements, returns
// lists of lists that are all simply connected
static void recur_connect_e (const MEdge &e,
                             std::multimap<MEdge,MElement*,Less_Edge> &e2e,
                             std::set<MElement*> &group,
                             std::set<MEdge,Less_Edge> &touched){
  if (touched.find(e) != touched.end())return;
  touched.insert(e);
  for (std::multimap <MEdge,MElement*,Less_Edge>::iterator it = e2e.lower_bound(e);
         it != e2e.upper_bound(e) ; ++it){
    group.insert(it->second);
    for (int i=0;i<it->second->getNumEdges();++i){
      recur_connect_e (it->second->getEdge(i),e2e,group,touched);
    }
  }
}
示例#10
0
 void checkOptions(const DeckKeyword& keyword, std::multimap<std::string , PartiallySupported<T> >& map, const ParseContext& parseContext, ErrorGuard& errorGuard)
 {
     // check for partially supported keywords.
     typename std::multimap<std::string, PartiallySupported<T> >::iterator it, itlow, itup;
     itlow = map.lower_bound(keyword.name());
     itup  = map.upper_bound(keyword.name());
     for (it = itlow; it != itup; ++it) {
         const auto& record = keyword.getRecord(0);
         if (record.getItem(it->second.item).template get<T>(0) != it->second.item_value) {
             std::string msg = "For keyword '" + it->first + "' only value " + boost::lexical_cast<std::string>(it->second.item_value)
                 + " in item " + it->second.item + " is supported by flow.\n"
                 + "In file " + keyword.getFileName() + ", line " + std::to_string(keyword.getLineNumber()) + "\n";
             parseContext.handleError(ParseContext::SIMULATOR_KEYWORD_ITEM_NOT_SUPPORTED, msg, errorGuard);
         }
     }
 }
示例#11
0
static void recur_connect(MVertex *v,
                          std::multimap<MVertex*,MEdge> &v2e,
                          std::set<MEdge,Less_Edge> &group,
                          std::set<MVertex*> &touched)
{
  if (touched.find(v) != touched.end())return;

  touched.insert(v);
  for (std::multimap <MVertex*,MEdge>::iterator it = v2e.lower_bound(v);
       it != v2e.upper_bound(v) ; ++it){
    group.insert(it->second);
    for (int i=0;i<it->second.getNumVertices();++i){
      recur_connect (it->second.getVertex(i),v2e,group,touched);
    }
  }

}
示例#12
0
文件: Main.cpp 项目: HeIIoween/FLHook
void __stdcall GFGoodBuy(struct SGFGoodBuyInfo const &gbi, unsigned int iClientID)
{
	uint iBase;
	pub::Player::GetBase(iClientID, iBase);

	multimap<uint, CARGO_MISSION>::iterator start = set_mapCargoMissions.lower_bound(iBase);
	multimap<uint, CARGO_MISSION>::iterator end = set_mapCargoMissions.upper_bound(iBase);
	for (; start != end; ++start)
	{
		if (start->second.item == gbi.iGoodID)
		{
			start->second.curr_amount -= gbi.iCount;
			if (start->second.curr_amount < 0)
			{
				start->second.curr_amount = 0;
			}
		}
	}
}
示例#13
0
static void recurConnectByMEdge(const MEdge &e,
				std::multimap<MEdge, MTriangle*, Less_Edge> &e2e,
				std::set<MTriangle*> &group,
				std::set<MEdge, Less_Edge> &touched,
				std::set<MEdge, Less_Edge> &theCut)
{
  if (touched.find(e) != touched.end()) return;
  touched.insert(e);
  for (std::multimap <MEdge, MTriangle*, Less_Edge>::iterator it = e2e.lower_bound(e);
       it != e2e.upper_bound(e); ++it){
    group.insert(it->second);
    for (int i = 0; i < it->second->getNumEdges(); ++i){
      MEdge me = it->second->getEdge(i);
      if (theCut.find(me) != theCut.end()){
	touched.insert(me); //break;
      }
      else recurConnectByMEdge(me, e2e, group, touched, theCut);
    }
  }
}
示例#14
0
文件: Main.cpp 项目: HeIIoween/FLHook
void __stdcall ShipDestroyed(DamageList *_dmg, DWORD *ecx, uint iKill)
{
	returncode = DEFAULT_RETURNCODE;

	if (iKill)
	{
		CShip *cship = (CShip*)ecx[4];

		int iRep;
		pub::SpaceObj::GetRep(cship->get_id(), iRep);
		
		uint iAff;
		pub::Reputation::GetAffiliation(iRep, iAff);

		Vector vPos;
		vPos.x = cship->fPosX;
		vPos.y = cship->fPosY;
		vPos.z = cship->fPosZ;
		string scSector = VectorToSectorCoord(cship->iSystem, vPos);

		multimap<uint, NPC_MISSION>::iterator start = set_mapNpcMissions.lower_bound(iAff);
		multimap<uint, NPC_MISSION>::iterator end = set_mapNpcMissions.upper_bound(iAff);
		for (; start != end; ++start)
		{
			if (start->second.system == cship->iSystem)
			{
				if (start->second.sector.length() && start->second.sector != scSector)
					continue;

				if (start->second.curr_amount < start->second.required_amount)
				{
					start->second.curr_amount++;
					// PrintUserCmdText(iClientID, L"%d ships remaining to destroy to complete mission objective", needed);
				}
			}
		}
	}
}
std::vector<TupletInfo> detectTuplets(
            const std::multimap<ReducedFraction, MidiChord>::iterator &startBarChordIt,
            const std::multimap<ReducedFraction, MidiChord>::iterator &endBarChordIt,
            const ReducedFraction &startBarTick,
            const ReducedFraction &barFraction,
            std::multimap<ReducedFraction, MidiChord> &chords,
            const ReducedFraction &basicQuant,
            int barIndex)
      {
      const auto divLengths = Meter::divisionsOfBarForTuplets(barFraction);

      std::vector<TupletInfo> tuplets;
      int id = 0;
      const auto tol = basicQuant / 2;

      for (const auto &divLen: divLengths) {
            const auto tupletNumbers = findTupletNumbers(divLen, barFraction);
            const auto div = barFraction / divLen;
            const int divCount = div.numerator() / div.denominator();

            for (int i = 0; i != divCount; ++i) {
                  const auto startDivTime = startBarTick + divLen * i;
                  const auto endDivTime = startBarTick + divLen * (i + 1);
                              // check which chords can be inside tuplet period
                              // [startDivTime - tol, endDivTime]
                  const auto startDivTimeWithTol = qMax(startBarTick, startDivTime - tol);
                  auto startDivChordIt = MChord::findFirstChordInRange(startDivTimeWithTol, endDivTime,
                                                                       startBarChordIt, endBarChordIt);
                  if (startDivChordIt == endBarChordIt)
                        continue;

                  Q_ASSERT_X(!startDivChordIt->second.isInTuplet,
                             "MIDI tuplets: findTuplets", "Tuplet chord has been already used");

                              // end iterator, as usual, point to the next - invalid chord
                  auto endDivChordIt = chords.lower_bound(endDivTime);
                  if (!isNextBarOwnershipOk(startDivChordIt, endDivChordIt, chords, barIndex))
                        continue;
                              // try different tuplets, nested tuplets are not allowed
                              // here chords from next bar can be captured
                              // if their on time < next bar start
                  for (const auto &tupletNumber: tupletNumbers) {
                        if (!isTupletLenAllowed(divLen, tupletNumber, startDivChordIt, endDivChordIt,
                                                basicQuant)) {
                              continue;
                              }
                        auto tupletInfo = findTupletApproximation(divLen, tupletNumber,
                                             basicQuant, startDivTime, startDivChordIt, endDivChordIt);

                        const auto &opers = midiImportOperations.data()->trackOpers;
                        const int currentTrack = midiImportOperations.currentTrack();

                        if (opers.simplifyDurations.value(currentTrack)) {
                              if (!haveChordsInTheMiddleBetweenTupletChords(
                                                startDivChordIt, endDivChordIt, tupletInfo)) {
                                    detectStaccato(tupletInfo);
                                    }
                              }
                        tupletInfo.sumLengthOfRests = findSumLengthOfRests(tupletInfo, startBarTick);

                        if (!isTupletAllowed(tupletInfo))
                              continue;
                        tupletInfo.id = id++;
                        tuplets.push_back(tupletInfo);   // tuplet found
                        }      // next tuplet type
                  }
            }

      return tuplets;
      }
示例#16
0
bool IndexServerConn::HandleMsg(enum IndexServerMsg msg_id)
{
  switch(msg_id)
    {
    case TS_MSG_VERSION:
      return HandShake();
      break;

    case TS_MSG_WIS_VERSION:
      {
        int version;
        if (BytesReceived() < sizeof(uint32_t)) // The message is not completely received
          return true;
        if (!ReceiveInt(version)) // Receive the version number of the server index
          return false;
        if (version > VERSION)
          {
            DPRINT(INFO,"The server at %i have a version %i, while we are only running a %i version",
                   GetIP(), version, VERSION);
            exit(EXIT_FAILURE);
          }
        else if(version < VERSION)
          {
            DPRINT(INFO,"This server is running an old version (v%i) !", version);
            return false;
          }
        DPRINT(INFO,"We are running the same version..");
      }
      break;
    case TS_MSG_JOIN_LEAVE:
      {
        int ip;
        int port;
        std::string version;

        if (!ReceiveStr(version))
            return false;

        if (BytesReceived() < 2*sizeof(uint32_t)) // The message is not completely received
          return true;
        if (!ReceiveInt(ip)) // Receive the IP of the warmux server
          return false;
        if (!ReceiveInt(port)) // Receive the port of the warmux server
          return false;

        if (port < 0) // means it disconnected
          {
	    for (std::multimap<std::string, FakeClient>::iterator serv = fake_clients.lower_bound(version);
		 serv != fake_clients.upper_bound(version);
		 serv++) {

	      if( serv->second.ip == ip
		  &&  serv->second.port == -port )
		{
		  fake_clients.erase(serv);
		  DPRINT(MSG, "A fake server disconnected");
		  break;
		}
	    }
          }
        else
          {
            HostOptions options;

	    std::string game_name;
	    if (!ReceiveStr(game_name))
	      return false;

	    int passwd;
	    if (!ReceiveInt(passwd))
	      return false;
	    options.Set(game_name, passwd);

            fake_clients.insert(std::make_pair(version, FakeClient(ip, port, options)));
            stats.NewFakeServer(version);
          }
      }
      break;
    default:
      DPRINT(INFO,"Bad message!");
      return false;
    }
  msg_id = TS_NO_MSG;
  return true;
}
示例#17
0
VkBool32 VKTS_APIENTRY engineRun()
{
    if (g_engineState != VKTS_ENGINE_INIT_STATE)
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Not in initialize state.");

        return VK_FALSE;
    }

    if (engineGetNumberUpdateThreads() < VKTS_MIN_UPDATE_THREADS || engineGetNumberUpdateThreads() > VKTS_MAX_UPDATE_THREADS)
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Number of update threads not correct.");

        return VK_FALSE;
    }

    //
    // Main thread gets all displays and windows attached.
    //

    const auto& displayList = _visualGetActiveDisplays();

    for (size_t i = 0; i < displayList.size(); i++)
    {
        engineAttachDisplayToUpdateThread(displayList[i], g_allUpdateThreads[g_allUpdateThreads.size() - 1]);
    }

    const auto& windowList = _visualGetActiveWindows();

    for (size_t i = 0; i < windowList.size(); i++)
    {
        engineAttachWindowToUpdateThread(windowList[i], g_allUpdateThreads[g_allUpdateThreads.size() - 1]);
    }

    //

    g_engineState = VKTS_ENGINE_UPDATE_STATE;

    logPrint(VKTS_LOG_INFO, "Engine: Started.");

    // Task queue creation.

    TaskQueueSP sendTaskQueue;
    TaskQueueSP executedTaskQueue;

    if (g_taskExecutorCount > 0)
    {
        sendTaskQueue = TaskQueueSP(new TaskQueue);

        if (!sendTaskQueue.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create task queue.");

            return VK_FALSE;
        }

        executedTaskQueue = TaskQueueSP(new TaskQueue);

        if (!executedTaskQueue.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create task queue.");

            return VK_FALSE;
        }
    }

    // Message dispatcher creation.

    MessageDispatcherSP messageDispatcher = MessageDispatcherSP(new MessageDispatcher());

    if (!messageDispatcher.get())
    {
        logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create message dispatcher.");

        return VK_FALSE;
    }

    // Object, needed for synchronizing the executors.

    ExecutorSync executorSync;

    //
    // Task executor creation and launching,
    //

    SmartPointerVector<TaskExecutorSP> realTaskExecutors;
    SmartPointerVector<ThreadSP> realTaskThreads;

    for (uint32_t i = 0; i < g_taskExecutorCount; i++)
    {
        auto currentTaskExecutor = TaskExecutorSP(new TaskExecutor(i, executorSync, sendTaskQueue, executedTaskQueue));

        if (!currentTaskExecutor.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current task executor.");

            return VK_FALSE;
        }

        auto currentRealThread = ThreadSP(new std::thread(&TaskExecutor::run, currentTaskExecutor));

        if (!currentRealThread.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current real thread.");

            return VK_FALSE;
        }

        //

        realTaskExecutors.append(currentTaskExecutor);
        realTaskThreads.append(currentRealThread);

        logPrint(VKTS_LOG_INFO, "Engine: Task %d started.", currentTaskExecutor->getIndex());
    }

    //
    // Update Thread creation and launching.
    //

    UpdateThreadExecutorSP mainUpdateThreadExecutor;

    SmartPointerVector<UpdateThreadExecutorSP> realUpdateThreadExecutors;
    SmartPointerVector<ThreadSP> realUpdateThreads;

    int32_t index = 0;

    for (size_t updateThreadIndex = 0; updateThreadIndex < g_allUpdateThreads.size(); updateThreadIndex++)
    {
        const auto& currentUpdateThread = g_allUpdateThreads[updateThreadIndex];

        //

        const auto currentMessageDispatcher = (index == engineGetNumberUpdateThreads() - 1) ? messageDispatcher : MessageDispatcherSP();

        //

        auto currentUpdateThreadContext = UpdateThreadContextSP(new UpdateThreadContext((int32_t) updateThreadIndex, (int32_t) g_allUpdateThreads.size(), g_tickTime, sendTaskQueue, executedTaskQueue));

        if (!currentUpdateThreadContext.get())
        {
            logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create update thread context.");

            return VK_FALSE;
        }

        //

        for (auto currentDisplayWalker = g_allAttachedDisplays.lower_bound(currentUpdateThread); currentDisplayWalker != g_allAttachedDisplays.upper_bound(currentUpdateThread); currentDisplayWalker++)
        {
            currentUpdateThreadContext->attachDisplay(currentDisplayWalker->second);
        }

        //

        for (auto currentWindowWalker = g_allAttachedWindows.lower_bound(currentUpdateThread); currentWindowWalker != g_allAttachedWindows.upper_bound(currentUpdateThread); currentWindowWalker++)
        {
            currentUpdateThreadContext->attachWindow(currentWindowWalker->second);
        }

        //

        if (index == engineGetNumberUpdateThreads() - 1)
        {
            // Last thread is the main thread.
            mainUpdateThreadExecutor = UpdateThreadExecutorSP(new UpdateThreadExecutor(index, executorSync, currentUpdateThread, currentUpdateThreadContext, currentMessageDispatcher));

            if (!mainUpdateThreadExecutor.get())
            {
                logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create main update thread executor.");

                return VK_FALSE;
            }
        }
        else
        {
            // Receive queue is the threads send queue.
            auto currentUpdateThreadExecutor = UpdateThreadExecutorSP(new UpdateThreadExecutor(index, executorSync, currentUpdateThread, currentUpdateThreadContext, currentMessageDispatcher));

            if (!currentUpdateThreadExecutor.get())
            {
                logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current update thread executor.");

                return VK_FALSE;
            }

            realUpdateThreadExecutors.append(currentUpdateThreadExecutor);

            logPrint(VKTS_LOG_INFO, "Engine: Thread %d started.", currentUpdateThreadExecutor->getIndex());

            auto currentRealThread = ThreadSP(new std::thread(&UpdateThreadExecutor::run, currentUpdateThreadExecutor));

            if (!currentRealThread.get())
            {
                logPrint(VKTS_LOG_ERROR, "Engine: Run failed! Could not create current real thread.");

                return VK_FALSE;
            }
            realUpdateThreads.append(currentRealThread);
        }
        index++;
    }

    // Run last thread and loop.
    logPrint(VKTS_LOG_INFO, "Engine: Thread %d started.", mainUpdateThreadExecutor->getIndex());

    mainUpdateThreadExecutor->run();

    //
    // Stopping everything.
    //

    logPrint(VKTS_LOG_INFO, "Engine: Thread %d stopped.", mainUpdateThreadExecutor->getIndex());

    // Wait for all threads to finish in the reverse order they were created.
    for (auto reverseIndex = static_cast<int32_t>(realUpdateThreads.size()) - 1; reverseIndex >= 0; reverseIndex--)
    {
        const auto& currentRealThread = realUpdateThreads[reverseIndex];

        currentRealThread->join();

        logPrint(VKTS_LOG_INFO, "Engine: Thread %d stopped.", reverseIndex);
    }

    realUpdateThreadExecutors.clear();
    realUpdateThreads.clear();

    //

    if (sendTaskQueue.get())
    {
    	// Empty the queue.
    	// As no update thread can feed the queue anymore, it is save to call reset.

    	sendTaskQueue->reset();

    	//

    	ITaskSP stopTask;

        logPrint(VKTS_LOG_SEVERE, "Engine: Disabling task queue.");

    	for (uint32_t i = 0; i < g_taskExecutorCount; i++)
    	{
    		// Send an empty task to the queue, to exit the thread.
    		sendTaskQueue->addTask(stopTask);
    	}
    }

    // Wait for all tasks to finish in the reverse order they were created.
    for (auto reverseIndex = static_cast<int32_t>(realTaskThreads.size()) - 1; reverseIndex >= 0; reverseIndex--)
    {
        const auto& currentRealThread = realTaskThreads[reverseIndex];

        currentRealThread->join();

        logPrint(VKTS_LOG_INFO, "Engine: Task %d stopped.", reverseIndex);
    }

    realTaskExecutors.clear();
    realTaskThreads.clear();

    //

    g_engineState = VKTS_ENGINE_INIT_STATE;

    logPrint(VKTS_LOG_INFO, "Engine: Stopped.");

    return VK_TRUE;
}
示例#18
0
 void setTickf(float t)
 {
     rtick = fmodf(t, (MYFLT) tickMax);
     ev_pos = ev.lower_bound( (int) rtick );
 }
示例#19
0
template <class C, class V> inline
bool CubitLoops<C, V>::recursive_make_loop(V* start_vertex, CoEdge* coedge,
    std::set<CoEdge* >& used_coedges,
    std::multimap<V*, CoEdge*>& start_coedge_map,
    std::vector<CoEdge*>& loop)
{
  V* curr_vertex;
  if (coedge->sense == CUBIT_FORWARD)
    curr_vertex = coedge->end;
  else
    curr_vertex = coedge->start;
  loop.push_back(coedge);
  used_coedges.insert(coedge);

  while (curr_vertex != start_vertex) 
  {
    typename std::multimap<V*, CoEdge*>::iterator iter;
    typename std::multimap<V*, CoEdge*>::iterator last;

    iter = start_coedge_map.lower_bound(curr_vertex);
    last = start_coedge_map.upper_bound(curr_vertex);

    std::vector<CoEdge*> possible_coedges;
    for (/*preinitialized*/; iter != last; iter++)
    {
      if (used_coedges.find(iter->second) == used_coedges.end())
        possible_coedges.push_back(iter->second);
    }

    if (possible_coedges.size() == 0)
      return false;
    else if (possible_coedges.size() == 1)
    {
      coedge = possible_coedges[0];
      loop.push_back(coedge);
      used_coedges.insert(coedge);
      if (coedge->sense == CUBIT_FORWARD)
        curr_vertex = coedge->end;
      else
        curr_vertex = coedge->start;
    }
    else
    {
      for (size_t i=0; i<possible_coedges.size(); i++)
      {
        std::vector<CoEdge*> sub_loop;
        if (recursive_make_loop(curr_vertex, possible_coedges[i], used_coedges, start_coedge_map, sub_loop) )
        {
          loop.insert(loop.end(), sub_loop.begin(), sub_loop.end());
        }
        else
        {
          for (size_t j=0; j<sub_loop.size(); j++)
            used_coedges.erase(sub_loop[j]);
          coedge = possible_coedges[i];
        }
      }
      loop.push_back(coedge);
      used_coedges.insert(coedge);
      if (coedge->sense == CUBIT_FORWARD)
        curr_vertex = coedge->end;
      else
        curr_vertex = coedge->start;
    }
  }

  return true;
}
示例#20
0
/// visitGraph - Visit the functions in the specified graph, updating the
/// specified lattice values for all of their uses.
///
void StructureFieldVisitorBase::
visitGraph(DSGraph &DSG, std::multimap<DSNode*, LatticeValue*> &NodeLVs) {
  assert(!NodeLVs.empty() && "No lattice values to compute!");

  // To visit a graph, first step, we visit the instruction making up each
  // function in the graph, but ignore calls when processing them.  We handle
  // call nodes explicitly by looking at call nodes in the graph if needed.  We
  // handle instructions before calls to avoid interprocedural analysis if we
  // can drive lattice values to bottom early.
  //
  SFVInstVisitor IV(DSG, Callbacks, NodeLVs);

  for (DSGraph::retnodes_iterator FI = DSG.retnodes_begin(),
         E = DSG.retnodes_end(); FI != E; ++FI)
    for (Function::iterator BB = FI->first->begin(), E = FI->first->end();
         BB != E; ++BB)
      for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
        if (IV.visit(*I) && NodeLVs.empty())
          return;  // Nothing left to analyze.

  // Keep track of which actual direct callees are handled.
  std::set<Function*> CalleesHandled;

  // Once we have visited all of the instructions in the function bodies, if
  // there are lattice values that have not been driven to bottom, see if any of
  // the nodes involved are passed into function calls.  If so, we potentially
  // have to recursively traverse the call graph.
  for (DSGraph::fc_iterator CS = DSG.fc_begin(), E = DSG.fc_end();
       CS != E; ++CS) {
    // Figure out the mapping from a node in the caller (potentially several)
    // nodes in the callee.
    DSGraph::NodeMapTy CallNodeMap;

    Instruction *TheCall = CS->getCallSite().getInstruction();

    // If this is an indirect function call, assume nothing gets passed through
    // it. FIXME: THIS IS BROKEN!  Just get the ECG for the fn ptr if it's not
    // direct.
    if (CS->isIndirectCall())
      continue;

    // If this is an external function call, it cannot be involved with this
    // node, because otherwise the node would be marked incomplete!
    if (CS->getCalleeFunc()->isExternal())
      continue;

    // If we can handle this function call, remove it from the set of direct
    // calls found by the visitor.
    CalleesHandled.insert(CS->getCalleeFunc());

    std::vector<DSNodeHandle> Args;

    DSGraph *CG = &ECG.getDSGraph(*CS->getCalleeFunc());
    CG->getFunctionArgumentsForCall(CS->getCalleeFunc(), Args);

    if (!CS->getRetVal().isNull())
      DSGraph::computeNodeMapping(Args[0], CS->getRetVal(), CallNodeMap);
    for (unsigned i = 0, e = CS->getNumPtrArgs(); i != e; ++i) {
      if (i == Args.size()-1) break;
      DSGraph::computeNodeMapping(Args[i+1], CS->getPtrArg(i), CallNodeMap);
    }
    Args.clear();

    // The mapping we just computed maps from nodes in the callee to nodes in
    // the caller, so we can't query it efficiently.  Instead of going through
    // the trouble of inverting the map to do this (linear time with the size of
    // the mapping), we just do a linear search to see if any affected nodes are
    // passed into this call.
    bool CallCanModifyDataFlow = false;
    for (DSGraph::NodeMapTy::iterator MI = CallNodeMap.begin(),
           E = CallNodeMap.end(); MI != E; ++MI)
      if (NodeLVs.count(MI->second.getNode()))
        // Okay, the node is passed in, check to see if the call might do
        // something interesting to it (i.e. if analyzing the call can produce
        // anything other than "top").
        if ((CallCanModifyDataFlow = NodeCanPossiblyBeInteresting(MI->first,
                                                                  Callbacks)))
          break;

    // If this function call cannot impact the analysis (either because the
    // nodes we are tracking are not passed into the call, or the DSGraph for
    // the callee tells us that analysis of the callee can't provide interesting
    // information), ignore it.
    if (!CallCanModifyDataFlow)
      continue;

    // Okay, either compute analysis results for the callee function, or reuse
    // results previously computed.
    std::multimap<DSNode*, LatticeValue*> &CalleeFacts = getCalleeFacts(*CG);

    // Merge all of the facts for the callee into the facts for the caller.  If
    // this reduces anything in the caller to 'bottom', remove them.
    for (DSGraph::NodeMapTy::iterator MI = CallNodeMap.begin(),
           E = CallNodeMap.end(); MI != E; ++MI) {
      // If we have Lattice facts in the caller for this node in the callee,
      // merge any information from the callee into the caller.

      // If the node is not accessed in the callee at all, don't update.
      if (MI->first->getType() == Type::VoidTy)
        continue;

      // If there are no data-flow facts live in the caller for this node, don't
      // both processing it.
      std::multimap<DSNode*, LatticeValue*>::iterator NLVI =
        NodeLVs.find(MI->second.getNode());
      if (NLVI == NodeLVs.end()) continue;
          
          
      // Iterate over all of the lattice values that have corresponding fields
      // in the callee, merging in information as we go.  Be careful about the
      // fact that the callee may get passed the address of a substructure and
      // other funny games.
      //if (CalleeFacts.count(const_cast<DSNode*>(MI->first)) == 0) {

      DSNode *CalleeNode = const_cast<DSNode*>(MI->first);

      unsigned CalleeNodeOffset = MI->second.getOffset();
      while (NLVI->first == MI->second.getNode()) {
        // Figure out what offset in the callee this field would land.
        unsigned FieldOff = NLVI->second->getFieldOffset()+CalleeNodeOffset;

        // If the field is not within the callee node, ignore it.
        if (FieldOff >= CalleeNode->getSize()) {
          ++NLVI;
          continue;
        }

        // Okay, check to see if we have a lattice value for the field at offset
        // FieldOff in the callee node.
        const LatticeValue *CalleeLV = 0;

        std::multimap<DSNode*, LatticeValue*>::iterator CFI = 
          CalleeFacts.lower_bound(CalleeNode);
        for (; CFI != CalleeFacts.end() && CFI->first == CalleeNode; ++CFI)
          if (CFI->second->getFieldOffset() == FieldOff) {
            CalleeLV = CFI->second;   // Found it!
            break;
          }
        
        // If we don't, the lattice value hit bottom and we should remove the
        // lattice value in the caller.
        if (!CalleeLV) {
          delete NLVI->second;   // The lattice value hit bottom.
          NodeLVs.erase(NLVI++);
          continue;
        }

        // Finally, if we did find a corresponding entry, merge the information
        // into the caller's lattice value and keep going.
        if (NLVI->second->mergeInValue(CalleeLV)) {
          // Okay, merging these two caused the caller value to hit bottom.
          // Remove it.
          delete NLVI->second;   // The lattice value hit bottom.
          NodeLVs.erase(NLVI++);
        }

        ++NLVI;  // We successfully merged in some information!
      }

      // If we ran out of facts to prove, just exit.
      if (NodeLVs.empty()) return;
    }
  }

  // The local analysis pass inconveniently discards many local function calls
  // from the graph if they are to known functions.  Loop over direct function
  // calls not handled above and visit them as appropriate.
  while (!IV.DirectCallSites.empty()) {
    Instruction *Call = *IV.DirectCallSites.begin();
    IV.DirectCallSites.erase(IV.DirectCallSites.begin());

    // Is this one actually handled by DSA?
    if (CalleesHandled.count(cast<Function>(Call->getOperand(0))))
      continue;

    // Collect the pointers involved in this call.    
    std::vector<Value*> Pointers;
    if (isa<PointerType>(Call->getType()))
      Pointers.push_back(Call);
    for (unsigned i = 1, e = Call->getNumOperands(); i != e; ++i)
      if (isa<PointerType>(Call->getOperand(i)->getType()))
        Pointers.push_back(Call->getOperand(i));

    // If this is an intrinsic function call, figure out which one.
    unsigned IID = cast<Function>(Call->getOperand(0))->getIntrinsicID();

    for (unsigned i = 0, e = Pointers.size(); i != e; ++i) {
      // If any of our lattice values are passed into this call, which is
      // specially handled by the local analyzer, inform the lattice function.
      DSNode *N = DSG.getNodeForValue(Pointers[i]).getNode();
      for (std::multimap<DSNode*, LatticeValue*>::iterator LVI =
             NodeLVs.lower_bound(N); LVI != NodeLVs.end() && LVI->first == N;) {
        bool AtBottom = false;
        switch (IID) {
        default:
          AtBottom = LVI->second->visitRecognizedCall(*Call);
          break;
        case Intrinsic::memset:
          if (Callbacks & Visit::Stores)
            AtBottom = LVI->second->visitMemSet(*cast<CallInst>(Call));
          break;
        }

        if (AtBottom) {
          delete LVI->second;
          NodeLVs.erase(LVI++);
        } else {
          ++LVI;
        }
      }
    }
  }
}