1 /******************************************************************************* 2 * Copyright (C) 2018 Cadence Design Systems, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to use this Software with Cadence processor cores only and 7 * not with any other processors and platforms, subject to 8 * the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included 11 * in all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 17 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 18 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 19 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21 ******************************************************************************/ 22 23 #ifndef __XF_H 24 #error "xf-osal.h mustn't be included directly" 25 #endif 26 27 /******************************************************************************* 28 * Includes 29 ******************************************************************************/ 30 #include "xos.h" 31 32 /******************************************************************************* 33 * Tracing primitive 34 ******************************************************************************/ 35 36 #define __xf_puts(str) \ 37 puts((str)) 38 39 /******************************************************************************* 40 * Lock operation 41 ******************************************************************************/ 42 43 /* ...lock definition */ 44 typedef XosMutex xf_lock_t; 45 46 /* ...lock initialization */ 47 static inline void __xf_lock_init(xf_lock_t *lock) 48 { 49 xos_mutex_create(lock, XOS_MUTEX_WAIT_PRIORITY, 0); 50 } 51 52 /* ...lock acquisition */ 53 static inline void __xf_lock(xf_lock_t *lock) 54 { 55 xos_mutex_lock(lock); 56 } 57 58 /* ...lock release */ 59 static inline void __xf_unlock(xf_lock_t *lock) 60 { 61 xos_mutex_unlock(lock); 62 } 63 64 /******************************************************************************* 65 * Waiting object 66 ******************************************************************************/ 67 68 #if 0 69 /* ...waiting object handle */ 70 typedef struct __xf_wait 71 { 72 /* ...conditional variable */ 73 pthread_cond_t wait; 74 75 /* ...waiting mutex */ 76 pthread_mutex_t mutex; 77 78 } xf_wait_t; 79 80 /* ...initialize waiting object */ 81 static inline void __xf_wait_init(xf_wait_t *w) 82 { 83 pthread_cond_init(&w->wait, NULL); 84 pthread_mutex_init(&w->mutex, NULL); 85 } 86 87 /* ...prepare to waiting */ 88 static inline void __xf_wait_prepare(xf_wait_t *w) 89 { 90 pthread_mutex_lock(&w->mutex); 91 } 92 93 #define __xf_wait_prepare(w) \ 94 ({ \ 95 TRACE(1, _x("prepare-wait")); \ 96 (__xf_wait_prepare)(w); \ 97 }) 98 99 /* ...wait until event is signalled */ 100 static inline int __xf_wait(xf_wait_t *w, u32 timeout) 101 { 102 struct timespec ts; 103 struct timeval tv; 104 int r; 105 106 /* ...wait with or without timeout (communication mutex is taken) */ 107 if (!timeout) 108 { 109 r = -pthread_cond_wait(&w->wait, &w->mutex); 110 } 111 else 112 { 113 /* ...get current time */ 114 gettimeofday(&tv, NULL); 115 116 /* ...set absolute timeout */ 117 ts.tv_sec = tv.tv_sec + timeout / 1000; 118 ts.tv_nsec = tv.tv_usec * 1000 + (timeout % 1000) * 1000000; 119 (ts.tv_nsec >= 1000000000 ? ts.tv_sec++, ts.tv_nsec -= 1000000000 : 0); 120 121 /* ...wait conditionally with absolute timeout*/ 122 r = -pthread_cond_timedwait(&w->wait, &w->mutex, &ts); 123 } 124 125 /* ...leave with communication mutex taken */ 126 return r; 127 } 128 129 #define __xf_wait(w, timeout) \ 130 ({ \ 131 int __r; \ 132 TRACE(1, _x("wait")); \ 133 __r = (__xf_wait)(w, timeout); \ 134 TRACE(1, _x("resume")); \ 135 __r; \ 136 }) 137 138 /* ...wake up waiting handle */ 139 static inline void __xf_wakeup(xf_wait_t *w) 140 { 141 /* ...take communication mutex before signaling */ 142 pthread_mutex_lock(&w->mutex); 143 144 /* ...signalling will resume waiting thread */ 145 pthread_cond_signal(&w->wait); 146 147 /* ...assure that waiting task will not resume until we say this - is that really needed? - tbd */ 148 pthread_mutex_unlock(&w->mutex); 149 } 150 151 #define __xf_wakeup(w) \ 152 ({ \ 153 TRACE(1, _x("wakeup")); \ 154 (__xf_wakeup)(w); \ 155 }) 156 157 /* ...complete waiting operation */ 158 static inline void __xf_wait_complete(xf_wait_t *w) 159 { 160 pthread_mutex_unlock(&w->mutex); 161 } 162 163 #define __xf_wait_complete(w) \ 164 ({ \ 165 TRACE(1, _x("wait-complete")); \ 166 (__xf_wait_complete)(w); \ 167 }) 168 #endif 169 170 /******************************************************************************* 171 * Thread support 172 ******************************************************************************/ 173 174 /* ...thread handle definition */ 175 typedef XosThread xf_thread_t; 176 typedef XosThreadFunc xf_entry_t; 177 178 /* ...thread creation */ 179 static inline int __xf_thread_create(xf_thread_t *thread, xf_entry_t *f, 180 void *arg, const char *name, void * stack, 181 unsigned int stack_size, int priority) 182 { 183 int r; 184 185 /* ...create proxy asynchronous thread managing SHMEM */ 186 r = xos_thread_create(thread, 0, f, arg, name, stack, stack_size, priority, 0, 0); 187 188 return r; 189 } 190 191 /* ...terminate thread operation */ 192 static inline int __xf_thread_destroy(xf_thread_t *thread) 193 { 194 int r; 195 196 /* ...wait until thread terminates */ 197 /* v-tbd - avoid infinite wait for join */ 198 //xos_thread_join(thread, &r); 199 200 /* ...delete thread, free up TCB, stack */ 201 r = xos_thread_delete(thread); 202 203 /* ...return final status */ 204 return r; 205 } 206 207