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