From dbd34bebfd0daeef74e6a78a2d570548609b7db1 Mon Sep 17 00:00:00 2001 From: Nils Much Date: Thu, 21 Jan 2021 15:27:29 +0100 Subject: [PATCH] Fix ThreadLocalStorage assigment operators Copy/move exemplar Add tests --- include/deal.II/base/thread_local_storage.h | 8 +- .../multithreading/thread_local_storage_07.cc | 79 +++++++++++++++++++ .../thread_local_storage_07.output | 8 ++ .../multithreading/thread_local_storage_08.cc | 79 +++++++++++++++++++ .../thread_local_storage_08.output | 8 ++ 5 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 tests/multithreading/thread_local_storage_07.cc create mode 100644 tests/multithreading/thread_local_storage_07.output create mode 100644 tests/multithreading/thread_local_storage_08.cc create mode 100644 tests/multithreading/thread_local_storage_08.output diff --git a/include/deal.II/base/thread_local_storage.h b/include/deal.II/base/thread_local_storage.h index 1bd0716b60..89ca9f5701 100644 --- a/include/deal.II/base/thread_local_storage.h +++ b/include/deal.II/base/thread_local_storage.h @@ -334,7 +334,10 @@ namespace Threads std::shared_lock reader_lock(t.insertion_mutex); std::unique_lock writer_lock(insertion_mutex); - data = t.data; + data = t.data; + exemplar = t.exemplar; + + return *this; } @@ -352,7 +355,8 @@ namespace Threads std::unique_lock reader_lock(t.insertion_mutex); std::unique_lock writer_lock(insertion_mutex); - data = std::move(t.data); + data = std::move(t.data); + exemplar = std::move(t.exemplar); return *this; } diff --git a/tests/multithreading/thread_local_storage_07.cc b/tests/multithreading/thread_local_storage_07.cc new file mode 100644 index 0000000000..6375ebdc4e --- /dev/null +++ b/tests/multithreading/thread_local_storage_07.cc @@ -0,0 +1,79 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2008 - 2018 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// test if ThreadLocalStorage::operator= (const ThreadLocalStorage &t) copies +// the shared ptr to the exemplar + +#include +#include + +#include "../tests.h" + + +struct X +{ + X() + { + deallog << "Creating" << std::endl; + }; + X(const X &) + { + deallog << "Copying" << std::endl; + }; + int i; +}; + +Threads::ThreadLocalStorage tls_data; + +void +execute(int i) +{ + tls_data.get().i = i; +} + + +void +test() +{ + // create a thread local storage object + X exemplar; + Threads::ThreadLocalStorage temp(exemplar); + + // copy assign thread local storage object + tls_data = temp; + + // create 5 threads and wait for their + // return. the OS will create 5 individual + // thread ids, which means that we will + // create 5 individual thread specific + // storage locations + Threads::ThreadGroup<> tg; + for (unsigned int i = 10; i < 15; ++i) + tg += Threads::new_thread(execute, i); + + // now make sure the threads all finish + tg.join_all(); +} + + + +int +main() +{ + initlog(); + + test(); +} diff --git a/tests/multithreading/thread_local_storage_07.output b/tests/multithreading/thread_local_storage_07.output new file mode 100644 index 0000000000..f66f4ca40a --- /dev/null +++ b/tests/multithreading/thread_local_storage_07.output @@ -0,0 +1,8 @@ + +DEAL::Creating +DEAL::Copying +DEAL::Copying +DEAL::Copying +DEAL::Copying +DEAL::Copying +DEAL::Copying diff --git a/tests/multithreading/thread_local_storage_08.cc b/tests/multithreading/thread_local_storage_08.cc new file mode 100644 index 0000000000..6d11dbdf18 --- /dev/null +++ b/tests/multithreading/thread_local_storage_08.cc @@ -0,0 +1,79 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2008 - 2018 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// test if ThreadLocalStorage::operator= (ThreadLocalStorage &&t) moves the +// shared ptr to the exemplar + +#include +#include + +#include "../tests.h" + + +struct X +{ + X() + { + deallog << "Creating" << std::endl; + }; + X(const X &) + { + deallog << "Copying" << std::endl; + }; + int i; +}; + +Threads::ThreadLocalStorage tls_data; + +void +execute(int i) +{ + tls_data.get().i = i; +} + + +void +test() +{ + // create a thread local storage object + X exemplar; + Threads::ThreadLocalStorage temp(exemplar); + + // move assign thread local storage object + tls_data = std::move(temp); + + // create 5 threads and wait for their + // return. the OS will create 5 individual + // thread ids, which means that we will + // create 5 individual thread specific + // storage locations + Threads::ThreadGroup<> tg; + for (unsigned int i = 10; i < 15; ++i) + tg += Threads::new_thread(execute, i); + + // now make sure the threads all finish + tg.join_all(); +} + + + +int +main() +{ + initlog(); + + test(); +} diff --git a/tests/multithreading/thread_local_storage_08.output b/tests/multithreading/thread_local_storage_08.output new file mode 100644 index 0000000000..f66f4ca40a --- /dev/null +++ b/tests/multithreading/thread_local_storage_08.output @@ -0,0 +1,8 @@ + +DEAL::Creating +DEAL::Copying +DEAL::Copying +DEAL::Copying +DEAL::Copying +DEAL::Copying +DEAL::Copying -- 2.39.5