diff options
author | Jesse Morgan <jesse@jesterpm.net> | 2016-12-17 21:28:53 -0800 |
---|---|---|
committer | Jesse Morgan <jesse@jesterpm.net> | 2016-12-17 21:28:53 -0800 |
commit | 54df2afaa61c6a03cbb4a33c9b90fa572b6d07b8 (patch) | |
tree | 18147b92b969d25ffbe61935fb63035cac820dd0 /db-4.8.30/test_stl/base/test_mt.h |
Berkeley DB 4.8 with rust build script for linux.
Diffstat (limited to 'db-4.8.30/test_stl/base/test_mt.h')
-rw-r--r-- | db-4.8.30/test_stl/base/test_mt.h | 914 |
1 files changed, 914 insertions, 0 deletions
diff --git a/db-4.8.30/test_stl/base/test_mt.h b/db-4.8.30/test_stl/base/test_mt.h new file mode 100644 index 0000000..ae4794b --- /dev/null +++ b/db-4.8.30/test_stl/base/test_mt.h @@ -0,0 +1,914 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#include "test.h" + +// tests containers in multiple threads, this thread class +// runs the thread function in specified manner---manipulating +// a specified type of container, with some thread inserting, +// updating, and deleting, some others reading specified amount +// of key/data pairs. +// +class WorkerThread +{ +public: + bool txnal/* if true, will create txn */, verbose; + wt_job job; + ContainerType cntnr_type; + int total_insert; + int strlenmin, strlenmax; + rand_str_dbt rand_str_maker; + Db *pdb; + DbEnv *penv; + + WorkerThread() + { + pdb = NULL; + penv = NULL; + + } + + WorkerThread(const WorkerThread& wt) + { + memcpy(this, &wt, sizeof(wt)); + } + + void run() + { + WorkerThread *p = this; + db_threadid_t tid; + int cnt = 0, i, total = total_insert, ndx; + DbstlDbt dbt, dbt2; + string str, str2; + bool iscds = false; + u_int32_t oflags; + size_t dlcnt = 0; + + + dbt.set_flags(DB_DBT_USERMEM); + dbt.set_data(DbstlMalloc(strlenmax + 10)); + dbt.set_ulen(strlenmax + 10); + dbt2.set_flags(DB_DBT_USERMEM); + dbt2.set_data(DbstlMalloc(strlenmax + 10)); + dbt2.set_ulen(strlenmax + 10); + + penv->get_open_flags(&oflags); + if (oflags & DB_INIT_CDB) + iscds = true; + __os_id(NULL, 0, &tid); + dbstl::register_db(p->pdb); + dbstl::register_db_env(penv); + if (p->cntnr_type == ct_vector) { + typedef db_vector<DbstlDbt> container_t; + container_t vi(p->pdb, penv); + const container_t& vi0 = vi; + srand((unsigned int)tid); + switch (p->job) { + case wt_read: { + + while (cnt < total - 1) { + cnt = 0; + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (container_t::const_iterator itr = vi0.begin(); itr != vi0.end() && cnt < total - 1; + itr++, cnt++) { + str = (char*)((*itr).get_data()); + if (verbose) + cout<<"\n [ "<<cnt<<" ] tid: "<<tid<<"\t [ "<< itr.get_current_index()<<" ] = "<<str.c_str(); + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 1, 0); // sleep 1 sec + } + if (iscds) // The update and delete thread will block until insert thread exits in cds mode + g_StopInsert = 1; + cout<<"\nthread "<<tid<<" got enough key/data pairs now, exiting, dead lock count = "<<dlcnt; + break; + } // case wt_job: + + case wt_insert: {// writer + + for (i = 0; g_StopInsert == 0; i++) { + rand_str_maker(dbt, str, strlenmin, strlenmax); + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + vi.push_back(dbt); + if (p->txnal) + dbstl::commit_txn(penv); + if (verbose) + cout<<endl<<"[ "<<i<<" ] thread "<<tid<<" put a string "<<str.c_str(); + } catch (DbException e) { + i--; + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + } + cout<<"\n[ "<<tid<<" ] writer OK, exiting... dead lock count = "<<dlcnt; + + break; + + } // case wt_insert + + case wt_delete: { + i = 0; // ADDITIVE, do total * 0.3 times of successful deletes, not necessarily delete so many recs because some ops may be aborted + while ( i < total * 0.1) { + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + while (i < total * 0.1) { + container_t::iterator itr = vi.begin(); + itr += (ndx = rand() % total); + if (itr != vi.end()) { + + vi.erase(itr); + i++; + if (verbose) + cout<<endl<<"vector element deleted: "<<itr.get_current_index()<<" : "<<(char*)(itr->get_data()); + } else { + if (vi.size() == 0) + return; + __os_yield(NULL, 0, 500000); + } + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + } + cout<<"\n[ "<<tid<<" ] deleter OK, exiting... dead lock count = "<<dlcnt; + break; + + }// case wt_delete + + case wt_update: { + rand_str_maker(dbt, str, strlenmin, strlenmax); + i = 0;// ADDITIVE + + while ( i < total * 0.5) { + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + while (i < total * 0.5) { + container_t::iterator itr = vi.begin(); + itr += (ndx = rand() % total); + if (itr != vi.end()) { + if (verbose) + cout<<endl<<"vector element updated: "<<itr.get_current_index()<<" updated: "<<(char*)(itr->get_data())<<" ===> "; + *itr = dbt; + i++; + if (verbose) + cout<<(char*)dbt.get_data(); + } else { + if (vi.size() == 0) + return; + __os_yield(NULL, 0, 500000); + } + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + } + cout<<"\n[ "<<tid<<" ] updater OK, exiting... dead lock count = "<<dlcnt; + break; + }; // case wt_update + + } // switch (p->job) + } // fi + if (p->cntnr_type == ct_map) { + typedef db_map<ptint , DbstlDbt> container_t; + container_t vi(p->pdb, penv); + const container_t& vi0 = vi; + container_t::iterator itr; + pair<container_t::iterator, bool> insret; + switch (p->job) { + case wt_read: + { + while (cnt < total - 1) { + cnt = 0; + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (container_t::const_iterator itrc = vi0.begin(); itrc != vi0.end(); + itrc++, cnt++) { + //str = (char*)((*itrc).first.get_data()); + str2 = (char*)((*itrc).second.get_data()); + if (verbose) + cout<<"\n [ "<<cnt<<" ] tid: "<<tid<<'\t'<<itrc->first<<"--> "<<str2.c_str(); + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 1, 0); // sleep 1 sec + } + if (iscds) // The update and delete thread will block until insert thread exits in cds mode + g_StopInsert = 1; + cout<<"\nthread "<<tid<<" got enough key/data pairs now, exiting... dead lock count = "<<dlcnt; + break; + } + case wt_insert: + {// writer + +tag6: for (i = 0; g_StopInsert == 0; i++) { + //rand_str_maker(dbt, str); + rand_str_maker(dbt2, str2, strlenmin, strlenmax); + if (i % 100 == 0) + __os_yield(NULL, 0, 0); // yield cpu + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + insret = vi.insert(make_pair(i, dbt2)); + //if (insret.second == false) // fail to insert + // i--; + if (p->txnal) + dbstl::commit_txn(penv); + if (verbose) + cout<<endl<<"[ "<<i<<" ] thread "<<tid<<" put a string "<<str.c_str()<<" --> "<<str2.c_str(); + } catch (DbException e) { + i--; + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + goto tag6; // continue; + } + + } + cout<<"\n [ "<<tid<<" ] writer thread finishes writing, exiting... dead lock count = "<<dlcnt; + break; + } //case wt_insert: + + case wt_delete: + { + i = 0;// ADDITIVE + while (i < total * 0.1) { + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (; i < total * 0.1;) { + itr = vi.begin(); + itr.move_to((ndx = rand() % total)); + if (itr != vi.end()) { + vi.erase(itr); + i++; + if (verbose) + cout<<endl<<"map k/d deleted: "<<itr->first<<" : "<<(char*)(itr->second.get_data()); + } else { + if (vi.size() == 0) + return; + __os_yield(NULL, 0, 500000); + } + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 0, 500000); + } + cout<<"\n[ "<<tid<<" ] deleter OK, exiting... dead lock count = "<<dlcnt; + break; + + }// case wt_delete + + case wt_update: + { + rand_str_maker(dbt, str, strlenmin, strlenmax); + i = 0; + while ( i < total * 0.5) { + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (i = 0; i < total * 0.5;) {// REAL DELETE: really update total * 0.5 number of recs from db + itr = vi.begin(); + itr.move_to(ndx = rand() % total); + if (itr != vi.end()) { + if (verbose) + cout<<endl<<"map key = "<<itr->first<<" updated: "<<(char*)(itr->second.get_data())<<" ===> "; + itr->second = dbt; + i++; + if (verbose) + cout<<(char*)dbt.get_data(); + } else { + if (vi.size() == 0) + return; + __os_yield(NULL, 0, 500000); + } + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 0, 500000); + } + cout<<"\n[ "<<tid<<" ] updater OK, exiting... dead lock count = "<<dlcnt; + break; + }; // case wt_update + } //switch (p->job) + + } + + if (p->cntnr_type == ct_multimap) { + typedef db_multimap<ptint , DbstlDbt> container_t; + container_t vi(p->pdb, penv); + const container_t& vi0 = vi; + + switch (p->job) { + case wt_read: + { + + while (cnt < total - 1) { + cnt = 0; + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (container_t::const_iterator itrc = vi0.begin(); itrc != vi0.end(); + itrc++, cnt++) { + //str = (char*)((*itrc).first.get_data()); + str2 = (char*)((*itrc).second.get_data()); + if (verbose) + cout<<"\n [ "<<cnt<<" ] tid: "<<tid<<'\t'<<itrc->first<<"--> "<<str2.c_str(); + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 1, 0); // sleep 1 sec + } + if (iscds) // The update and delete thread will block until insert thread exits in cds mode + g_StopInsert = 1; + cout<<"\nthread "<<tid<<" got enough key/data pairs now, exiting... dead lock count = "<<dlcnt; + break; + } //case wt_read: + + case wt_insert: + {// writer + srand ((unsigned int)tid); + int j, dupcnt; + for (i = 0; g_StopInsert == 0; i += dupcnt) { + //rand_str_maker(dbt, str); + for (j = 0, dupcnt = (rand() % 5); j < dupcnt; j++) { + + rand_str_maker(dbt2, str2, strlenmin, strlenmax); + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + vi.insert(make_pair(i, dbt2)); + if (p->txnal) + dbstl::commit_txn(penv); + if (verbose) + cout<<endl<<"[ "<<i<<" ] thread "<<tid<<" put a string "<<str.c_str()<<" --> "<<str2.c_str(); + } catch (DbException e) { + i--; + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + } + } // there may be more than total number of recs inserted because of the dupcnt + cout<<"\n[ "<<tid<<" ] writer thread finishes writing, exiting... dead lock count = "<<dlcnt; + break; + } //case wt_insert: + + case wt_delete: + { + i = 0;// ADDITIVE + while ( i < total * 0.1) { + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (container_t::iterator itr = vi.begin(); i < total * 0.1;) { + + itr.move_to(ndx = rand() % total); + if (itr != vi.end()) { + + vi.erase(itr); + i++; + if (verbose) + cout<<endl<<"multimap k/d deleted: "<<itr->first<<" : "<<(char*)(itr->second.get_data()); + + } else { + if (vi.size() == 0) + return; + __os_yield(NULL, 0, 500000); + } + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 0, 500000); + } + cout<<"\n[ "<<tid<<" ] deleter OK, exiting... dead lock count = "<<dlcnt; + break; + + }// case wt_delete + + case wt_update: + { + rand_str_maker(dbt, str, strlenmin, strlenmax); + i = 0;// ADDITIVE + while (i < total * 0.5) { + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (container_t::iterator itr = vi.begin(); i < total * 0.5;) { + + itr.move_to(ndx = rand() % total); + if (itr != vi.end()) { + if (verbose) + cout<<endl<<"multimap key = "<<itr->first<<" updated: "<<(char*)(itr->second.get_data())<<" ===> "; + itr->second = dbt; + i++; + if (verbose) + cout<<(char*)dbt.get_data(); + + } else { + if (vi.size() == 0) + return; + __os_yield(NULL, 0, 500000); + } + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 0, 500000); + + } + cout<<"\n[ "<<tid<<" ] updater OK, exiting... dead lock count = "<<dlcnt; + break; + + } // case wt_update + } // switch (p->job) + } + + if (p->cntnr_type == ct_set) { + typedef db_set<DbstlDbt> container_t; + container_t vi(p->pdb, penv); + const container_t &vi0 = vi; + container_t::iterator itr; + int rowcnt; + int j; + switch (p->job) { + case wt_read: + { + + while (cnt < total - 1) { + cnt = 0; + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (container_t::const_iterator itrc = vi0.begin(); itrc != vi0.end(); + itrc++, cnt++) { + str = (char*)((*itrc).get_data()); + if (verbose) + cout<<"\n [ "<<cnt<<" ] tid: "<<tid<<'\t'<<str.c_str(); + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 1, 0); // sleep 1 sec + } + if (iscds) // The update and delete thread will block until insert thread exits in cds mode + g_StopInsert = 1; + cout<<"\nthread "<<tid<<" got enough key/data pairs now, exiting... dead lock count = "<<dlcnt; + break; + } + case wt_insert: + {// writer + srand ((unsigned int)tid); + + pair<container_t::iterator, bool> insret; + for (i = 0; g_StopInsert == 0; i += 1) { + + rand_str_maker(dbt, str, strlenmin, strlenmax); + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + insret = vi.insert(dbt); + if (p->txnal) + dbstl::commit_txn(penv); + if (insret.second == false) // fail to insert + i--; + if (verbose) + cout<<endl<<"[ "<<i<<" ] thread "<<tid<<" put a string "<<str.c_str(); + } catch (DbException e) { + i--; + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + + } // there may be more than total number of recs inserted because of the dupcnt + cout<<"\n[ "<<tid<<" ] writer thread finishes writing, exiting... dead lock count = "<<dlcnt; + break; + } // case wt_insert: + + case wt_delete: + { + i = 0; + j = 0; + while (i < total * 0.1) { + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for ( ; i < total * 0.1;) {// ADDITIVE + rowcnt = rand() % total; + for (itr = vi.begin(), j = 0; j < rowcnt; j++, itr++) + ; // move to a random pos + if (itr != vi.end()) { + + vi.erase(itr); + i++; + if (verbose) + cout<<endl<<"set key deleted: "<<(char*)(itr->get_data()); + + } else { + if (vi.size() == 0) + return; + __os_yield(NULL, 0, 500000); + } + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 0, 500000); + } + cout<<"\n[ "<<tid<<" ] deleter OK, exiting... dead lock count = "<<dlcnt; + break; + + }// case wt_delete + + case wt_update: + { + rand_str_maker(dbt, str, strlenmin, strlenmax); + i = 0; + while ( i < total * 0.5) { + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (i = 0; i < total * 0.5;) { // REAL UPDATE + rowcnt = rand() % total; + + for (itr = vi.begin(), j = 0; j < rowcnt; j++, itr++) + ; // move to a random pos + if (itr != vi.end()) { + if (verbose) + cout<<endl<<"set key updated: "<<(char*)(itr->get_data())<<" ===> "; + *itr = dbt; + i++; + if (verbose) + cout<<(char*)dbt.get_data(); + + } else { + if (vi.size() == 0) + return; + __os_yield(NULL, 0, 500000); + } + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 0, 500000); + } + cout<<"\n[ "<<tid<<" ] updater OK, exiting... dead lock count = "<<dlcnt; + break; + }// case wt_update + } // switch (p->job) + } // fi + + if (p->cntnr_type == ct_multiset) { + typedef db_multiset<DbstlDbt> container_t; + container_t::iterator itr; + int rowcnt; + int j, dupcnt; + container_t vi(p->pdb, penv); + const container_t &vi0 = vi; + switch (p->job) { + case wt_read: + { + + while (cnt < total - 1) { + cnt = 0; + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (container_t::const_iterator itrc = vi0.begin(); itrc != vi0.end(); + itrc++, cnt++) { + str = (char*)((*itrc).get_data()); + if (verbose) + cout<<"\n [ "<<cnt<<" ] tid: "<<tid<<'\t'<<str.c_str(); + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 1, 0); // sleep 1 sec + } + if (iscds) // The update and delete thread will block until insert thread exits in cds mode + g_StopInsert = 1; + cout<<"\nthread "<<tid<<" got enough key/data pairs now, exiting... dead lock count = "<<dlcnt; + break; + } // case wt_read: + case wt_insert: + {// writer + srand ((unsigned int)tid); + + for (i = 0; g_StopInsert == 0; i += dupcnt) { + + for (j = 0, dupcnt = (rand() % 5); j < dupcnt; j++) { + rand_str_maker(dbt, str, strlenmin, strlenmax); + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + vi.insert(dbt); + if (p->txnal) + dbstl::commit_txn(penv); + if (verbose) + cout<<endl<<"[ "<<i<<" ] thread "<<tid<<" put a string "<<str.c_str(); + } catch (DbException e) { + i--; + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + } + } // there may be more than total number of recs inserted because of the dupcnt + cout<<"\n[ "<<tid<<" ] writer thread finishes writing, exiting... dead lock count = "<<dlcnt; + break; + } // case wt_insert: + case wt_delete: + { + i = 0; + j = 0; + while (i < total * 0.1) { + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (; i < total * 0.1;) {// ADDITIVE + rowcnt = rand() % total; + for (itr = vi.begin(), j = 0; j < rowcnt; j++, itr++) + ; // move to a random pos + if (itr != vi.end()) { + + vi.erase(itr); + i++; + if (verbose) + cout<<endl<<"multiset key deleted: "<<(char*)(itr->get_data()); + + } else { + if (vi.size() == 0) + return; + __os_yield(NULL, 0, 500000); + } + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 0, 500000); + } + cout<<"\n[ "<<tid<<" ] deleter OK, exiting... dead lock count = "<<dlcnt; + break; + + }// case wt_delete + + case wt_update: + { + rand_str_maker(dbt, str, strlenmin, strlenmax); + i = 0; + while ( i < total * 0.5) { + + try { + if (p->txnal) + dbstl::begin_txn(0, penv); + for (i = 0; i < total * 0.5;) {// REAL UPDATE + rowcnt = rand() % total; + for (itr = vi.begin(), j = 0; j < rowcnt; j++, itr++) + ; // move to a random pos + if (itr != vi.end()) { + if (verbose) + cout<<endl<<"multiset key updated: "<<(char*)(itr->get_data())<<" ===> "; + *itr = dbt; + i++; + if (verbose) + cout<<(char*)dbt.get_data(); + + } else { + if (vi.size() == 0) + return; + __os_yield(NULL, 0, 500000); + } + } + if (p->txnal) + dbstl::commit_txn(penv); + } catch (DbException e) { + dlcnt++; + dbstl::abort_txn(penv); + if (e.get_errno() != DB_LOCK_DEADLOCK) + throw e; + else + continue; + } + + __os_yield(NULL, 0, 500000); + } + cout<<"\n[ "<<tid<<" ] updater OK, exiting... dead lock count = "<<dlcnt; + break; + } // case wt_update + } //switch (p->job) + }// fi + + }// void operator()() +}; // WorkerThread + +// Used in the multi-threaded test to manage test threads, +// works like boost::thread_group +class ThreadMgr +{ +public: + os_thread_t create_thread(WorkerThread *thrd); + void clear() { threads.clear();} + void join_all(); + ThreadMgr() : threads(0){} +private: + vector<os_thread_t> threads; +}; // ThreadMgr + +#ifdef WIN32 +#define ThrdFuncRet DWORD +#define FunctRet return (0) +#else +#define ThrdFuncRet void* +#define FunctRet return (NULL) +#endif + +static ThrdFuncRet thread_func(void *arg) +{ + (*((WorkerThread *)arg)).run(); + FunctRet; +} + +os_thread_t ThreadMgr::create_thread(WorkerThread *thrd) +{ + os_thread_t thrdhandle; + + os_thread_create(&thrdhandle, NULL, thread_func, thrd); + threads.push_back(thrdhandle); + return thrdhandle; +} + +void ThreadMgr::join_all() +{ + ThrdFuncRet ret; + + for (size_t i = 0; i < threads.size(); i++) + os_thread_join(threads[i], &ret); +} |