Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | /* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <ztest.h> #include <kernel.h> #include <pthread.h> #include <sys/util.h> #define N_THR 2 #define N_KEY 2 #define STACKSZ (1024 + CONFIG_TEST_EXTRA_STACKSIZE) #define BUFFSZ 48 K_THREAD_STACK_ARRAY_DEFINE(stackp, N_THR, STACKSZ); pthread_key_t key, keys[N_KEY]; static pthread_once_t key_once, keys_once; void *thread_top(void *p1) { int ret = -1; void *value; void *getval; char *buffer[BUFFSZ]; value = k_malloc(sizeof(buffer)); zassert_true((int) POINTER_TO_INT(value), "thread could not allocate storage"); ret = pthread_setspecific(key, value); /* TESTPOINT: Check if thread's value is associated with key */ zassert_false(ret, "pthread_setspecific failed"); getval = 0; getval = pthread_getspecific(key); /* TESTPOINT: Check if pthread_getspecific returns the same value * set by pthread_setspecific */ zassert_equal(value, getval, "set and retrieved values are different"); printk("set value = %d and retrieved value = %d\n", (int) POINTER_TO_INT(value), (int) POINTER_TO_INT(getval)); return NULL; } void *thread_func(void *p1) { int i, ret = -1; void *value; void *getval; char *buffer[BUFFSZ]; value = k_malloc(sizeof(buffer)); zassert_true((int) POINTER_TO_INT(value), "thread could not allocate storage"); for (i = 0; i < N_KEY; i++) { ret = pthread_setspecific(keys[i], value); /* TESTPOINT: Check if thread's value is associated with keys */ zassert_false(ret, "pthread_setspecific failed"); } for (i = 0; i < N_KEY; i++) { getval = 0; getval = pthread_getspecific(keys[i]); /* TESTPOINT: Check if pthread_getspecific returns the same * value set by pthread_setspecific for each of the keys */ zassert_equal(value, getval, "set and retrieved values are different"); printk("key %d: set value = %d and retrieved value = %d\n", i, (int) POINTER_TO_INT(value), (int) POINTER_TO_INT(getval)); } return NULL; } static void make_key(void) { int ret = 0; ret = pthread_key_create(&key, NULL); zassert_false(ret, "insufficient memory to create key"); } static void make_keys(void) { int i, ret = 0; for (i = 0; i < N_KEY; i++) { ret = pthread_key_create(&keys[i], NULL); zassert_false(ret, "insufficient memory to create keys"); } } /** * @brief Test to demonstrate pthread_key APIs usage * * @details The tests spawn a thread which uses pthread_once() to * create a key via pthread_key_create() API. It then sets the * thread-specific value to the key using pthread_setspecific() and * gets it back using pthread_getspecific and asserts that they * are equal. It then deletes the key using pthread_key_delete(). * Both the sub-tests do the above, but one with multiple threads * using the same key and the other with a single thread using * multiple keys. */ void test_posix_multiple_threads_single_key(void) { int i, ret = -1; pthread_attr_t attr[N_THR]; struct sched_param schedparam; pthread_t newthread[N_THR]; void *retval; ret = pthread_once(&key_once, make_key); /* TESTPOINT: Check if key is created */ zassert_false(ret, "attempt to create key failed"); printk("\nDifferent threads set different values to same key:\n"); /* Creating threads with lowest application priority */ for (i = 0; i < N_THR; i++) { ret = pthread_attr_init(&attr[i]); if (ret != 0) { zassert_false(pthread_attr_destroy(&attr[i]), "Unable to destroy pthread object attr"); zassert_false(pthread_attr_init(&attr[i]), "Unable to create pthread object attr"); } schedparam.sched_priority = 2; pthread_attr_setschedparam(&attr[i], &schedparam); pthread_attr_setstack(&attr[i], &stackp[i][0], STACKSZ); ret = pthread_create(&newthread[i], &attr[i], thread_top, INT_TO_POINTER(i)); /* TESTPOINT: Check if threads are created successfully */ zassert_false(ret, "attempt to create threads failed"); } for (i = 0; i < N_THR; i++) { printk("thread %d: ", i); pthread_join(newthread[i], &retval); } ret = pthread_key_delete(key); /* TESTPOINT: Check if key is deleted */ zassert_false(ret, "attempt to delete key failed"); printk("\n"); } void test_posix_single_thread_multiple_keys(void) { int i, ret = -1; pthread_attr_t attr; struct sched_param schedparam; pthread_t newthread; ret = pthread_once(&keys_once, make_keys); /* TESTPOINT: Check if keys are created successfully */ zassert_false(ret, "attempt to create keys failed"); printk("\nSingle thread associates its value with different keys:\n"); ret = pthread_attr_init(&attr); if (ret != 0) { zassert_false(pthread_attr_destroy(&attr), "Unable to destroy pthread object attr"); zassert_false(pthread_attr_init(&attr), "Unable to create pthread object attr"); } schedparam.sched_priority = 2; pthread_attr_setschedparam(&attr, &schedparam); pthread_attr_setstack(&attr, &stackp[0][0], STACKSZ); ret = pthread_create(&newthread, &attr, thread_func, (void *)0); /*TESTPOINT: Check if thread is created successfully */ zassert_false(ret, "attempt to create thread failed"); pthread_join(newthread, NULL); for (i = 0; i < N_KEY; i++) { ret = pthread_key_delete(keys[i]); /* TESTPOINT: Check if keys are deleted */ zassert_false(ret, "attempt to delete keys failed"); } printk("\n"); } |