/*
 * Copyright (c) 2017 Oticon A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * Here is where things actually happen for the POSIX arch
 *
 * We isolate all functions here, to ensure they can be compiled as
 * independently as possible to the remainder of Zephyr to avoid name clashes
 * as Zephyr does provide functions with the same names as the POSIX threads
 * functions
 */
/**
 * Principle of operation:
 *
 * The Zephyr OS and its app run as a set of native pthreads.
 * The Zephyr OS only sees one of this thread executing at a time.
 * Which is running is controlled using {cond|mtx}_threads and
 * currently_allowed_thread.
 *
 * The main part of the execution of each thread will occur in a fully
 * synchronous and deterministic manner, and only when commanded by the Zephyr
 * kernel.
 * But the creation of a thread will spawn a new pthread whose start
 * is asynchronous to the rest, until synchronized in posix_wait_until_allowed()
 * below.
 * Similarly aborting and canceling threads execute a tail in a quite
 * asynchronous manner.
 *
 * This implementation is meant to be portable in between POSIX systems.
 * A table (threads_table) is used to abstract the native pthreads.
 * And index in this table is used to identify threads in the IF to the kernel.
 *
 */

#define POSIX_ARCH_DEBUG_PRINTS 0

#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

#include "posix_core.h"
#include "posix_arch_internal.h"
#include <zephyr/arch/posix/posix_soc_if.h>
#include "kernel_internal.h"
#include "kernel_structs.h"
#include "ksched.h"
#include "kswap.h"

#define PREFIX     "POSIX arch core: "
#define ERPREFIX   PREFIX"error on "
#define NO_MEM_ERR PREFIX"Can't allocate memory\n"

#if POSIX_ARCH_DEBUG_PRINTS
#define PC_DEBUG(fmt, ...) posix_print_trace(PREFIX fmt, __VA_ARGS__)
#else
#define PC_DEBUG(...)
#endif

#define PC_ALLOC_CHUNK_SIZE 64
#define PC_REUSE_ABORTED_ENTRIES 0
/* tests/kernel/threads/scheduling/schedule_api fails when setting
 * PC_REUSE_ABORTED_ENTRIES => don't set it by now
 */

static int threads_table_size;
struct threads_table_el {
	enum {NOTUSED = 0, USED, ABORTING, ABORTED, FAILED} state;
	bool running;     /* Is this the currently running thread */
	pthread_t thread; /* Actual pthread_t as returned by native kernel */
	int thead_cnt; /* For debugging: Unique, consecutive, thread number */
	/* Pointer to the status kept in the Zephyr thread stack */
	posix_thread_status_t *t_status;
};

static struct threads_table_el *threads_table;

static int thread_create_count; /* For debugging. Thread creation counter */

/*
 * Conditional variable to block/awake all threads during swaps()
 * (we only need 1 mutex and 1 cond variable for all threads)
 */
static pthread_cond_t cond_threads = PTHREAD_COND_INITIALIZER;
/* Mutex for the conditional variable posix_core_cond_threads */
static pthread_mutex_t mtx_threads = PTHREAD_MUTEX_INITIALIZER;
/* Token which tells which process is allowed to run now */
static int currently_allowed_thread;

static bool terminate; /* Are we terminating the program == cleaning up */

static void posix_wait_until_allowed(int this_th_nbr);
static void *posix_thread_starter(void *arg);
static void posix_preexit_cleanup(void);

/**
 * Helper function, run by a thread is being aborted
 */
static void abort_tail(int this_th_nbr)
{
	PC_DEBUG("Thread [%i] %i: %s: Aborting (exiting) (rel mut)\n",
		threads_table[this_th_nbr].thead_cnt,
		this_th_nbr,
		__func__);

	threads_table[this_th_nbr].running = false;
	threads_table[this_th_nbr].state = ABORTED;
	posix_preexit_cleanup();
	pthread_exit(NULL);
}

/**
 *  Helper function to block this thread until it is allowed again
 *  (somebody calls posix_let_run() with this thread number
 *
 * Note that we go out of this function (the while loop below)
 * with the mutex locked by this particular thread.
 * In normal circumstances, the mutex is only unlocked internally in
 * pthread_cond_wait() while waiting for cond_threads to be signaled
 */
