/* Copyright (c) 2012 The Regents of the University of California
 * Kevin Klues <klueska@cs.berkeley.edu>
 *
 * See LICENSE for details. */

#include <parlib/assert.h>
#include <parlib/dtls.h>
#include <parlib/slab.h>
#include <parlib/spinlock.h>
#include <stddef.h>

/* The current dymamic tls implementation uses a locked linked list
 * to find the key for a given thread. We should probably find a better way to
 * do this based on a custom lock-free hash table or something. */
#include <parlib/spinlock.h>
#include <sys/queue.h>

/* Define some number of static keys, for which the memory containing the keys
 * and the per-thread memory for the values associated with those keys is
 * allocated statically. This is adapted from glibc's notion of the
 * "specific_1stblock" field embedded directly into its pthread structure for
 * pthread_get/specific() calls. */
#define NUM_STATIC_KEYS 32

/* The dynamic tls key structure */
struct dtls_key {
	int id;
	int ref_count;
	bool valid;
	void (*dtor)(void *);
};

/* The definition of a dtls_key list and its elements */
struct dtls_value {
	TAILQ_ENTRY(dtls_value) link;
	struct dtls_key *key;
	const void *dtls;
};
TAILQ_HEAD(dtls_list, dtls_value);

/* A struct containing all of the per thread (i.e. vcore or uthread) data
 * associated with dtls */
typedef struct dtls_data {
	/* A per-thread list of dtls regions */
	struct dtls_list list;
	/* Memory to hold dtls values for the first NUM_STATIC_KEYS keys */
	struct dtls_value early_values[NUM_STATIC_KEYS];
} dtls_data_t;

/* A slab of dtls keys (global to all threads) */
static struct kmem_cache *__dtls_keys_cache;

/* A slab of values for use when mapping a dtls_key to its per-thread value */
struct kmem_cache *__dtls_values_cache;

static __thread dtls_data_t __dtls_data;
static __thread bool __dtls_initialized;
static struct dtls_key static_dtls_keys[NUM_STATIC_KEYS];
static int num_dtls_keys;

/* Initialize the slab caches for allocating dtls keys and values. */
int dtls_cache_init(void)
{
	/* Make sure this only runs once */
	static bool initialized;

	if (initialized)
		return 0;
	initialized = true;

	/* Initialize the global cache of dtls_keys */
	__dtls_keys_cache =
	    kmem_cache_create("dtls_keys_cache", sizeof(struct dtls_key),
	                      __alignof__(struct dtls_key), 0, NULL, NULL, NULL);

	/* Initialize the global cache of dtls_values */
	__dtls_values_cache =
	    kmem_cache_create("dtls_values_cache", sizeof(struct dtls_value),
	                      __alignof__(struct dtls_value), 0, NULL, NULL, NULL);

	return 0;
}

static dtls_key_t __allocate_dtls_key(void)
{
	dtls_key_t key;
	int keyid = __sync_fetch_and_add(&num_dtls_keys, 1);

	if (keyid < NUM_STATIC_KEYS) {
		key = &static_dtls_keys[keyid];
	} else {
		dtls_cache_init();
		key = kmem_cache_alloc(__dtls_keys_cache, 0);
	}
	assert(key);
	key->id = keyid;
	key->ref_count = 1;
	return key;
}

static void __maybe_free_dtls_key(dtls_key_t key)
{
	int ref_count = __sync_add_and_fetch(&key->ref_count, -1);

	if (ref_count == 0 && key->id >= NUM_STATIC_KEYS)
		kmem_cache_free(__dtls_keys_cache, key);
}

static struct dtls_value *__allocate_dtls_value(struct dtls_data *dtls_data,
                                                struct dtls_key *key)
{
	struct dtls_value *v;

	if (key->id < NUM_STATIC_KEYS)
		v = &dtls_data->early_values[key->id];
	else
		v = kmem_cache_alloc(__dtls_values_cache, 0);
	assert(v);
	return v;
}

