blob: d7eeea03932b1ba2a6eb24a6881c4ff424e1413c [file] [log] [blame]
yu.dongc33b3072024-08-21 23:14:49 -07001/*****************************************************************************
2* Copyright Statement:
3* --------------------
4* This software is protected by Copyright and the information contained
5* herein is confidential. The software may not be copied and the information
6* contained herein may not be used or disclosed except with the written
7* permission of MediaTek Inc. (C) 2018
8*
9* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
10* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
11* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
12* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
13* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
15* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
16* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
17* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
18* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
19* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
20* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
21*
22* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
23* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
24* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
25* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
26* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
27*
28* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
29* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
30* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
31* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
32* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
33*
34*****************************************************************************/
35
36/*******************************************************************************
37 * Filename:
38 * ---------
39 * mcf_object.h
40 *
41 * Project:
42 * --------
43 * UMOLYA
44 *
45 * Description:
46 * ------------
47 * Helper for object management and synchronization.
48 *
49 * Author:
50 * -------
51 * -------
52 *
53 *==============================================================================
54 * HISTORY
55 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
56 *------------------------------------------------------------------------------
57 * removed!
58 *
59 *------------------------------------------------------------------------------
60 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
61 *==============================================================================
62 *******************************************************************************/
63
64#ifndef __INC_MCF_OBJECT_H
65#define __INC_MCF_OBJECT_H
66
67#include "kal_public_api.h"
68
69#include "mcf_struct.h"
70
71struct _mcf_object_template;
72extern kal_enhmutexid mcf_enhmutex_g;
73static INLINE kal_bool mcf_is_object_valid(struct _mcf_object_template *object);
74
75/*------------------------------------------------------------------------------
76 * Data structure defintion.
77 *----------------------------------------------------------------------------*/
78#define MCF_MUTEX_LOCK(_lock) \
79 if (kal_query_systemInit() == KAL_FALSE) { \
80 kal_take_enh_mutex(_lock); \
81 }
82#define MCF_MUTEX_UNLOCK(_lock) \
83 if (kal_query_systemInit() == KAL_FALSE) { \
84 kal_give_enh_mutex(_lock); \
85 }
86
87#define MCF_IS_VALID_OBJECT_WO_LOCK(_object) \
88 ((_object) != NULL && (_object)->ref_count == 2)
89
90#define MCF_IS_VALID_OBJECT(_object) \
91 mcf_is_object_valid((struct _mcf_object_template *)_object)
92
93#define MCF_R_LOCK_OBJECT(_object, _lock) \
94 MCF_MUTEX_LOCK(_lock); \
95 if (MCF_IS_VALID_OBJECT_WO_LOCK(_object) && ((_object)->writer_cnt == 0)) { \
96 ++((_object)->reader_cnt); \
97 } else { \
98 (_object) = NULL; \
99 } \
100 MCF_MUTEX_UNLOCK(_lock)
101
102#define MCF_R_UNLOCK_OBJECT(_object, _lock) \
103 ASSERT((_object)); \
104 MCF_MUTEX_LOCK(_lock); \
105 ASSERT((_object)->reader_cnt > 0); \
106 --((_object)->reader_cnt); \
107 MCF_MUTEX_UNLOCK(_lock)
108
109#define MCF_INIT_OBJECT_BEGIN(_object, _lock) \
110 ASSERT(_object); \
111 MCF_MUTEX_LOCK(_lock); \
112 ASSERT((_object)->ref_count == 0); \
113 (_object)->ref_count = 1; \
114 MCF_MUTEX_UNLOCK(_lock)
115
116#define MCF_INIT_OBJECT_END(_object, _lock) \
117 ASSERT(_object); \
118 MCF_MUTEX_LOCK(_lock); \
119 ASSERT(_object->ref_count == 1); \
120 (_object)->ref_count = 2; \
121 (_object)->reader_cnt = 0; \
122 (_object)->writer_cnt = 0; \
123 MCF_MUTEX_UNLOCK(_lock)
124
125#define MCF_DEINIT_OBJECT_BEGIN(_object, _lock) \
126 MCF_MUTEX_LOCK(_lock); \
127 if (MCF_IS_VALID_OBJECT_WO_LOCK(_object)) { \
128 --((_object)->ref_count); \
129 while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
130 MCF_MUTEX_UNLOCK(_lock); \
131 kal_sleep_task(MCF_DEL_OBJECT_SLEEP_TICKS); \
132 MCF_MUTEX_LOCK(_lock); \
133 } \
134 ASSERT((_object)->ref_count == 1); \
135 } else { \
136 (_object) = NULL; \
137 } \
138 MCF_MUTEX_UNLOCK(_lock)
139
140#define MCF_DEINIT_OBJECT_END(_object, _lock) \
141 MCF_MUTEX_LOCK(_lock); \
142 ASSERT((_object)->ref_count == 1); \
143 ASSERT((_object)->reader_cnt == 0); \
144 ASSERT((_object)->writer_cnt == 0); \
145 (_object)->ref_count = 0; \
146 MCF_MUTEX_UNLOCK(_lock)
147
148#define MCF_W_LOCK_OBJECT(_object, _lock) \
149 MCF_MUTEX_LOCK(_lock); \
150 if (MCF_IS_VALID_OBJECT_WO_LOCK(_object)) { \
151 while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
152 MCF_MUTEX_UNLOCK(_lock); \
153 kal_sleep_task(MCF_W_LOCK_OBJECT_SLEEP_TICKS); \
154 MCF_MUTEX_LOCK(_lock); \
155 } \
156 if (MCF_IS_VALID_OBJECT_WO_LOCK(_object)) { \
157 ++((_object)->writer_cnt); \
158 } else { \
159 (_object) = NULL; \
160 MCF_MUTEX_UNLOCK(_lock); \
161 } \
162 } else { \
163 (_object) = NULL; \
164 MCF_MUTEX_UNLOCK(_lock); \
165 }
166
167#define MCF_W_UNLOCK_OBJECT(_object, _lock) \
168 ASSERT((_object)); \
169 ASSERT((_object)->writer_cnt == 1); \
170 --((_object)->writer_cnt); \
171 MCF_MUTEX_UNLOCK(_lock)
172
173/* Safely convert between Read & Write lock at the same time. */
174#define MCF_R_TO_W_LOCK_OBJECT(_object, _lock) \
175 MCF_MUTEX_LOCK(_lock); \
176 if (MCF_IS_VALID_OBJECT_WO_LOCK(_object)) { \
177 ASSERT((_object)->reader_cnt > 0); \
178 --((_object)->reader_cnt); \
179 while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
180 MCF_MUTEX_UNLOCK(_lock); \
181 kal_sleep_task(MCF_W_LOCK_OBJECT_SLEEP_TICKS); \
182 MCF_MUTEX_LOCK(_lock); \
183 } \
184 if (MCF_IS_VALID_OBJECT_WO_LOCK(_object)) { \
185 ++((_object)->writer_cnt); \
186 } else { \
187 (_object) = NULL; \
188 MCF_MUTEX_UNLOCK(_lock); \
189 } \
190 } else { \
191 (_object) = NULL; \
192 MCF_MUTEX_UNLOCK(_lock); \
193 }
194
195#define MCF_W_TO_R_LOCK_OBJECT(_object, _lock) \
196 ASSERT((_object)); \
197 ASSERT((_object)->reader_cnt == 0); \
198 ASSERT((_object)->writer_cnt == 1); \
199 --((_object)->writer_cnt); \
200 ++((_object)->reader_cnt); \
201 MCF_MUTEX_UNLOCK(_lock)
202
203/*------------------------------------------------------------------------------
204 * Functions for Synchronization
205 *----------------------------------------------------------------------------*/
206struct _mcf_object_template {
207 MCF_DECLARE_OBJECT
208};
209
210static INLINE kal_bool mcf_is_object_valid(struct _mcf_object_template *object)
211{
212 kal_bool ret;
213
214 MCF_MUTEX_LOCK(mcf_enhmutex_g);
215 ret = MCF_IS_VALID_OBJECT_WO_LOCK(object)? KAL_TRUE:KAL_FALSE;
216 MCF_MUTEX_UNLOCK(mcf_enhmutex_g);
217
218 return ret;
219}
220
221#endif /* __INC_MCF_OBJECT_H */