static void posix_wait_until_allowed(int this_th_nbr)
{
	threads_table[this_th_nbr].running = false;

	PC_DEBUG("Thread [%i] %i: %s: Waiting to be allowed to run (rel mut)\n",
		threads_table[this_th_nbr].thead_cnt,
		this_th_nbr,
		__func__);

	while (this_th_nbr != currently_allowed_thread) {
		pthread_cond_wait(&cond_threads, &mtx_threads);

		if (threads_table &&
		    (threads_table[this_th_nbr].state == ABORTING)) {
			abort_tail(this_th_nbr);
		}
	}

	threads_table[this_th_nbr].running = true;

	PC_DEBUG("Thread [%i] %i: %s(): I'm allowed to run! (hav mut)\n",
		threads_table[this_th_nbr].thead_cnt,
		this_th_nbr,
		__func__);
}


/**
 * Helper function to let the thread <next_allowed_th> run
 * Note: posix_let_run() can only be called with the mutex locked
 */
static void posix_let_run(int next_allowed_th)
{
	PC_DEBUG("%s: We let thread [%i] %i run\n",
		__func__,
		threads_table[next_allowed_th].thead_cnt,
		next_allowed_th);


	currently_allowed_thread = next_allowed_th;

	/*
	 * We let all threads know one is able to run now (it may even be us
	 * again if fancied)
	 * Note that as we hold the mutex, they are going to be blocked until
	 * we reach our own posix_wait_until_allowed() while loop
	 */
	PC_SAFE_CALL(pthread_cond_broadcast(&cond_threads));
}


static void posix_preexit_cleanup(void)
{
	/*
	 * Release the mutex so the next allowed thread can run
	 */
	PC_SAFE_CALL(pthread_mutex_unlock(&mtx_threads));

	/* We detach ourselves so nobody needs to join to us */
	pthread_detach(pthread_self());
}


/**
 * Let the ready thread run and block this thread until it is allowed again
 *
 * called from arch_swap() which does the picking from the kernel structures
 */
void posix_swap(int next_allowed_thread_nbr, int this_th_nbr)
{
	posix_let_run(next_allowed_thread_nbr);

	if (threads_table[this_th_nbr].state == ABORTING) {
		PC_DEBUG("Thread [%i] %i: %s: Aborting curr.\n",
			threads_table[this_th_nbr].thead_cnt,
			this_th_nbr,
			__func__);
		abort_tail(this_th_nbr);
	} else {
		posix_wait_until_allowed(this_th_nbr);
	}
}

/**
 * Let the ready thread (main) run, and exit this thread (init)
 *
 * Called from arch_switch_to_main_thread() which does the picking from the
 * kernel structures
 *
 * Note that we could have just done a swap(), but that would have left the
 * init thread lingering. Instead here we exit the init thread after enabling
 * the new one
 */
void posix_main_thread_start(int next_allowed_thread_nbr)
{
	posix_let_run(next_allowed_thread_nbr);
	PC_DEBUG("%s: Init thread dying now (rel mut)\n",
		__func__);
	posix_preexit_cleanup();
	pthread_exit(NULL);
}

/**
 * Handler called when any thread is cancelled or exits
 */
static void posix_cleanup_handler(void *arg)
{
	/*
	 * If we are not terminating, this is just an aborted thread,
	 * and the mutex was already released
	 * Otherwise, release the mutex so other threads which may be
	 * caught waiting for it could terminate
	 */

	if (!terminate) {
		return;
	}

#if POSIX_ARCH_DEBUG_PRINTS
	posix_thread_status_t *ptr = (posix_thread_status_t *) arg;

	PC_DEBUG("Thread %i: %s: Canceling (rel mut)\n",
		ptr->thread_idx,
		__func__);
#endif


	PC_SAFE_CALL(pthread_mutex_unlock(&mtx_threads));

	/* We detach ourselves so nobody needs to join to us */
	pthread_detach(pthread_self());
}

/**
 * Helper function to start a Zephyr thread as a POSIX thread:
 *  It will block the thread until a arch_swap() is called for it
 *
 * Spawned from posix_new_thread() below
 */
