/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include <stdint.h>
#include <string.h>

__thread int local_var = 100;
int shared_var = 200;

static void reset_vars() {
  local_var = 1000;
  shared_var = 2000;
  // local_var should be reset by threads
}

typedef void* (*MyThread)(void*);

static void* inc_shared_var(void* p) {
  int *data = reinterpret_cast<int*>(p);
  shared_var++;
  *data = shared_var;
  return nullptr;
}

static void* inc_local_var(void* p) {
  int *data = reinterpret_cast<int*>(p);
  local_var++;
  *data = local_var;
  return nullptr;
}

static int run_one_thread(MyThread foo) {
  pthread_t t;
  int data;
  int error = pthread_create(&t, nullptr, foo, &data);
  if (!error)
      error = pthread_join(t, nullptr);
  return error ? error : data;
}

TEST(thread_local_storage, shared) {
  reset_vars();
  ASSERT_EQ(local_var, 1000);
  ASSERT_EQ(shared_var, 2000);

  // Update shared_var, local_var remains 1000.
  ASSERT_EQ(run_one_thread(inc_shared_var), 2001);
  ASSERT_EQ(local_var, 1000);
  ASSERT_EQ(shared_var, 2001);

  ASSERT_EQ(run_one_thread(inc_shared_var), 2002);
  ASSERT_EQ(local_var, 1000);
  ASSERT_EQ(shared_var, 2002);

  ASSERT_EQ(run_one_thread(inc_shared_var), 2003);
  ASSERT_EQ(local_var, 1000);
  ASSERT_EQ(shared_var, 2003);
}

TEST(thread_local_storage, local) {
  reset_vars();
  ASSERT_EQ(local_var, 1000);
  ASSERT_EQ(shared_var, 2000);

  // When a child thread updates its own TLS variable,
  // this thread's local_var and shared_var are not changed.
  // TLS local_var is initialized to 100 in a thread.
  ASSERT_EQ(run_one_thread(inc_local_var), 101);
  ASSERT_EQ(local_var, 1000);
  ASSERT_EQ(shared_var, 2000);

  ASSERT_EQ(run_one_thread(inc_local_var), 101);
  ASSERT_EQ(local_var, 1000);
  ASSERT_EQ(shared_var, 2000);

  ASSERT_EQ(run_one_thread(inc_local_var), 101);
  ASSERT_EQ(local_var, 1000);
  ASSERT_EQ(shared_var, 2000);
}

// Test TLS initialization of more complicated type, array of struct.
struct Point {
  int x, y;
};

typedef Point Triangle[3];

__thread Triangle local_triangle = {{10,10}, {20,20}, {30,30}};
Triangle shared_triangle = {{1,1}, {2,2}, {3,3}};

static void reset_triangle() {
  static const Triangle t1 = {{3,3}, {4,4}, {5,5}};
  static const Triangle t2 = {{2,2}, {3,3}, {4,4}};
  memcpy(local_triangle, t1, sizeof(local_triangle));
  memcpy(shared_triangle, t2, sizeof(shared_triangle));
}

static void* move_shared_triangle(void* p) {
  int *data = reinterpret_cast<int*>(p);
  shared_triangle[1].y++;
  *data = shared_triangle[1].y;
  return nullptr;
}

static void* move_local_triangle(void* p) {
  int *data = reinterpret_cast<int*>(p);
  local_triangle[1].y++;
  *data = local_triangle[1].y;
  return nullptr;
}

TEST(thread_local_storage, shared_triangle) {
  reset_triangle();
  ASSERT_EQ(local_triangle[1].y, 4);
  ASSERT_EQ(shared_triangle[1].y, 3);

  // Update shared_triangle, local_triangle remains 1000.
  ASSERT_EQ(run_one_thread(move_shared_triangle), 4);
  ASSERT_EQ(local_triangle[1].y, 4);
  ASSERT_EQ(shared_triangle[1].y, 4);

  ASSERT_EQ(run_one_thread(move_shared_triangle), 5);
  ASSERT_EQ(local_triangle[1].y, 4);
  ASSERT_EQ(shared_triangle[1].y, 5);

  ASSERT_EQ(run_one_thread(move_shared_triangle), 6);
  ASSERT_EQ(local_triangle[1].y, 4);
  ASSERT_EQ(shared_triangle[1].y, 6);
}

