1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <unittest/unittest.h>
6 #include <sched.h>
7 #include <threads.h>
8
9 #include "dso-ctor/dso-ctor.h"
10
11 namespace {
12
13 bool global_ctor_ran;
14
15 static struct Global {
Global__anon73cf1d930111::Global16 Global() { global_ctor_ran = true; }
~Global__anon73cf1d930111::Global17 ~Global() {
18 // This is just some random nonempty thing that the compiler
19 // can definitely never decide to optimize away. We can't
20 // easily test that the destructor got run, but we can ensure
21 // that using a static destructor compiles and links correctly.
22 sched_yield();
23 }
24 } global;
25
check_ctor()26 bool check_ctor() {
27 BEGIN_TEST;
28 EXPECT_TRUE(global_ctor_ran, "global constuctor didn't run!");
29 END_TEST;
30 }
31
32 int my_static = 23;
33
check_initializer()34 bool check_initializer() {
35 BEGIN_TEST;
36 EXPECT_EQ(my_static, 23, "static initializer didn't run!");
37 END_TEST;
38 }
39
40 bool tlocal_ctor_ran, tlocal_dtor_ran;
41 thread_local ThreadLocal<&tlocal_ctor_ran, &tlocal_dtor_ran> tlocal;
42
do_thread_local_dtor_test(void *)43 int do_thread_local_dtor_test(void*) {
44 BEGIN_HELPER;
45 EXPECT_TRUE(decltype(tlocal)::check_before_reference());
46 tlocal.flag = true;
47 EXPECT_TRUE(decltype(tlocal)::check_after_reference());
48 EXPECT_TRUE(check_dso_tlocal_in_thread());
49 END_HELPER;
50 }
51
check_thread_local_ctor_dtor()52 bool check_thread_local_ctor_dtor() {
53 BEGIN_TEST;
54 thrd_t th;
55 ASSERT_EQ(thrd_create(&th, &do_thread_local_dtor_test, nullptr),
56 thrd_success);
57 int retval = -1;
58 EXPECT_EQ(thrd_join(th, &retval), thrd_success);
59 EXPECT_TRUE(static_cast<bool>(retval));
60 EXPECT_TRUE(decltype(tlocal)::check_after_join());
61 EXPECT_TRUE(check_dso_tlocal_after_join());
62 END_TEST;
63 }
64
65 } // namespace
66
67 BEGIN_TEST_CASE(ctors)
RUN_TEST(check_ctor)68 RUN_TEST(check_ctor)
69 RUN_TEST(check_initializer)
70 RUN_TEST(check_dso_ctor)
71 RUN_TEST(check_thread_local_ctor_dtor)
72 END_TEST_CASE(ctors)
73
74 int main(int argc, char** argv) {
75 return unittest_run_all_tests(argc, argv) ? 0 : -1;
76 }
77