static void *posix_thread_starter(void *arg)
{
	int thread_idx = (intptr_t)arg;

	PC_DEBUG("Thread [%i] %i: %s: Starting\n",
		threads_table[thread_idx].thead_cnt,
		thread_idx,
		__func__);

	/*
	 * We block until all other running threads reach the while loop
	 * in posix_wait_until_allowed() and they release the mutex
	 */
	PC_SAFE_CALL(pthread_mutex_lock(&mtx_threads));

	/*
	 * The program may have been finished before this thread ever got to run
	 */
	/* LCOV_EXCL_START */ /* See Note1 */
	if (!threads_table) {
		posix_cleanup_handler(arg);
		pthread_exit(NULL);
	}
	/* LCOV_EXCL_STOP */

	pthread_cleanup_push(posix_cleanup_handler, arg);

	PC_DEBUG("Thread [%i] %i: %s: After start mutex (hav mut)\n",
		threads_table[thread_idx].thead_cnt,
		thread_idx,
		__func__);

	/*
	 * The thread would try to execute immediately, so we block it
	 * until allowed
	 */
	posix_wait_until_allowed(thread_idx);

	posix_new_thread_pre_start();

	posix_thread_status_t *ptr = threads_table[thread_idx].t_status;

	z_thread_entry(ptr->entry_point, ptr->arg1, ptr->arg2, ptr->arg3);

	/*
	 * We only reach this point if the thread actually returns which should
	 * not happen. But we handle it gracefully just in case
	 */
	/* LCOV_EXCL_START */
	posix_print_trace(PREFIX"Thread [%i] %i [%lu] ended!?!\n",
			threads_table[thread_idx].thead_cnt,
			thread_idx,
			pthread_self());


	threads_table[thread_idx].running = false;
	threads_table[thread_idx].state = FAILED;

	pthread_cleanup_pop(1);

	return NULL;
	/* LCOV_EXCL_STOP */
}

/**
 * Return the first free entry index in the threads table
 */
static int ttable_get_empty_slot(void)
{

	for (int i = 0; i < threads_table_size; i++) {
		if ((threads_table[i].state == NOTUSED)
			|| (PC_REUSE_ABORTED_ENTRIES
			&& (threads_table[i].state == ABORTED))) {
			return i;
		}
	}

	/*
	 * else, we run out table without finding an index
	 * => we expand the table
	 */

	threads_table = realloc(threads_table,
				(threads_table_size + PC_ALLOC_CHUNK_SIZE)
				* sizeof(struct threads_table_el));
	if (threads_table == NULL) { /* LCOV_EXCL_BR_LINE */
		posix_print_error_and_exit(NO_MEM_ERR); /* LCOV_EXCL_LINE */
	}

	/* Clear new piece of table */
	(void)memset(&threads_table[threads_table_size], 0,
		     PC_ALLOC_CHUNK_SIZE * sizeof(struct threads_table_el));

	threads_table_size += PC_ALLOC_CHUNK_SIZE;

	/* The first newly created entry is good: */
	return threads_table_size - PC_ALLOC_CHUNK_SIZE;
}

/**
 * Called from arch_new_thread(),
 * Create a new POSIX thread for the new Zephyr thread.
 * arch_new_thread() picks from the kernel structures what it is that we need
 * to call with what parameters
 */
void posix_new_thread(posix_thread_status_t *ptr)
{
	int t_slot;

	t_slot = ttable_get_empty_slot();
	threads_table[t_slot].state = USED;
	threads_table[t_slot].running = false;
	threads_table[t_slot].thead_cnt = thread_create_count++;
	threads_table[t_slot].t_status = ptr;
	ptr->thread_idx = t_slot;

	PC_SAFE_CALL(pthread_create(&threads_table[t_slot].thread,
				  NULL,
				  posix_thread_starter,
				  (void *)(intptr_t)t_slot));

	PC_DEBUG("%s created thread [%i] %i [%lu]\n",
		__func__,
		threads_table[t_slot].thead_cnt,
		t_slot,
		threads_table[t_slot].thread);

}

/**
 * Called from zephyr_wrapper()
 * prepare whatever needs to be prepared to be able to start threads
 */
void posix_init_multithreading(void)
{
	thread_create_count = 0;

	currently_allowed_thread = -1;

	threads_table = calloc(PC_ALLOC_CHUNK_SIZE,
				sizeof(struct threads_table_el));
	if (threads_table == NULL) { /* LCOV_EXCL_BR_LINE */
		posix_print_error_and_exit(NO_MEM_ERR); /* LCOV_EXCL_LINE */
	}

	threads_table_size = PC_ALLOC_CHUNK_SIZE;


	PC_SAFE_CALL(pthread_mutex_lock(&mtx_threads));
}

/**
 * Free any allocated memory by the posix core and clean up.
 * Note that this function cannot be called from a SW thread
 * (the CPU is assumed halted. Otherwise we will cancel ourselves)
 *
 * This function cannot guarantee the threads will be cancelled before the HW
 * thread exists. The only way to do that, would be  to wait for each of them in
 * a join (without detaching them, but that could lead to locks in some
 * convoluted cases. As a call to this function can come from an ASSERT or other
 * error termination, we better do not assume things are working fine.
 * => we prefer the supposed memory leak report from valgrind, and ensure we
 * will not hang
 *
 */