static void __free_dtls_value(struct dtls_value *v)
{
	if (v->key->id >= NUM_STATIC_KEYS)
		kmem_cache_free(__dtls_values_cache, v);
}

dtls_key_t dtls_key_create(dtls_dtor_t dtor)
{
	dtls_key_t key = __allocate_dtls_key();

	key->valid = true;
	key->dtor = dtor;
	return key;
}

void dtls_key_delete(dtls_key_t key)
{
	assert(key);

	key->valid = false;
	__maybe_free_dtls_key(key);
}

static inline struct dtls_value *__get_dtls(dtls_data_t *dtls_data,
                                            dtls_key_t key)
{
	struct dtls_value *v;

	assert(key);
	if (key->id < NUM_STATIC_KEYS) {
		v = &dtls_data->early_values[key->id];
		if (v->key != NULL)
			return v;
	} else {
		TAILQ_FOREACH(v, &dtls_data->list, link)
			if (v->key == key)
				return v;
	}
	return NULL;
}

static inline void __set_dtls(dtls_data_t *dtls_data, dtls_key_t key,
                              const void *dtls)
{
	struct dtls_value *v;

	assert(key);
	v = __get_dtls(dtls_data, key);
	if (!v) {
		v = __allocate_dtls_value(dtls_data, key);
		__sync_fetch_and_add(&key->ref_count, 1);
		v->key = key;
		TAILQ_INSERT_HEAD(&dtls_data->list, v, link);
	}
	v->dtls = dtls;
}

static inline void __destroy_dtls(dtls_data_t *dtls_data)
{
	struct dtls_value *v, *n;
	dtls_key_t key;
	const void *dtls;

	v = TAILQ_FIRST(&dtls_data->list);
	while (v != NULL) {
		key = v->key;
		/* The dtor must be called outside of a spinlock so that it can call
		 * code that may deschedule it for a while (i.e. a mutex). Probably a
		 * good idea anyway since it can be arbitrarily long and is written by
		 * the user. Note, there is a small race here on the valid field,
		 * whereby we may run a destructor on an invalid key. At least the keys
		 * memory wont be deleted though, as protected by the ref count. Any
		 * reasonable usage of this interface should safeguard that a key is
		 * never destroyed before all of the threads that use it have exited
		 * anyway. */
		if (key->valid && key->dtor) {
			dtls = v->dtls;
			v->dtls = NULL;
			key->dtor((void*)dtls);
		}
		n = TAILQ_NEXT(v, link);
		TAILQ_REMOVE(&dtls_data->list, v, link);
		/* Free both the key (which is v->key) and v *after* removing v from the
		 * list.  It's possible that free() will call back into the DTLS (e.g.
		 * pthread_getspecific()), and v must be off the list by then.
		 *
		 * For a similar, hilarious bug in glibc, check out:
		 * https://sourceware.org/bugzilla/show_bug.cgi?id=3317 */
		__maybe_free_dtls_key(key);
		__free_dtls_value(v);
		v = n;
	}
}

void set_dtls(dtls_key_t key, const void *dtls)
{
	bool initialized = true;
	dtls_data_t *dtls_data = NULL;

	if (!__dtls_initialized) {
		initialized = false;
		__dtls_initialized = true;
	}
	dtls_data = &__dtls_data;
	if (!initialized)
		TAILQ_INIT(&dtls_data->list);
	__set_dtls(dtls_data, key, dtls);
}

void *get_dtls(dtls_key_t key)
{
	dtls_data_t *dtls_data = NULL;
	struct dtls_value *v;

	if (!__dtls_initialized)
		return NULL;
	dtls_data = &__dtls_data;
	v = __get_dtls(dtls_data, key);
	return v ? (void*)v->dtls : NULL;
}

void destroy_dtls(void)
{
	dtls_data_t *dtls_data = NULL;

	if (!__dtls_initialized)
		return;
	dtls_data = &__dtls_data;
	__destroy_dtls(dtls_data);
}
