From: Kefu Chai Date: Wed, 26 Aug 2020 09:56:59 +0000 (+0800) Subject: test/multi_stress_watch: use condition_variable for level triggering X-Git-Tag: v16.1.0~1292^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6b36eb949c36fbcc0df99c94992bbd8e28b146d7;p=ceph.git test/multi_stress_watch: use condition_variable for level triggering * use mutex+condition_variable instead of POSIX semaphore, for couple reasons: - for using POSIX semaphore, we should set the initial value: before this change, sem_init() is not called, so the initial value of the semaphore is not set. - use condition_variable::wait_for() instead of TestAlarm. simpler this way. and avoid hiding the magic numbers -- if we choose to live with them, make them more visible. - use RAII to avoid sem_init() and sem_destroy() - use a member variable for being level triggered. as notify() could be called before wait() is called. * define 10000 using a constant variable: NR_ITERATIONS * remove unused `#include ` and using declaration. * use cout for printing informative messages Signed-off-by: Kefu Chai --- diff --git a/src/test/multi_stress_watch.cc b/src/test/multi_stress_watch.cc index 0871f3380d28..1c18d917870b 100644 --- a/src/test/multi_stress_watch.cc +++ b/src/test/multi_stress_watch.cc @@ -3,10 +3,12 @@ #include "include/rados/librados.hpp" #include "test/librados/test_cxx.h" -#include #include + +#include +#include +#include #include -#include #include #include #include @@ -14,18 +16,28 @@ using namespace librados; using std::map; -using std::ostringstream; using std::string; -static sem_t sem; - class WatchNotifyTestCtx : public WatchCtx { public: - void notify(uint8_t opcode, uint64_t ver, bufferlist& bl) override - { - sem_post(&sem); - } + WatchNotifyTestCtx(std::mutex &lock) + : lock{lock} {} + void notify(uint8_t opcode, uint64_t ver, bufferlist &bl) override { + std::unique_lock locker {lock}; + notified = true; + cond.notify_one(); + } + bool wait() { + std::unique_lock locker {lock}; + return cond.wait_for(locker, std::chrono::seconds(1200), + [this] { return notified; }); + } + +private: + bool notified = false; + std::mutex& lock; + std::condition_variable cond; }; #pragma GCC diagnostic ignored "-Wpragmas" @@ -50,20 +62,20 @@ test_loop(Rados &cluster, std::string pool_name, std::string obj_name) exit(1); } - for (int i = 0; i < 10000; ++i) { - std::cerr << "Iteration " << i << std::endl; + std::mutex lock; + constexpr int NR_ITERATIONS = 10000; + for (int i = 0; i < NR_ITERATIONS; ++i) { + std::cout << "Iteration " << i << std::endl; uint64_t handle; - WatchNotifyTestCtx ctx; + WatchNotifyTestCtx ctx{lock}; ret = ioctx.watch(obj_name, 0, &handle, &ctx); ceph_assert(!ret); bufferlist bl2; ret = ioctx.notify(obj_name, 0, bl2); ceph_assert(!ret); - TestAlarm alarm; - sem_wait(&sem); + ceph_assert_always(ctx.wait()); ioctx.unwatch(obj_name, handle); } - ioctx.close(); ret = cluster.pool_delete(pool_name.c_str()); if (ret < 0) { @@ -133,8 +145,8 @@ int main(int args, char **argv) pool_name = argv[2]; obj_name = argv[3]; } - std::cerr << "Test type " << type << std::endl; - std::cerr << "pool_name, obj_name are " << pool_name << ", " << obj_name << std::endl; + std::cout << "Test type " << type << std::endl; + std::cout << "pool_name, obj_name are " << pool_name << ", " << obj_name << std::endl; if (type != "ec" && type != "rep") { std::cerr << "Error: " << argv[0] << " Invalid arg must be 'ec' or 'rep' saw " << type << std::endl; @@ -170,6 +182,5 @@ int main(int args, char **argv) else if (type == "ec") test_erasure(cluster, pool_name, obj_name); - sem_destroy(&sem); return 0; }