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