xref: /netbsd-src/tests/lib/libpthread/h_thread_local_dtor.cpp (revision e5678be828932e6f3c8f31897ff2b79723f3129b)
1 /*
2  * Copyright (c) 2016 Tavian Barnes. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
14  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23  * POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include <sys/cdefs.h>
27 __RCSID("$NetBSD: h_thread_local_dtor.cpp,v 1.1 2017/07/11 15:21:36 joerg Exp $");
28 
29 #include <cstdlib>
30 #include <thread>
31 
32 static int seq;
33 
34 class OrderChecker {
35 public:
OrderChecker(int n)36   explicit OrderChecker(int n) : n_{n} { }
37 
~OrderChecker()38   ~OrderChecker() {
39     if (seq != n_) {
40       printf("Unexpected sequence point: %d\n", 3);
41       _Exit(1);
42     }
43     ++seq;
44   }
45 
46 private:
47   int n_;
48 };
49 
50 template <int ID>
51 class CreatesThreadLocalInDestructor {
52 public:
~CreatesThreadLocalInDestructor()53   ~CreatesThreadLocalInDestructor() {
54     thread_local OrderChecker checker{ID};
55   }
56 };
57 
58 OrderChecker global{7};
59 
thread_fn()60 void thread_fn() {
61   static OrderChecker fn_static{5};
62   thread_local CreatesThreadLocalInDestructor<2> creates_tl2;
63   thread_local OrderChecker fn_thread_local{1};
64   thread_local CreatesThreadLocalInDestructor<0> creates_tl0;
65 }
66 
main()67 int main() {
68   static OrderChecker fn_static{6};
69 
70   std::thread{thread_fn}.join();
71   if (seq != 3) {
72     printf("Unexpected sequence point: %d\n", 3);
73     _Exit(1);
74   }
75 
76   thread_local OrderChecker fn_thread_local{4};
77   thread_local CreatesThreadLocalInDestructor<3> creates_tl;
78 
79   return 0;
80 }
81