TEST(thread_local_storage, local_triangle) {
  reset_triangle();
  ASSERT_EQ(local_triangle[1].y, 4);
  ASSERT_EQ(shared_triangle[1].y, 3);

  // Update local_triangle, parent thread's
  // shared_triangle and local_triangle are unchanged.
  ASSERT_EQ(run_one_thread(move_local_triangle), 21);
  ASSERT_EQ(local_triangle[1].y, 4);
  ASSERT_EQ(shared_triangle[1].y, 3);

  ASSERT_EQ(run_one_thread(move_local_triangle), 21);
  ASSERT_EQ(local_triangle[1].y, 4);
  ASSERT_EQ(shared_triangle[1].y, 3);

  ASSERT_EQ(run_one_thread(move_local_triangle), 21);
  ASSERT_EQ(local_triangle[1].y, 4);
  ASSERT_EQ(shared_triangle[1].y, 3);
}

// Test emutls runtime data structures and __emutls_get_address function.
typedef unsigned int gcc_word __attribute__((mode(word)));
typedef unsigned int gcc_pointer __attribute__((mode(pointer)));
struct gcc_emutls_object {  // for libgcc
  gcc_word size;
  gcc_word align;
  union {
    gcc_pointer offset;
    void* ptr;
  } loc;
  void* templ;
};

typedef struct __emutls_control {  // for clang/llvm
  size_t size;
  size_t align;
  union {
    uintptr_t index;
    void* address;
  } object;
  void* value;
} __emutls_control;

TEST(thread_local_storage, type_size) {
  static_assert(sizeof(size_t) == sizeof(gcc_word),
                "size_t != gcc_word");
  static_assert(sizeof(uintptr_t) == sizeof(gcc_pointer),
                "uintptr_t != gcc_pointer");
  static_assert(sizeof(uintptr_t) == sizeof(void*),
                "sizoeof(uintptr_t) != sizeof(void*)");
  static_assert(sizeof(__emutls_control) == sizeof(struct gcc_emutls_object),
                "sizeof(__emutls_control) != sizeof(struct gcc_emutls_object)");
}

extern "C" void* __emutls_get_address(__emutls_control*);

TEST(thread_local_storage, init_value) {
  char tls_value1[] = "123456789";
  char tls_value2[] = "abcdefghi";
  constexpr size_t num_saved_values = 10;
  __emutls_control tls_var[num_saved_values];
  size_t prev_index = 0;
  void* saved_gap[num_saved_values];
  void* saved_p[num_saved_values];
  ASSERT_TRUE(strlen(tls_value2) <= strlen(tls_value1));
  __emutls_control c =
      {strlen(tls_value1) + 1, 1, {0}, tls_value1};
  for (size_t n = 0; n < num_saved_values; n++) {
    memcpy(&tls_var[n], &c, sizeof(c));
    tls_var[n].align = (1 << n);
  }
  for (size_t n = 0; n < num_saved_values; n++) {
    // Try to mess up malloc space so that the next malloc will not have the
    // required alignment, but __emutls_get_address should still return an
    // aligned address.
    saved_gap[n] = malloc(1);
    void* p = __emutls_get_address(&tls_var[n]);
    saved_p[n] = p;
    ASSERT_TRUE(p != nullptr);
    ASSERT_TRUE(tls_var[n].object.index != 0);
    // check if p is a new object.
    if (n > 0) {
      // In single-thread environment, object.address == p.
      // In multi-threads environment, object.index is increased.
      ASSERT_TRUE(prev_index + 1 == tls_var[n].object.index ||
                  p == tls_var[n].object.address);
      ASSERT_TRUE(p != saved_p[n - 1]);
    }
    prev_index = tls_var[n].object.index;
    // check if p is aligned
    uintptr_t align = (1 << n);
    uintptr_t address= reinterpret_cast<uintptr_t>(p);
    ASSERT_EQ((address & ~(align - 1)), address);
    // check if *p is initialized
    ASSERT_STREQ(tls_value1, static_cast<char*>(p));
    // change value in *p
    memcpy(p, tls_value2, strlen(tls_value2) + 1);
  }
  for (size_t n = 0; n < num_saved_values; n++) {
    free(saved_gap[n]);
  }
  for (size_t n = 0; n < num_saved_values; n++) {
    void* p = __emutls_get_address(&tls_var[n]);
    ASSERT_EQ(p, saved_p[n]);
    // check if *p has the new value
    ASSERT_STREQ(tls_value2, static_cast<char*>(p));
  }
}
