// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <assert.h>
#include <magenta/syscalls.h>
#include <unittest/unittest.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdio.h>
#include <unistd.h>

static pthread_key_t tsd_key;
static pthread_key_t tsd_key_dtor;
static atomic_int dtor_count = ATOMIC_VAR_INIT(0);

void dtor(void* unused) {
    atomic_fetch_add(&dtor_count, 1);
}

static void test_tls(int thread_no) {
    int value1 = thread_no;
    int value2 = thread_no + 10;
    EXPECT_EQ(pthread_setspecific(tsd_key, &value1), 0,
              "Error while setting tls value");
    EXPECT_EQ(pthread_setspecific(tsd_key_dtor, &value2), 0,
              "Error while setting tls value");
    mx_nanosleep(mx_deadline_after(MX_MSEC(100)));
    int* v = pthread_getspecific(tsd_key);
    EXPECT_EQ(*v, value1, "wrong TLS value for key");
    v = pthread_getspecific(tsd_key_dtor);
    EXPECT_EQ(*v, value2, "wrong TLS value for key_dtor");
    unittest_printf("tls_test completed for thread: %d\n", thread_no);
}

static void* do_work(void* arg) {
    unittest_printf("do_work for thread: %d\n", *(int*)arg);
    test_tls(*(int*)arg);
    return NULL;
}

bool tls_test(void) {
    BEGIN_TEST;
    ASSERT_EQ(pthread_key_create(&tsd_key, NULL), 0, "Error during key creation");
    ASSERT_EQ(pthread_key_create(&tsd_key_dtor, dtor), 0, "Error during key creation");

    int expected_dtor_count = 0;

    // Run this 20 times for sanity check
    for (int i = 1; i <= 20; i++) {
        int main_thread = 1, thread_1 = i * 2, thread_2 = i * 2 + 1;

        pthread_t thread2, thread3;

        unittest_printf("creating thread: %d\n", thread_1);
        pthread_create(&thread2, NULL, do_work, &thread_1);

        unittest_printf("creating thread: %d\n", thread_2);
        pthread_create(&thread3, NULL, do_work, &thread_2);

        test_tls(main_thread);

        unittest_printf("joining thread: %d\n", thread_1);
        pthread_join(thread2, NULL);

        unittest_printf("joining thread: %d\n", thread_2);
        pthread_join(thread3, NULL);

        expected_dtor_count += 2;
        ASSERT_EQ(atomic_load(&dtor_count), expected_dtor_count, "dtors not run");
    }
    END_TEST;
}

BEGIN_TEST_CASE(tls_tests)
RUN_TEST(tls_test)
END_TEST_CASE(tls_tests)

#ifndef BUILD_COMBINED_TESTS
int main(int argc, char** argv) {
    return unittest_run_all_tests(argc, argv) ? 0 : -1;
}
#endif
