1 /** @file osa.c
2 *
3 * @brief OS Abstraction API
4 *
5 * Copyright 2023-2024 NXP
6 *
7 * SPDX-License-Identifier: BSD-3-Clause
8 *
9 */
10 #include <inttypes.h>
11 #include <stdio.h>
12 #include <osa.h>
13 #include <wmlog.h>
14
15 /** Check if cpu is in isr context
16 *
17 * \return bool value - true if cpu is in isr context
18 */
is_isr_context(void)19 bool is_isr_context(void)
20 {
21 #ifdef __CA7_REV
22 return (0U != if (SystemGetIRQNestingLevel()))
23 #else /* __CA7_REV */
24 return (0U != __get_IPSR());
25 #endif
26 }
27
28 /*** OS Reader Writer Locks ***/
29 int OSA_RWLockCreate(osa_rw_lock_t *plock, const char *mutex_name, const char *lock_name)
30 {
31 return OSA_RWLockCreateWithCB(plock, mutex_name, lock_name, NULL);
32 }
33
34 int OSA_RWLockCreateWithCB(osa_rw_lock_t *plock, const char *mutex_name, const char *lock_name, cb_fn r_fn)
35 {
36 osa_status_t status;
37
38 status = OSA_MutexCreate((osa_mutex_handle_t)plock->reader_mutex);
39 if (status != KOSA_StatusSuccess)
40 {
41 return -WM_FAIL;
42 }
43 status = OSA_MutexCreate((osa_mutex_handle_t)plock->write_mutex);
44 if (status != KOSA_StatusSuccess)
45 {
46 return -WM_FAIL;
47 }
48 status = OSA_SemaphoreCreateBinary((osa_semaphore_handle_t)plock->rw_lock);
49 if (status != KOSA_StatusSuccess)
50 {
51 return -WM_FAIL;
52 }
53 OSA_SemaphorePost((osa_semaphore_handle_t)plock->rw_lock);
54 plock->reader_count = 0;
55 plock->reader_cb = r_fn;
56 return WM_SUCCESS;
57 }
58
59 int OSA_RWLockReadLock(osa_rw_lock_t *lock, unsigned int wait_time)
60 {
61 int ret;
62 osa_status_t status = OSA_MutexLock((osa_mutex_handle_t)lock->reader_mutex, osaWaitForever_c);
63 if (status != KOSA_StatusSuccess)
64 {
65 return -WM_FAIL;
66 }
67 lock->reader_count++;
68 if (lock->reader_count == 1U)
69 {
70 if (lock->reader_cb != NULL)
71 {
72 ret = lock->reader_cb(lock, wait_time);
73 if (ret != WM_SUCCESS)
74 {
75 lock->reader_count--;
76 (void)OSA_MutexUnlock((osa_mutex_handle_t)lock->reader_mutex);
77 return ret;
78 }
79 }
80 else
81 {
82 /* If 1 it is the first reader and
83 * if writer is not active, reader will get access
84 * else reader will block.
85 */
86 status = OSA_SemaphoreWait((osa_semaphore_handle_t)lock->rw_lock, wait_time);
87 if (status != KOSA_StatusSuccess)
88 {
89 lock->reader_count--;
90 (void)OSA_MutexUnlock((osa_mutex_handle_t)lock->reader_mutex);
91 return -WM_FAIL;
92 }
93 }
94 }
95 (void)OSA_MutexUnlock((osa_mutex_handle_t)lock->reader_mutex);
96 return WM_SUCCESS;
97 }
98
99 int OSA_RWLockReadUnlock(osa_rw_lock_t *lock)
100 {
101 osa_status_t status = OSA_MutexLock((osa_mutex_handle_t)lock->reader_mutex, osaWaitForever_c);
102 if (status != KOSA_StatusSuccess)
103 {
104 return -WM_FAIL;
105 }
106 lock->reader_count--;
107 if (lock->reader_count == 0U)
108 {
109 /* This is last reader so
110 * give a chance to writer now
111 */
112 (void)OSA_SemaphorePost((osa_semaphore_handle_t)lock->rw_lock);
113 }
114 (void)OSA_MutexUnlock((osa_mutex_handle_t)lock->reader_mutex);
115 return WM_SUCCESS;
116 }
117
118 int OSA_RWLockWriteLock(osa_rw_lock_t *lock, unsigned int wait_time)
119 {
120 osa_status_t status = OSA_SemaphoreWait((osa_semaphore_handle_t)lock->rw_lock, wait_time);
121 if (status != KOSA_StatusSuccess)
122 {
123 return -WM_FAIL;
124 }
125
126 return WM_SUCCESS;
127 }
128
129 void OSA_RWLockWriteUnlock(osa_rw_lock_t *lock)
130 {
131 (void)OSA_SemaphorePost((osa_semaphore_handle_t)lock->rw_lock);
132 }
133
134 void OSA_RWLockDestroy(osa_rw_lock_t *lock)
135 {
136 lock->reader_cb = NULL;
137
138 (void)OSA_SemaphoreDestroy((osa_semaphore_handle_t)lock->rw_lock);
139
140 (void)OSA_MutexDestroy((osa_mutex_handle_t)lock->reader_mutex);
141
142 (void)OSA_MutexDestroy((osa_mutex_handle_t)lock->write_mutex);
143
144 lock->reader_count = 0;
145 }