void RWLock::unlock_read() { // repeatedly try to remove a reader (ignoring write lock) unsigned int old_rw = m_rw; unsigned int new_rw = mkrw(readers(old_rw) - 1, writing(old_rw)); while (!m_rw.compare_exchange_weak(old_rw, new_rw)) { new_rw = mkrw(readers(old_rw) - 1, writing(old_rw)); } }
void RWLock::lock_read() { // repeatedly try to add one more reader, without a write lock unsigned int old_rw = mkrw(readers(m_rw), 0); unsigned int new_rw = mkrw(readers(old_rw) + 1, 0); while (!m_rw.compare_exchange_weak(old_rw, new_rw)) { old_rw = mkrw(readers(old_rw), 0); new_rw = mkrw(readers(old_rw) + 1, 0); } }
ParticlesInfo* readHeaders(const char* c_filename) { std::string filename(c_filename); std::string extension; bool endsWithGz; if(!extensionIgnoringGz(filename,extension,endsWithGz)) return 0; std::map<std::string,READER_FUNCTION>::iterator i=readers().find(extension); if(i==readers().end()){ std::cerr<<"Partio: No reader defined for extension "<<extension<<std::endl; return 0; } return (*i->second)(c_filename,true); }
void RWLock::lock_upgrade() { // repeatedly try to set writing from false to true and remove a reader unsigned int old_rw = mkrw(readers(m_rw), 0); unsigned int new_rw = mkrw(readers(old_rw) - 1, 1); while (!m_rw.compare_exchange_weak(old_rw, new_rw)) { old_rw = mkrw(readers(old_rw), 0); new_rw = mkrw(readers(old_rw) - 1, 1); } // wait for readers to leave while (readers(m_rw) > 0); }
/** Get a constrained list of interfaces. * @param type_pattern tyoe pattern, may contain shell-like wildcards * (any number * of characters) and ? (one character), cf. man fnmatch(). * @param id_pattern ID pattern, may contain shell-like wildcards * (any number * of characters) and ? (one character), cf. man fnmatch(). * @return list of currently existing interfaces matching the given type and * ID patterns. List may be outdated on return since there maybe concurrent * actions. */ InterfaceInfoList * BlackBoardInterfaceManager::list(const char *type_pattern, const char *id_pattern) const { InterfaceInfoList *infl = new InterfaceInfoList(); memmgr->lock(); interface_header_t *ih; BlackBoardMemoryManager::ChunkIterator cit; for ( cit = memmgr->begin(); cit != memmgr->end(); ++cit ) { ih = (interface_header_t *)*cit; Interface::interface_data_ts_t *data_ts = (Interface::interface_data_ts_t *)((char *)*cit + sizeof(interface_header_t)); char type[__INTERFACE_TYPE_SIZE + 1]; char id[__INTERFACE_ID_SIZE + 1]; // ensure NULL-termination type[__INTERFACE_TYPE_SIZE] = 0; id[__INTERFACE_ID_SIZE] = 0; strncpy(type, ih->type, __INTERFACE_TYPE_SIZE); strncpy(id, ih->id, __INTERFACE_ID_SIZE); if ((fnmatch(type_pattern, type, FNM_NOESCAPE) == 0) && (fnmatch(id_pattern, id, FNM_NOESCAPE) == 0)) { std::string uid = std::string(type) + "::" + id; infl->append(ih->type, ih->id, ih->hash, ih->serial, ih->flag_writer_active, ih->num_readers, readers(uid), writer(uid), fawkes::Time(data_ts->timestamp_sec, data_ts->timestamp_usec)); } } memmgr->unlock(); return infl; }
QStringList QPCSC::drivers() const { #ifdef Q_OS_WIN HDEVINFO h = SetupDiGetClassDevs( 0, 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); if( !h ) return QStringList(); SP_DEVINFO_DATA info = { sizeof(SP_DEVINFO_DATA) }; QStringList list; for( DWORD i = 0; SetupDiEnumDeviceInfo( h, i, &info ); i++ ) { DWORD size = 0; WCHAR data[1024]; SetupDiGetDeviceRegistryPropertyW( h, &info, SPDRP_CLASS, 0, LPBYTE(data), sizeof(data), &size ); if( _wcsicmp( data, L"SmartCardReader" ) != 0 ) continue; DWORD conf = 0; SetupDiGetDeviceRegistryPropertyW( h, &info, SPDRP_CONFIGFLAGS, 0, LPBYTE(&conf), sizeof(conf), &size ); if( conf & CONFIGFLAG_DISABLED ) continue; SetupDiGetDeviceRegistryPropertyW( h, &info, SPDRP_DEVICEDESC, 0, LPBYTE(data), sizeof(data), &size ); QString name( (QChar*)data ); SetupDiGetDeviceRegistryPropertyW( h, &info, SPDRP_HARDWAREID, 0, LPBYTE(data), sizeof(data), &size ); list << QString( "%1 (%2)").arg( name, QString( (QChar*)data ) ); } SetupDiDestroyDeviceInfoList( h ); return list; #else return readers(); #endif }
int main(int argc, char *argv[]) { po::options_description desc("Multithread IO benchmark.\n Allowed options"); desc.add_options()("help", "produce help message") ("mc", po::value<size_t>(&meas2write)->default_value(meas2write), "measurment count") ("ic", po::value<size_t>(&iteration_count)->default_value(iteration_count), "iteration count") ("dyncache", po::value<bool>(&enable_dyn_cache)->default_value(enable_dyn_cache), "enable dynamic cache") ("cache-size", po::value<size_t>(&cache_size)->default_value(cache_size), "cache size") ("cache-pool-size", po::value<size_t>(&cache_pool_size)->default_value(cache_pool_size), "cache pool size") ("thread-count", po::value<size_t>(&thread_count)->default_value(thread_count), "write thread count") ("page-size", po::value<size_t>(&pagesize)->default_value(pagesize), "page size") ("verbose", "verbose ouput") ("dont-remove", "dont remove created storage"); po::variables_map vm; try { po::store(po::parse_command_line(argc, argv, desc), vm); } catch (std::exception &ex) { logger("Error: " << ex.what()); exit(1); } po::notify(vm); if (vm.count("help")) { std::cout << desc << std::endl; return 1; } if (vm.count("verbose")) { verbose = true; } if (vm.count("dont-remove")) { dont_remove = true; } makeStorage(); std::thread info_thread(show_info); logger("threads count: "<<thread_count); /// writers std::vector<std::thread> writers(thread_count); size_t pos = 0; for (size_t i = 0; i < thread_count; i++) { std::thread t{ writer, iteration_count }; writers[pos++] = std::move(t); } pos = 0; for (size_t i = 0; i < thread_count; i++) { std::thread t = std::move(writers[pos++]); t.join(); } stop_info = true; info_thread.join(); /// readers stop_info = false; std::thread read_info_thread(show_reads_info); std::vector<std::thread> readers(thread_count); pos = 0; auto reads_per_thread = (iteration_count / ((float)thread_count)); for (size_t i = 0; i < thread_count; i++) { std::thread t{ reader,i, reads_per_thread*i, reads_per_thread*(i+1) }; readers[pos++] = std::move(t); } pos = 0; for (size_t i = 0; i < thread_count; i++) { std::thread t = std::move(readers[pos++]); t.join(); } stop_info = true; read_info_thread.join(); ds=nullptr; if (!dont_remove) { nkvdb::utils::rm(storage_path); } }
int main( int, char** ) { #ifdef LUNCHBOX_USE_OPENMP const size_t nThreads = lunchbox::OMP::getNThreads() * 3; #else const size_t nThreads = 16; #endif std::cout << " read, write, push, copy, erase, " << " flush/ms, rd, other #threads" << std::endl; _runSerialTest< std::vector< size_t >, size_t >(); _runSerialTest< Vector_t, size_t >(); std::vector< Reader > readers(nThreads); std::vector< Writer > writers(nThreads); std::vector< Pusher > pushers(nThreads); stage_ = 1; size_t stage = 0; for( size_t l = 0; l < nThreads; ++l ) { readers[l].start(); writers[l].start(); pushers[l].start(); } lunchbox::sleep( 10 ); for( size_t i = 1; i <= nThreads; i = i<<1 ) for( size_t j = 1; j <= nThreads; j = j<<1 ) { // concurrent read, write, push Vector_t vector; for( size_t k = 0; k < nThreads; ++k ) { readers[k].vector = k < i ? &vector : 0; writers[k].vector = k < j ? &vector : 0; pushers[k].vector = k < j ? &vector : 0; } const size_t nextStage = ++stage * STAGESIZE; _clock.reset(); stage_ = nextStage; stage_.waitEQ( nextStage + (3 * nThreads) ); TEST( vector.size() >= LOOPSIZE ); // multi-threaded copy std::vector< Copier > copiers(j); _clock.reset(); for( size_t k = 0; k < j; ++k ) { copiers[k].vector = &vector; copiers[k].start(); } for( size_t k = 0; k < j; ++k ) copiers[k].join(); for( size_t k = 0; k < vector.size(); ++k ) TEST( vector[k] == k || vector[k] == 0 ); // multi-threaded erase std::vector< Eraser > erasers(j); _clock.reset(); for( size_t k = 0; k < j; ++k ) { erasers[k].vector = &vector; erasers[k].start(); } for( size_t k = 0; k < j; ++k ) erasers[k].join(); for( size_t k = 0; k < vector.size(); ++k ) { if( vector[k] == 0 ) break; if( k > vector.size() / 2 ) { TEST( vector[k] > vector[k-1] ); } else { TEST( vector[k] == k ); } } // multi-threaded pop_back const size_t fOps = vector.size(); std::vector< Flusher > flushers(j); _clock.reset(); for( size_t k = 0; k < j; ++k ) { flushers[k].vector = &vector; flushers[k].start(); } for( size_t k = 0; k < j; ++k ) flushers[k].join(); const float fTime = _clock.getTimef(); TEST( vector.empty( )); std::cerr << std::setw(11) << float(i*LOOPSIZE)/rTime_ << ", " << std::setw(11) << float(j*LOOPSIZE)/wTime_ << ", " << std::setw(11) << float(LOOPSIZE)/pTime_ << ", " << std::setw(9) << float(j)/cTime_ << ", " << std::setw(9) << float(j)/eTime_ << ", " << std::setw(9) << float(fOps)/fTime << ", " << std::setw(3) << i << ", " << std::setw(3) << j << std::endl; } stage_ = std::numeric_limits< size_t >::max(); for( size_t k = 0; k < nThreads; ++k ) { readers[k].join(); writers[k].join(); pushers[k].join(); } return EXIT_SUCCESS; }