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 }