void Annotate::unify(SList dst, SCList src) { const QString m("Merge"); for (int i = 0; i < dst.size(); ++i) { if (dst.at(i) == m) dst[i] = src.at(i); } }
std::size_t Processer::StealHalf(Processer & other) { std::size_t runnable_task_count = runnable_list_.size(); SList<Task> tasks = runnable_list_.pop_back((runnable_task_count + 1) / 2); std::size_t c = tasks.size(); DebugPrint(dbg_scheduler, "proc[%u] steal proc[%u] work returns %d.", other.id_, id_, (int)c); if (!c) return 0; other.runnable_list_.push(std::move(tasks)); return c; }
int main() { SList<int> *intList = new SList<int>; delete intList; SList<string> facultyList; facultyList.insert("unknown"); facultyList.insert("erdly"); facultyList.insert("sung"); facultyList.insert("olson"); facultyList.insert("zander"); facultyList.insert("berger"); facultyList.insert("cioch"); facultyList.insert("fukuda"); facultyList.insert("stiber"); facultyList.insert("jackels"); cout << "#faculty members: " << facultyList.size() << endl; facultyList.show(); cout << endl; cout << "deleting unknown" << endl; facultyList.remove("unknown"); cout << "#faculty members: " << facultyList.size() << endl; facultyList.show(); cout << endl; cout << "finding stiber = " << facultyList.find("stiber") << endl; cout << endl; cout << "create another list" << endl; SList<string> studentList = facultyList; cout << "finding stiber = " << facultyList.find("stiber") << endl; cout << "#faculty members: " << facultyList.size() << endl; cout << endl; cout << "cost of find = " << facultyList.getCost() << endl; }
void UpwardPlanRep::removeSinkArcs(SList<adjEntry> &crossedEdges) { if (crossedEdges.size() == 2) return; SListIterator<adjEntry> itPred = crossedEdges.begin(), it; for(it = itPred.succ(); it.valid() && it.succ().valid(); ++it) { adjEntry adj = *it; if (m_isSinkArc[adj->theEdge()]) { m_Gamma.joinFaces(adj->theEdge()); crossedEdges.delSucc(itPred); it = itPred; continue; } itPred = it; } m_Gamma.setExternalFace(m_Gamma.rightFace(extFaceHandle)); }
double MaxCPlanarMaster::heuristicInitialUpperBound() { double upperBoundO = m_G->numberOfEdges(); double upperBoundC = 0.0; // Checking graph for planarity // If \a m_G is planar \a upperBound is simply set to the number of edges of \a m_G. GraphCopy gc(*m_G); BoyerMyrvold bm; if (bm.isPlanarDestructive(gc)) upperBoundO = m_G->numberOfEdges(); else { // Extract all possible Kuratowski subdivisions. // Compare extracted subdivisions and try to obtain the // maximum number of independent subdivisions, i.e. a maximum // independent set in the overlap graph. // Due to the complexity of this task, we only check if // a subdivision (sd) does overlap with a subdivision for which // we already decreased the upper bound. In this case, // upperBound stays the same. upperBoundO = m_G->numberOfEdges(); GraphCopy *gCopy = new GraphCopy(*m_G); SList<KuratowskiWrapper> subDivs; bm.planarEmbedDestructive(*gCopy,subDivs,-1); //we store a representative and its status for each edge //note that there might be an overlap, in that case //we keep a representative with status false if existing //to check if we can safely reduce the upper bound (ub) EdgeArray<edge> subRep(*gCopy, nullptr); //store representing edge for sd EdgeArray<bool> coverStatus(*gCopy, false); //false means not covered by ub decrease yet //runtime for the check: we run over all edges in all subdivisions if (subDivs.size() > 0) { // At least one edge has to be deleted to obtain planarity. // We run over all subdivisions and check for overlaps for(const KuratowskiWrapper &kw : subDivs) { bool covered = false; //may the sd already be covered by a decrease in ub //for each edge we set the representative to be the first edge of sd edge sdRep = kw.edgeList.front(); //sd is always non-empty //we check if any of the edges in sd were already visited and if //the representative has status false, in this case, we are not //allowed to decrease the ub for (edge e : kw.edgeList) { //we already encountered this edge if (subRep[e] != nullptr) { //and decreased ub for an enclosing sd //(could we just break in the if case?) if (coverStatus[subRep[e]]) covered = true; else subRep[e] = sdRep; //might need an update } else subRep[e] = sdRep; } if (!covered) { coverStatus[sdRep] = true; upperBoundO--; }//not yet covered, independent } } delete gCopy; } /* * Heuristic can be improved by checking, how many additional C-edges have to be added at least. * A first simple approach is the following: * Since the Graph has to be completely connected in the end, all chunks have to be connected. * Thus the numbers of chunks minus 1 summed up over all clusters is a trivial lower bound. * We perform a bottom-up search through the cluster-tree, each time checking the cluster * induced Graph for connectivity. If the Graph is not connected, the number of chunks -1 is added to * a counter. For "inner" clusters we have to collapse all child clusters to one node, * in order to obtain a correct result. */ GraphCopy gcc(*m_G); cluster c = m_C->rootCluster(); clusterConnection(c, gcc, upperBoundC); // Return-value results from the max. number of O-edges that might be contained // in an optimal solution minus \a epsilon times the number of C-edges that have // to be added at least in any optimal solution. (\a upperBoundC is non-positive) return (upperBoundO + upperBoundC); }
uint32_t Scheduler::Run() { ThreadLocalInfo& info = GetLocalInfo(); info.current_task = NULL; uint32_t do_max_count = runnale_task_count_; uint32_t do_count = 0; Debug("Run --------------------------"); // 每次Run执行的协程数量不能多于当前runnable协程数量 // 以防wait状态的协程得不到执行。 while (do_count < do_max_count) { uint32_t cnt = std::max((uint32_t)1, std::min( do_max_count / GetOptions().chunk_count, GetOptions().max_chunk_size)); Debug("want pop %u tasks.", cnt); SList<Task> slist = run_task_.pop(cnt); Debug("really pop %u tasks.", cnt); if (slist.empty()) break; SList<Task>::iterator it = slist.begin(); while (it != slist.end()) { Task* tk = &*it; info.current_task = tk; Debug("enter task(%llu)", tk->id_); swapcontext(&info.scheduler, &tk->ctx_); ++do_count; Debug("exit task(%llu) state=%d", tk->id_, tk->state_); info.current_task = NULL; switch (tk->state_) { case TaskState::runnable: ++it; break; case TaskState::io_block: case TaskState::sync_block: --runnale_task_count_; it = slist.erase(it); wait_task_.push(tk); break; case TaskState::done: default: --task_count_; --runnale_task_count_; it = slist.erase(it); delete tk; break; } } Debug("push %d task return to runnable list", slist.size()); run_task_.push(slist); } static thread_local epoll_event evs[1024]; int n = epoll_wait(epoll_fd, evs, 1024, 1); Debug("do_count=%u, do epoll event, n = %d", do_count, n); for (int i = 0; i < n; ++i) { Task* tk = (Task*)evs[i].data.ptr; if (tk->unlink()) AddTask(tk); } return do_count; }
uint32_t Processer::Run(ThreadLocalInfo &info, uint32_t &done_count) { info.current_task = NULL; done_count = 0; uint32_t c = 0; SList<Task> slist = runnable_list_.pop_all(); uint32_t do_count = slist.size(); DebugPrint(dbg_scheduler, "Run [Proc(%d) do_count:%u] --------------------------", id_, do_count); SList<Task>::iterator it = slist.begin(); for (; it != slist.end(); ++c) { Task* tk = &*it; info.current_task = tk; tk->state_ = TaskState::runnable; DebugPrint(dbg_switch, "enter task(%s)", tk->DebugInfo()); RestoreStack(tk); int ret = swapcontext(&info.scheduler, &tk->ctx_); if (ret) { fprintf(stderr, "swapcontext error:%s\n", strerror(errno)); runnable_list_.push(tk); ThrowError(eCoErrorCode::ec_swapcontext_failed); } DebugPrint(dbg_switch, "leave task(%s) state=%d", tk->DebugInfo(), tk->state_); info.current_task = NULL; switch (tk->state_) { case TaskState::runnable: ++it; break; case TaskState::io_block: it = slist.erase(it); g_Scheduler.io_wait_.SchedulerSwitch(tk); break; case TaskState::sleep: it = slist.erase(it); g_Scheduler.sleep_wait_.SchedulerSwitch(tk); break; case TaskState::sys_block: case TaskState::user_block: { if (tk->block_) { it = slist.erase(it); if (!tk->block_->AddWaitTask(tk)) runnable_list_.push(tk); tk->block_ = NULL; } else { std::unique_lock<LFLock> lock(g_Scheduler.user_wait_lock_); auto &zone = g_Scheduler.user_wait_tasks_[tk->user_wait_type_]; auto &wait_pair = zone[tk->user_wait_id_]; auto &task_queue = wait_pair.second; if (wait_pair.first) { --wait_pair.first; tk->state_ = TaskState::runnable; ++it; } else { it = slist.erase(it); task_queue.push(tk); } g_Scheduler.ClearWaitPairWithoutLock(tk->user_wait_type_, tk->user_wait_id_, zone, wait_pair); } } break; case TaskState::done: default: --task_count_; ++done_count; it = slist.erase(it); DebugPrint(dbg_task, "task(%s) done.", tk->DebugInfo()); if (tk->eptr_) { std::exception_ptr ep = tk->eptr_; runnable_list_.push(slist); tk->DecrementRef(); std::rethrow_exception(ep); } else tk->DecrementRef(); break; } } if (do_count) runnable_list_.push(slist); return c; }