ThreadingManagerOMP(int req = -1) : start_counter(1), barrier_protocol(*static_cast<ThreadingManager*>(this)) { assert(req == -1); // In the OpenMP backend, the ThreadManager is instantiated // in a serial section, so in contrast to the threaded backend // we do not know the number of threads here. // Instead we find out when we are called again in thread_main() startup_lock.lock(); lock_workers_initialized.lock(); Options::ThreadAffinity::init(); }
void func(int i) { g_lock.lock(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::cout << std::this_thread::get_id() << "add : " << i << std::endl; sum++; g_lock.unlock(); }
void init_worker(int id) { Options::ThreadAffinity::pin_workerthread(id); // allocate Worker on thread TaskExecutor<Options> *te = new TaskExecutor<Options>(id, *this); // wait until main thread has initialized the threadmanager startup_lock.lock(); startup_lock.unlock(); threads[id] = te; task_queues[id] = &te->get_task_queue(); Atomic::increase(&start_counter); lock_workers_initialized.lock(); lock_workers_initialized.unlock(); te->work_loop(); }
void stop() { if (get_thread_num() != 0) { // workers don't come here until terminate() has been called int nv = Atomic::decrease_nv(&start_counter); // wait until all workers reached this step // all threads must agree that we are shutting // down before we can continue and invoke the // destructor startup_lock.lock(); startup_lock.unlock(); return; } start_executing(); // make sure threads have been started, or we will wait forever in barrier barrier_protocol.barrier(*threads[0]); startup_lock.lock(); for (int i = 1; i < get_num_cpus(); ++i) threads[i]->terminate(); // wait for all threads to join while (start_counter != 1) Atomic::rep_nop(); // signal that threads can destruct startup_lock.unlock(); for (int i = 1; i < get_num_cpus(); ++i) delete threads[i]; delete [] threads; delete [] task_queues; }
/** * Return the number of bytes consumed by all free list blocks. * * This does not define the number of bytes available for actual usable allocation, and should not be used * by non-implementation code outside of unit tests or debugging. */ vm_size_t debug_bytes_free () { vm_size_t bytes_free = 0; _lock.lock(); control_block *first = _free_list; for (control_block *b = _free_list; b != NULL; b = b->_next) { bytes_free += b->_size; if (b->_next == first) break; } _lock.unlock(); return bytes_free; }
TEST(ParallelUtils,SpinLock) { const int N = 1000000; SpinLock lock; volatile int c =0; #pragma omp parallel for num_threads(4) for(int i=0; i<N; i++) { lock.lock(); c++; lock.unlock(); } EXPECT_EQ(N, c); }
Font Font::getDefault() { static Font font; static SpinLock lock; lock.lock(); if (font.getHandle() == nullptr) { jni::Class Button("libnative/ui/TextComponent"); jni::method_t viewConstructor = Button.getConstructor("(Landroid/content/Context;)V"); jni::Object button = Button.newInstance(viewConstructor, (jni::Object*) App::getAppHandle()); // Android already scales its default fonts. font._size = button.call<float>("getScaledTextSize"); font._shared->handle = new jni::Object(button.call<jni::Object>("getTypeface()Landroid/graphics/Typeface;")); } lock.release(); return font; }
SpinGuard(SpinLock& mutex) : _mutex(&mutex){ _mutex->lock(); }
void func(int n) { g_Lock.lock(); std::cout << "Output from thread: " << n << std::endl; g_Lock.unlock(); }