<commit_before>/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ztest.h>
#include <irq_offload.h>
#include <sys/__assert.h>
#include <sys/util.h>

/*
 * @file
 * @brief Test fifo APIs timeout
 *
 * This module tests following fifo timeout scenarios
 *
 * First, the thread waits with a timeout and times out. Then it wait with a
 * timeout, but gets the data in time.
 *
 * Then, multiple timeout tests are done for the threads, to test the ordering
 * of queueing/dequeueing when timeout occurs, first on one fifo, then on
 * multiple fifos.
 *
 * Finally, multiple threads pend on one fifo, and they all get the
 * data in time, except the last one: this tests that the timeout is
 * recomputed correctly when timeouts are aborted.
 */

struct scratch_fifo_packet {
	void *link_in_fifo;
	void *data_if_needed;
};

struct reply_packet {
	void *link_in_fifo;
	s32_t reply;
};

struct timeout_order_data {
	void *link_in_fifo;
	struct k_fifo *fifo;
	u32_t timeout;
	s32_t timeout_order;
	s32_t q_order;
};


#define NUM_SCRATCH_FIFO_PACKETS 20
struct scratch_fifo_packet scratch_fifo_packets[NUM_SCRATCH_FIFO_PACKETS];

struct k_fifo scratch_fifo_packets_fifo;

static struct k_fifo fifo_timeout[2];
struct k_fifo timeout_order_fifo;

struct timeout_order_data timeout_order_data[] = {
	{0, &fifo_timeout[0], 20, 2, 0},
	{0, &fifo_timeout[0], 40, 4, 1},
	{0, &fifo_timeout[0], 0, 0, 2},
	{0, &fifo_timeout[0], 10, 1, 3},
	{0, &fifo_timeout[0], 30, 3, 4},
};

struct timeout_order_data timeout_order_data_mult_fifo[] = {
	{0, &fifo_timeout[1], 0, 0, 0},
	{0, &fifo_timeout[0], 30, 3, 1},
	{0, &fifo_timeout[0], 50, 5, 2},
	{0, &fifo_timeout[1], 80, 8, 3},
	{0, &fifo_timeout[1], 70, 7, 4},
	{0, &fifo_timeout[0], 10, 1, 5},
	{0, &fifo_timeout[0], 60, 6, 6},
	{0, &fifo_timeout[0], 20, 2, 7},
	{0, &fifo_timeout[1], 40, 4, 8},
};

#define TIMEOUT_ORDER_NUM_THREADS	ARRAY_SIZE(timeout_order_data_mult_fifo)
#define TSTACK_SIZE			(1024 + CONFIG_TEST_EXTRA_STACKSIZE)
#define FIFO_THREAD_PRIO		-5

static K_THREAD_STACK_ARRAY_DEFINE(ttstack,
		TIMEOUT_ORDER_NUM_THREADS, TSTACK_SIZE);
static struct k_thread ttdata[TIMEOUT_ORDER_NUM_THREADS];
static k_tid_t tid[TIMEOUT_ORDER_NUM_THREADS];

static void *get_scratch_packet(void)
{
	void *packet = k_fifo_get(&scratch_fifo_packets_fifo, K_NO_WAIT);

	zassert_true(packet != NULL, NULL);
	return packet;
}

static void put_scratch_packet(void *packet)
{
	k_fifo_put(&scratch_fifo_packets_fifo, packet);
}

static bool is_timeout_in_range(u32_t start_time, u32_t timeout)
{
	u32_t stop_time, diff;

	stop_time = k_cycle_get_32();
	diff = (u32_t)k_cyc_to_ns_floor64(stop_time -
			start_time) / NSEC_PER_USEC;
	diff = diff / USEC_PER_MSEC;
	return timeout <= diff;
}

/* a thread sleeps then puts data on the fifo */
static void test_thread_put_timeout(void *p1, void *p2, void *p3)
{
	u32_t timeout = *((u32_t *)p2);

	k_sleep(timeout);
	k_fifo_put((struct k_fifo *)p1, get_scratch_packet());
}

