1 /*
2 * Copyright (c) 2016, 2020 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include "test_mheap.h"
9
10 #define THREAD_NUM 3
11 #define BLOCK_SIZE 16
12 #define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
13
14 struct k_sem sync_sema;
15 static K_THREAD_STACK_ARRAY_DEFINE(tstack, THREAD_NUM, STACK_SIZE);
16 static struct k_thread tdata[THREAD_NUM];
17 static void *pool_blocks[BLK_NUM_MAX];
18
19 /*test cases*/
20
21 /**
22 * @brief The test validates k_calloc() API.
23 *
24 * @ingroup kernel_heap_tests
25 *
26 * @details The 8 blocks of memory of size 16 bytes are allocated
27 * by k_calloc() API. When allocated using k_calloc() the memory buffers
28 * have to be zeroed. Check is done, if the blocks are memset to 0 and
29 * read/write is allowed. The test is then teared up by freeing all the
30 * blocks allocated.
31 *
32 * @see k_malloc(), k_free()
33 */
ZTEST(mheap_api,test_mheap_malloc_align4)34 ZTEST(mheap_api, test_mheap_malloc_align4)
35 {
36 void *block[BLK_NUM_MAX];
37
38 /**
39 * TESTPOINT: The address of the allocated chunk is guaranteed to be
40 * aligned on a word boundary (4 or 8 bytes).
41 */
42 for (int i = 0; i < BLK_NUM_MAX; i++) {
43 block[i] = k_malloc(i);
44 zassert_not_null(block[i], NULL);
45 zassert_false((uintptr_t)block[i] % sizeof(void *));
46 }
47
48 /* test case tear down*/
49 for (int i = 0; i < BLK_NUM_MAX; i++) {
50 k_free(block[i]);
51 }
52 }
53
tmheap_handler(void * p1,void * p2,void * p3)54 static void tmheap_handler(void *p1, void *p2, void *p3)
55 {
56 int thread_id = POINTER_TO_INT(p1);
57
58 pool_blocks[thread_id] = k_malloc(BLOCK_SIZE);
59
60 zassert_not_null(pool_blocks[thread_id], "memory is not allocated");
61
62 k_sem_give(&sync_sema);
63 }
64
65 /**
66 * @brief Verify alloc from multiple equal priority threads
67 *
68 * @details Test creates three preemptive threads of equal priority.
69 * In each child thread , call k_malloc() to alloc a block of memory.
70 * Check These four threads can share the same heap space without
71 * interfering with each other.
72 *
73 * @ingroup kernel_memory_slab_tests
74 */
ZTEST(mheap_api,test_mheap_threadsafe)75 ZTEST(mheap_api, test_mheap_threadsafe)
76 {
77 if (!IS_ENABLED(CONFIG_MULTITHREADING)) {
78 return;
79 }
80
81 k_tid_t tid[THREAD_NUM];
82
83 k_sem_init(&sync_sema, 0, THREAD_NUM);
84
85 /* create multiple threads to invoke same memory heap APIs*/
86 for (int i = 0; i < THREAD_NUM; i++) {
87 tid[i] = k_thread_create(&tdata[i], tstack[i], STACK_SIZE,
88 tmheap_handler, INT_TO_POINTER(i), NULL, NULL,
89 K_PRIO_PREEMPT(1), 0, K_NO_WAIT);
90 }
91
92 for (int i = 0; i < THREAD_NUM; i++) {
93 k_sem_take(&sync_sema, K_FOREVER);
94 }
95
96 for (int i = 0; i < THREAD_NUM; i++) {
97 /* verify free mheap in main thread */
98 k_free(pool_blocks[i]);
99 k_thread_abort(tid[i]);
100 }
101 }
102