void posix_core_clean_up(void)
{

	if (!threads_table) { /* LCOV_EXCL_BR_LINE */
		return; /* LCOV_EXCL_LINE */
	}

	terminate = true;

	for (int i = 0; i < threads_table_size; i++) {
		if (threads_table[i].state != USED) {
			continue;
		}

		/* LCOV_EXCL_START */
		if (pthread_cancel(threads_table[i].thread)) {
			posix_print_warning(
				PREFIX"cleanup: could not stop thread %i\n",
				i);
		}
		/* LCOV_EXCL_STOP */
	}

	free(threads_table);
	threads_table = NULL;
}


void posix_abort_thread(int thread_idx)
{
	if (threads_table[thread_idx].state != USED) { /* LCOV_EXCL_BR_LINE */
		/* The thread may have been already aborted before */
		return; /* LCOV_EXCL_LINE */
	}

	PC_DEBUG("Aborting not scheduled thread [%i] %i\n",
		threads_table[thread_idx].thead_cnt,
		thread_idx);

	threads_table[thread_idx].state = ABORTING;
	/*
	 * Note: the native thread will linger in RAM until it catches the
	 * mutex or awakes on the condition.
	 * Note that even if we would pthread_cancel() the thread here, that
	 * would be the case, but with a pthread_cancel() the mutex state would
	 * be uncontrolled
	 */
}


#if defined(CONFIG_ARCH_HAS_THREAD_ABORT)
void z_impl_k_thread_abort(k_tid_t thread)
{
	unsigned int key;
	int thread_idx;

	posix_thread_status_t *tstatus =
					(posix_thread_status_t *)
					thread->callee_saved.thread_status;

	thread_idx = tstatus->thread_idx;

	key = irq_lock();

	if (_current == thread) {
		if (tstatus->aborted == 0) { /* LCOV_EXCL_BR_LINE */
			tstatus->aborted = 1;
		} else {
			posix_print_warning(/* LCOV_EXCL_LINE */
				PREFIX"The kernel is trying to abort and swap "
				"out of an already aborted thread %i. This "
				"should NOT have happened\n",
				thread_idx);
		}
		threads_table[thread_idx].state = ABORTING;
		PC_DEBUG("Thread [%i] %i: %s Marked myself "
			"as aborting\n",
			threads_table[thread_idx].thead_cnt,
			thread_idx,
			__func__);
	}

	z_thread_abort(thread);

	if (tstatus->aborted == 0) {
		PC_DEBUG("%s aborting now [%i] %i\n",
			__func__,
			threads_table[thread_idx].thead_cnt,
			thread_idx);

		tstatus->aborted = 1;
		posix_abort_thread(thread_idx);
	} else {
		PC_DEBUG("%s ignoring re_abort of [%i] "
			"%i\n",
			__func__,
			threads_table[thread_idx].thead_cnt,
			thread_idx);
	}

	/* The abort handler might have altered the ready queue. */
	z_reschedule_irqlock(key);
}
#endif


/*
 * Notes about coverage:
 *
 * Note1:
 *
 * This condition will only be triggered in very unlikely cases
 * (once every few full regression runs).
 * It is therefore excluded from the coverage report to avoid confusing
 * developers.
 *
 * Background: This arch creates a pthread as soon as the Zephyr kernel creates
 * a Zephyr thread. A pthread creation is an asynchronous process handled by the
 * host kernel.
 *
 * This architecture normally keeps only 1 thread executing at a time.
 * But part of the pre-initialization during creation of a new thread
 * and some cleanup at the tail of the thread termination are executed
 * in parallel to other threads.
 * That is, the execution of those code paths is a bit indeterministic.
 *
 * Only when the Zephyr kernel attempts to swap to a new thread does this
 * architecture need to wait until its pthread is ready and initialized
 * (has reached posix_wait_until_allowed())
 *
 * In some cases (tests) threads are created which are never actually needed
 * (typically the idle thread). That means the test may finish before this
 * thread's underlying pthread has reached posix_wait_until_allowed().
 *
 * In this unlikely cases the initialization or cleanup of the thread follows
 * non-typical code paths.
 * This code paths are there to ensure things work always, no matter
 * the load of the host. Without them, very rare & mysterious segfault crashes
 * would occur.
 * But as they are very atypical and only triggered with some host loads,
 * they will be covered in the coverage reports only rarely.
 *
 * Note2:
 *
 * Some other code will never or only very rarely trigger and is therefore
 * excluded with LCOV_EXCL_LINE
 *
 */
