T fake_consume(std::atomic<T> &val) { // XXX: ALPHA or some shit also compilers wtvr return val.load(mo_rlx); }
inline bool operator !() const { return !m_value.load(); }
inline void operator =(bool _value) { m_value.store(_value); }
bool is_locked() { return locked.load(std::memory_order_acquire); }
void stop() { _exit_flag.store(true); _cond_var.notify_all(); join(); }
void lock() { while(mSpinLock.exchange(true) == true) SwitchToThread(); }
/** @brief a test-and-test-and-set lock */ class tatas_lock { std::atomic<bool> locked; /* TODO can std::atomic_flag be used? */ public: tatas_lock() : locked(false) {}; tatas_lock(tatas_lock&) = delete; /* TODO? */ bool try_lock() { if(is_locked()) return false; return !locked.exchange(true, std::memory_order_acq_rel); }
/** getter for file nature */ inline NatureFlag getnature() { return m_filenature.load(std::memory_order_acquire); }
namespace folly { std::atomic<EventBaseManager*> globalManager(nullptr); EventBaseManager* EventBaseManager::get() { EventBaseManager* mgr = globalManager; if (mgr) { return mgr; } EventBaseManager* new_mgr = new EventBaseManager; bool exchanged = globalManager.compare_exchange_strong(mgr, new_mgr); if (!exchanged) { delete new_mgr; return mgr; } else { return new_mgr; } } /* * EventBaseManager methods */ void EventBaseManager::setEventBase(EventBase *eventBase, bool takeOwnership) { EventBaseInfo *info = localStore_.get(); if (info != nullptr) { throw std::runtime_error("EventBaseManager: cannot set a new EventBase " "for this thread when one already exists"); } info = new EventBaseInfo(eventBase, takeOwnership); localStore_.reset(info); this->trackEventBase(eventBase); } void EventBaseManager::clearEventBase() { EventBaseInfo *info = localStore_.get(); if (info != nullptr) { this->untrackEventBase(info->eventBase); this->localStore_.reset(nullptr); } } // XXX should this really be "const"? EventBase * EventBaseManager::getEventBase() const { // have one? auto *info = localStore_.get(); if (! info) { info = new EventBaseInfo(); localStore_.reset(info); if (observer_) { info->eventBase->setObserver(observer_); } // start tracking the event base // XXX // note: ugly cast because this does something mutable // even though this method is defined as "const". // Simply removing the const causes trouble all over fbcode; // lots of services build a const EventBaseManager and errors // abound when we make this non-const. (const_cast<EventBaseManager *>(this))->trackEventBase(info->eventBase); } return info->eventBase; } } // namespace folly
/** getter for File state */ inline State state() { return m_state.load(std::memory_order_acquire); }
/** change the file nature */ inline void nature(NatureFlag nature = NatureFlag::PHYSICAL){ m_filenature.exchange(nature, std::memory_order_acq_rel); }
T* get() const { return v.load(std::memory_order_consume); }
void SWRenderer::Init() { s_bScreenshot.store(false); }
void SWRenderer::SetScreenshot(const char *_szFilename) { std::lock_guard<std::mutex> lk(s_criticalScreenshot); s_sScreenshotName = _szFilename; s_bScreenshot.store(true); }
AtomWrapper & operator=(const AtomWrapper &other) { _a.store(other._a.load()); }
void schedule (const Task & task) { POMAGMA_ASSERT(m_accepting.load(), "pool is not accepting work"); m_queue.push(task); m_condition.notify_one(); }
T operator+=(T val) { return _a.fetch_add(val); }
namespace HPHP { namespace jit { namespace tc { void recordPerfRelocMap( TCA start, TCA end, TCA coldStart, TCA coldEnd, SrcKey sk, int argNum, const GrowableVector<IncomingBranch> &incomingBranchesIn, CGMeta& fixups) { String info = perfRelocMapInfo(start, end, coldStart, coldEnd, sk, argNum, incomingBranchesIn, fixups); Debug::DebugInfo::Get()->recordRelocMap(start, end, info); } void recordRelocationMetaData(SrcKey sk, SrcRec& srcRec, const TransLoc& loc, CGMeta& fixups) { if (!RuntimeOption::EvalPerfRelocate) return; recordPerfRelocMap(loc.mainStart(), loc.mainEnd(), loc.coldCodeStart(), loc.coldEnd(), sk, -1, srcRec.tailFallbackJumps(), fixups); } static Debug::TCRange rangeFrom(const CodeBlock& cb, const TCA addr, bool isAcold) { assertx(cb.contains(addr)); return Debug::TCRange(addr, cb.frontier(), isAcold); } void recordGdbTranslation(SrcKey sk, const Func* srcFunc, const CodeBlock& cb, const TCA start, bool exit, bool inPrologue) { if (start != cb.frontier()) { assertOwnsCodeLock(); if (!RuntimeOption::EvalJitNoGdb) { Debug::DebugInfo::Get()->recordTracelet( rangeFrom(cb, start, &cb == &code().cold()), srcFunc, srcFunc->unit() ? srcFunc->unit()->at(sk.offset()) : nullptr, exit, inPrologue ); } if (RuntimeOption::EvalPerfPidMap) { Debug::DebugInfo::Get()->recordPerfMap( rangeFrom(cb, start, &cb == &code().cold()), sk, srcFunc, exit, inPrologue ); } } } void recordBCInstr(uint32_t op, const TCA addr, const TCA end, bool cold) { if (addr != end) { Debug::DebugInfo::Get()->recordBCInstr(Debug::TCRange(addr, end, cold), op); } } //////////////////////////////////////////////////////////////////////////////// static std::atomic<bool> s_loggedJitMature{false}; /* * If the jit maturity counter is enabled, update it with the current amount of * emitted code. */ void reportJitMaturity(const CodeCache& code) { auto static jitMaturityCounter = ServiceData::createCounter("jit.maturity"); // Optimized translations are faster than profiling translations, which are // faster than the interpreter. But when optimized translations are // generated, some profiling translations will become dead. We assume the // incremental value of an optimized translation over the corresponding // profiling translations is comparable to the incremental value of a // profiling translation of similar size; thus we don't have to apply // different weights to code in different regions. auto const codeSize = code.hot().used() + code.main().used() + code.prof().used(); if (jitMaturityCounter) { // EvalJitMatureSize is supposed to to be set to approximately 20% of the // code that will give us full performance, so recover the "fully mature" // size with some math. auto const fullSize = RuntimeOption::EvalJitMatureSize * 5; auto const after = codeSize >= fullSize ? 100 : (codeSize * 100 / fullSize); auto const before = jitMaturityCounter->getValue(); if (after > before) jitMaturityCounter->setValue(after); } if (!s_loggedJitMature.load(std::memory_order_relaxed) && StructuredLog::enabled() && codeSize >= RuntimeOption::EvalJitMatureSize && !s_loggedJitMature.exchange(true, std::memory_order_relaxed)) { StructuredLogEntry cols; cols.setInt("jit_mature_sec", time(nullptr) - HttpServer::StartTime); StructuredLog::log("hhvm_warmup", cols); } } void logTranslation(const TransEnv& env) { auto nanos = HPHP::Timer::GetThreadCPUTimeNanos() - env.unit->startNanos(); StructuredLogEntry cols; auto& context = env.unit->context(); auto kind = show(context.kind); cols.setStr("trans_kind", !debug ? kind : kind + "_debug"); if (context.func) { cols.setStr("func", context.func->fullName()->data()); } cols.setInt("jit_sample_rate", RuntimeOption::EvalJitSampleRate); // timing info cols.setInt("jit_micros", nanos / 1000); // hhir stats cols.setInt("max_tmps", env.unit->numTmps()); cols.setInt("max_blocks", env.unit->numBlocks()); cols.setInt("max_insts", env.unit->numInsts()); auto hhir_blocks = rpoSortCfg(*env.unit); cols.setInt("num_blocks", hhir_blocks.size()); size_t num_insts = 0; for (auto b : hhir_blocks) num_insts += b->instrs().size(); cols.setInt("num_insts", num_insts); // vasm stats cols.setInt("max_vreg", env.vunit->next_vr); cols.setInt("max_vblocks", env.vunit->blocks.size()); cols.setInt("max_vcalls", env.vunit->vcallArgs.size()); size_t max_vinstr = 0; for (auto& blk : env.vunit->blocks) max_vinstr += blk.code.size(); cols.setInt("max_vinstr", max_vinstr); cols.setInt("num_vconst", env.vunit->constToReg.size()); auto vblocks = sortBlocks(*env.vunit); size_t num_vinstr[kNumAreas] = {0, 0, 0}; size_t num_vblocks[kNumAreas] = {0, 0, 0}; for (auto b : vblocks) { const auto& block = env.vunit->blocks[b]; num_vinstr[(int)block.area_idx] += block.code.size(); num_vblocks[(int)block.area_idx]++; } cols.setInt("num_vinstr_main", num_vinstr[(int)AreaIndex::Main]); cols.setInt("num_vinstr_cold", num_vinstr[(int)AreaIndex::Cold]); cols.setInt("num_vinstr_frozen", num_vinstr[(int)AreaIndex::Frozen]); cols.setInt("num_vblocks_main", num_vblocks[(int)AreaIndex::Main]); cols.setInt("num_vblocks_cold", num_vblocks[(int)AreaIndex::Cold]); cols.setInt("num_vblocks_frozen", num_vblocks[(int)AreaIndex::Frozen]); // finish & log StructuredLog::log("hhvm_jit", cols); } }}}
int main() { try { SDLManager sdl{SDL_INIT_TIMER}; sdl.setOpenGLVersion(3, 3); auto window = sdl.createWindow("Harken", 1024, 768); glewExperimental = true; const auto glewResult = glewInit(); if (glewResult != GLEW_OK) { throw std::runtime_error{StringBuilder{} << "Could not initialise GLEW. Error: " << glewGetErrorString(glewResult)}; } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); VertexArrayObject triangleVAO; triangleVAO.bind(); VertexBufferObject arrayBuffer{GL_ARRAY_BUFFER}; arrayBuffer.bind(); GLfloat vertices[3][2] = { { 0.0f, 0.433f}, { 0.5f, -0.433f}, {-0.5f, -0.433f} }; glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); const auto vertexShader = std::make_shared<Shader>(GL_VERTEX_SHADER, "uniform-scale.vert"); const auto fragmentShader = std::make_shared<Shader>(GL_FRAGMENT_SHADER, "red.frag"); ShaderProgram shaderProgram{vertexShader, fragmentShader}; shaderProgram.use(); glVertexAttribPointer(PositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(PositionAttrib); const auto scaleLocation = shaderProgram.uniformLocation("scale"); SDL_AddTimer(1000 / 60, update, nullptr); auto running = true; while (running) { // TODO: move this into SDLManager SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { running = false; } } glUniform1f(scaleLocation, std::sin(scale.load())); render(window, triangleVAO); } } catch (const std::exception& ex) { std::cout << ex.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
void future_function_pointers(Executor& exec) { future_void_f1_count.store(0); future_void_f2_count.store(0); future_int_f1_count.store(0); future_int_f2_count.store(0); future<void> f1 = dataflow(exec, &future_void_f1 , async(&future_void_sf1, shared_future<void>(make_ready_future())) ); f1.wait(); HPX_TEST_EQ(future_void_f1_count, 2u); future_void_f1_count.store(0); future<void> f2 = dataflow(exec, &future_void_f2 , async(&future_void_sf1, shared_future<void>(make_ready_future())) , async(&future_void_sf1, shared_future<void>(make_ready_future())) ); f2.wait(); HPX_TEST_EQ(future_void_f1_count, 2u); HPX_TEST_EQ(future_void_f2_count, 1u); future_void_f1_count.store(0); future_void_f2_count.store(0); future_int_f1_count.store(0); future_int_f2_count.store(0); future<int> f3 = dataflow(exec, &future_int_f1 , make_ready_future() ); HPX_TEST_EQ(f3.get(), 1); HPX_TEST_EQ(future_int_f1_count, 1u); future_int_f1_count.store(0); future<int> f4 = dataflow(exec, &future_int_f2 , dataflow(exec, &future_int_f1, make_ready_future()) , dataflow(exec, &future_int_f1, make_ready_future()) ); HPX_TEST_EQ(f4.get(), 2); HPX_TEST_EQ(future_int_f1_count, 2u); HPX_TEST_EQ(future_int_f2_count, 1u); future_int_f1_count.store(0); future_int_f2_count.store(0); future_int_f_vector_count.store(0); std::vector<future<int> > vf; for(std::size_t i = 0; i < 10; ++i) { vf.push_back(dataflow(exec, &future_int_f1, make_ready_future())); } future<int> f5 = dataflow(exec, &future_int_f_vector, std::ref(vf)); HPX_TEST_EQ(f5.get(), 10); }
void unlock() { locked.store(false, std::memory_order_release); }
void operator()(BlockingQueue<int> &queue) { for (int i = 0; i < size; ++i) { queue.WaitAndPush(product_item.fetch_add(1)); } }
~ThreadPoolExecutor() { if (!_exit_flag.load()) { stop(); } }
AtomWrapper(const std::atomic<T> &a) :_a(a.load()) {}
inline operator bool() const { return m_value.load(); }
void store(T val) volatile noexcept { _a.store(val); }
inline bool operator !=(bool _value) const { return m_value.load() != _value; }
T load() volatile noexcept { return _a.load(); }
//----------------------------------------------------------------------------- int main( int argc, char* argv[] ) { // Due to realtime scheduling, et al, must have root access to run. if( geteuid() != 0 ) { sprintf( spstr, "This program requires root access. Re-run with sudo.\nExiting\n" ); printf( "%s", spstr ); exit( 1 ); } init( argc, argv ); // last before main loop, arm the timer timer.arm( timer_c::PERIODIC, TIMER_PERIOD_NSECS ); //while( !quit.load( std::memory_order_seq_cst ) ) { //while( !quit ) { bool preycontroller_idle = true; while( !quit.load( std::memory_order_relaxed ) ) { int fd; notification_t note; ssize_t bytes; while( !select() ); if( FD_ISSET( FD_TIMER_TO_COORDINATOR_READ_CHANNEL, &pending_fds ) != 0 ) { fd = FD_TIMER_TO_COORDINATOR_READ_CHANNEL; if( __read( fd, ¬e, sizeof(notification_t) ) == -1 ) { if( info ) { sprintf( spstr, "ERROR : (coordinator.cpp) read_messages() failed calling __read(FD_TIMER_TO_COORDINATOR_READ_CHANNEL,...)\n" ); info->write( spstr ); } } else { if( info ) { sprintf( spstr, "read_notifications( note.source=TIMER, caught_timer_events=%d, actual_timer_events=%d\n", ++caught_timer_events, actual_timer_events ); info->write( spstr ); } if( caught_timer_events >= MAX_TIMER_EVENTS ) { //quit.store( 1, std::memory_order_relaxed ); //quit.store( 1, std::memory_order_seq_cst ); //quit = true; //quit++; if( info ) { info->flush(); } kill( coordinator_pid, SIGTERM ); } if( preycontroller_idle ) { //pthread_kill( wakeup_thread, SIGSTOP ); prey_controller->raise_priority(); //pthread_kill( wakeup_thread, SIGCONT ); preycontroller_idle = false; sprintf( spstr, "raised_priority: pid=%d, _os_priority=%d)\n", prey_controller->pid, prey_controller->_os_priority ); info->write( spstr ); } } } // - check for client specific notifications - // prey controller if( FD_ISSET( FD_PREYCONTROLLER_TO_COORDINATOR_READ_CHANNEL, &pending_fds ) != 0) { fd = FD_PREYCONTROLLER_TO_COORDINATOR_READ_CHANNEL; if( __read( fd, ¬e, sizeof(notification_t) ) == -1 ) { if( info ) { sprintf( spstr, "ERROR : (coordinator.cpp) read_messages() failed calling __read(FD_PREYCONTROLLER_TO_COORDINATOR_READ_CHANNEL,...)\n" ); info->write( spstr ); } //printf( "%s\n", spstr ); } else { if( info ) { char note_type[8]; if( note.type == notification_t::IDLE ) sprintf( note_type, "IDLE" ); else if( note.type == notification_t::OPEN ) sprintf( note_type, "OPEN" ); else if( note.type == notification_t::CLOSE ) sprintf( note_type, "CLOSE" ); else if( note.type == notification_t::READ ) sprintf( note_type, "READ" ); else if( note.type == notification_t::WRITE ) sprintf( note_type, "WRITE" ); sprintf( spstr, "read_notifications( note.source=CLIENT, note.type=%s, client=prey_controller )\n", note_type ); info->write( spstr ); } if( note.type == notification_t::CLOSE ) { prey_controller->invalidated = true; } else { prey_controller->message_queue.push( note ); } } } // check block detection first. If client blocked, needs to be put into // blocking queue. If falls through, might get put into run queue instead. if( FD_ISSET( FD_WAKEUP_TO_COORDINATOR_READ_CHANNEL, &pending_fds) != 0 ) { fd = FD_WAKEUP_TO_COORDINATOR_READ_CHANNEL; if( __read( fd, ¬e, sizeof(notification_t) ) == -1 ) { if( info ) { sprintf( spstr, "ERROR : (coordinator.cpp) read_messages() failed calling __read(FD_WAKEUP_TO_COORDINATOR_READ_CHANNEL,...)\n" ); info->write( spstr ); } } else { if( info ) { sprintf( spstr, "read_notifications( note.source=WAKEUP\n" ); info->write( spstr ); } // reenable block detection notifications wakeup_enabled.store( 1, std::memory_order_seq_cst ); } } /* if( info ) { // print the notification for debugging char note_type[8]; char note_source[8]; if( note.source == notification_t::TIMER ) sprintf( note_source, "TIMER" ); else if( note.source == notification_t::WAKEUP ) sprintf( note_source, "WAKEUP" ); else if( note.source == notification_t::CLIENT ) sprintf( note_source, "CLIENT" ); if( note.type == notification_t::IDLE ) sprintf( note_type, "IDLE" ); else if( note.type == notification_t::OPEN ) sprintf( note_type, "OPEN" ); else if( note.type == notification_t::CLOSE ) sprintf( note_type, "CLOSE" ); else if( note.type == notification_t::READ ) sprintf( note_type, "READ" ); else if( note.type == notification_t::WRITE ) sprintf( note_type, "WRITE" ); sprintf( spstr, "notification: source[%s], type[%s], ts[%llu], period[%llu]\n", note_source, note_type, note.ts, note.period ); info->write( spstr ); } */ if( note.source == notification_t::CLIENT ) { if( note.type == notification_t::IDLE ) { //pthread_kill( wakeup_thread, SIGSTOP ); prey_controller->lower_priority(); //pthread_kill( wakeup_thread, SIGCONT ); preycontroller_idle = true; sprintf( spstr, "lowered_priority: pid=%d, _os_priority=%d)\n", prey_controller->pid, prey_controller->_os_priority ); info->write( spstr ); } else if( note.type == notification_t::OPEN ) { } else if( note.type == notification_t::CLOSE ) { } else if( note.type == notification_t::READ ) { fd = FD_COORDINATOR_TO_PREYCONTROLLER_WRITE_CHANNEL; note.source = notification_t::SERVER; note.type = notification_t::READ; // the instruction to the client sprintf( spstr, "server responding with notification: source[SERVER], type[READ]\n" ); info->write( spstr ); note.ts = generate_timestamp(); if( __write( fd, ¬e, sizeof(notification_t), bytes ) != OS_ERROR_NONE ) { // TODO: Handle/Recover if( info ) { sprintf( spstr, "ERROR : (coordinator.cpp) process_notifications() failed calling __write(FD_COORDINATOR_TO_PREYCONTROLLER_WRITE_CHANNEL,...)\n" ); info->write( spstr ); } } } else if( note.type == notification_t::WRITE ) { } } else if( note.source == notification_t::TIMER ) { } else if( note.source == notification_t::WAKEUP ) { } info->flush(); } shutdown(); return 0; }
T *get_from(size_t rind) { auto ccount = count.load(std::memory_order_relaxed); act_ind = rin % ccount; }