/* a thread pends on a fifo then times out */
static void test_thread_pend_and_timeout(void *p1, void *p2, void *p3)
{
	struct timeout_order_data *d = (struct timeout_order_data *)p1;
	u32_t start_time;
	void *packet;

	k_sleep(K_MSEC(1)); /* Align to ticks */

	start_time = k_cycle_get_32();
	packet = k_fifo_get(d->fifo, d->timeout);
	zassert_true(packet == NULL, NULL);
	zassert_true(is_timeout_in_range(start_time, d->timeout), NULL);

	k_fifo_put(&timeout_order_fifo, d);
}
/* Spins several threads that pend and timeout on fifos */
static int test_multiple_threads_pending(struct timeout_order_data *test_data,
					 int test_data_size)
{
	int ii, j;
	u32_t diff_ms;

	for (ii = 0; ii < test_data_size; ii++) {
		tid[ii] = k_thread_create(&ttdata[ii], ttstack[ii], TSTACK_SIZE,
				test_thread_pend_and_timeout,
				&test_data[ii], NULL, NULL,
				FIFO_THREAD_PRIO, K_INHERIT_PERMS, K_NO_WAIT);
	}

	/* In general, there is no guarantee of wakeup order when multiple
	 * threads are woken up on the same tick. This can especially happen
	 * when the system is loaded. However, in this particular test, we
	 * are controlling the system state and hence we can make a reasonable
	 * estimation of a timeout occurring with the max deviation of an
	 * additional tick. Hence the timeout order may slightly be different
	 * from what we normally expect.
	 */
	for (ii = 0; ii < test_data_size; ii++) {
		struct timeout_order_data *data =
			k_fifo_get(&timeout_order_fifo, K_FOREVER);

		if (data->timeout_order == ii) {
			TC_PRINT(" thread (q order: %d, t/o: %d, fifo %p)\n",
				data->q_order, data->timeout, data->fifo);
		} else {
			/* Get the index of the thread which should have
			 * actually timed out.
			 */
			for (j = 0; j < test_data_size; j++) {
				if (test_data[j].timeout_order == ii) {
					break;
				}
			}<commit_msg>tests: fifo: assert of NULL from k_fifo_get<commit_after>/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ztest.h>
#include <irq_offload.h>
#include <sys/__assert.h>
#include <sys/util.h>

/*
 * @file
 * @brief Test fifo APIs timeout
 *
 * This module tests following fifo timeout scenarios
 *
 * First, the thread waits with a timeout and times out. Then it wait with a
 * timeout, but gets the data in time.
 *
 * Then, multiple timeout tests are done for the threads, to test the ordering
 * of queueing/dequeueing when timeout occurs, first on one fifo, then on
 * multiple fifos.
 *
 * Finally, multiple threads pend on one fifo, and they all get the
 * data in time, except the last one: this tests that the timeout is
 * recomputed correctly when timeouts are aborted.
 */

struct scratch_fifo_packet {
	void *link_in_fifo;
	void *data_if_needed;
};

struct reply_packet {
	void *link_in_fifo;
	s32_t reply;
};

struct timeout_order_data {
	void *link_in_fifo;
	struct k_fifo *fifo;
	u32_t timeout;
	s32_t timeout_order;
	s32_t q_order;
};


#define NUM_SCRATCH_FIFO_PACKETS 20
struct scratch_fifo_packet scratch_fifo_packets[NUM_SCRATCH_FIFO_PACKETS];

struct k_fifo scratch_fifo_packets_fifo;

static struct k_fifo fifo_timeout[2];
struct k_fifo timeout_order_fifo;

struct timeout_order_data timeout_order_data[] = {
	{0, &fifo_timeout[0], 20, 2, 0},
	{0, &fifo_timeout[0], 40, 4, 1},
	{0, &fifo_timeout[0], 0, 0, 2},
	{0, &fifo_timeout[0], 10, 1, 3},
	{0, &fifo_timeout[0], 30, 3, 4},
};

struct timeout_order_data timeout_order_data_mult_fifo[] = {
	{0, &fifo_timeout[1], 0, 0, 0},
	{0, &fifo_timeout[0], 30, 3, 1},
	{0, &fifo_timeout[0], 50, 5, 2},
	{0, &fifo_timeout[1], 80, 8, 3},
	{0, &fifo_timeout[1], 70, 7, 4},
	{0, &fifo_timeout[0], 10, 1, 5},
	{0, &fifo_timeout[0], 60, 6, 6},
	{0, &fifo_timeout[0], 20, 2, 7},
	{0, &fifo_timeout[1], 40, 4, 8},
};

#define TIMEOUT_ORDER_NUM_THREADS	ARRAY_SIZE(timeout_order_data_mult_fifo)
#define TSTACK_SIZE			(1024 + CONFIG_TEST_EXTRA_STACKSIZE)
#define FIFO_THREAD_PRIO		-5

static K_THREAD_STACK_ARRAY_DEFINE(ttstack,
		TIMEOUT_ORDER_NUM_THREADS, TSTACK_SIZE);
static struct k_thread ttdata[TIMEOUT_ORDER_NUM_THREADS];
static k_tid_t tid[TIMEOUT_ORDER_NUM_THREADS];

static void *get_scratch_packet(void)
{
	void *packet = k_fifo_get(&scratch_fifo_packets_fifo, K_NO_WAIT);

	zassert_true(packet != NULL, NULL);
	return packet;
}

static void put_scratch_packet(void *packet)
{
	k_fifo_put(&scratch_fifo_packets_fifo, packet);
}

static bool is_timeout_in_range(u32_t start_time, u32_t timeout)
{
	u32_t stop_time, diff;

	stop_time = k_cycle_get_32();
	diff = (u32_t)k_cyc_to_ns_floor64(stop_time -
			start_time) / NSEC_PER_USEC;
	diff = diff / USEC_PER_MSEC;
	return timeout <= diff;
}

/* a thread sleeps then puts data on the fifo */
static void test_thread_put_timeout(void *p1, void *p2, void *p3)
{
	u32_t timeout = *((u32_t *)p2);

	k_sleep(timeout);
	k_fifo_put((struct k_fifo *)p1, get_scratch_packet());
}

/* a thread pends on a fifo then times out */
static void test_thread_pend_and_timeout(void *p1, void *p2, void *p3)
{
	struct timeout_order_data *d = (struct timeout_order_data *)p1;
	u32_t start_time;
	void *packet;

	k_sleep(K_MSEC(1)); /* Align to ticks */

	start_time = k_cycle_get_32();
	packet = k_fifo_get(d->fifo, d->timeout);
	zassert_true(packet == NULL, NULL);
	zassert_true(is_timeout_in_range(start_time, d->timeout), NULL);

	k_fifo_put(&timeout_order_fifo, d);
}
/* Spins several threads that pend and timeout on fifos */
static int test_multiple_threads_pending(struct timeout_order_data *test_data,
					 int test_data_size)
{
	int ii, j;
	u32_t diff_ms;

	for (ii = 0; ii < test_data_size; ii++) {
		tid[ii] = k_thread_create(&ttdata[ii], ttstack[ii], TSTACK_SIZE,
				test_thread_pend_and_timeout,
				&test_data[ii], NULL, NULL,
				FIFO_THREAD_PRIO, K_INHERIT_PERMS, K_NO_WAIT);
	}

	/* In general, there is no guarantee of wakeup order when multiple
	 * threads are woken up on the same tick. This can especially happen
	 * when the system is loaded. However, in this particular test, we
	 * are controlling the system state and hence we can make a reasonable
	 * estimation of a timeout occurring with the max deviation of an
	 * additional tick. Hence the timeout order may slightly be different
	 * from what we normally expect.
	 */
	for (ii = 0; ii < test_data_size; ii++) {
		struct timeout_order_data *data =
			k_fifo_get(&timeout_order_fifo, K_FOREVER);

		zassert_not_null(data, NULL);
		if (data->timeout_order == ii) {
			TC_PRINT(" thread (q order: %d, t/o: %d, fifo %p)\n",
				data->q_order, data->timeout, data->fifo);
		} else {
			/* Get the index of the thread which should have
			 * actually timed out.
			 */
			for (j = 0; j < test_data_size; j++) {
				if (test_data[j].timeout_order == ii) {
					break;
				}
			}
{'fraction_non_alphanumeric': 0.11661867544220485, 'fraction_numerical': 0.028589058000822707, 'mean_word_length': 4.710510863182619, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4769458', 'n_tokens_mistral': 4053, 'n_tokens_neox': 3730, 'n_words': 1036}