blob: d7eeea03932b1ba2a6eb24a6881c4ff424e1413c [file] [log] [blame]
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2018
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*******************************************************************************
* Filename:
* ---------
* mcf_object.h
*
* Project:
* --------
* UMOLYA
*
* Description:
* ------------
* Helper for object management and synchronization.
*
* Author:
* -------
* -------
*
*==============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* removed!
*
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*==============================================================================
*******************************************************************************/
#ifndef __INC_MCF_OBJECT_H
#define __INC_MCF_OBJECT_H
#include "kal_public_api.h"
#include "mcf_struct.h"
struct _mcf_object_template;
extern kal_enhmutexid mcf_enhmutex_g;
static INLINE kal_bool mcf_is_object_valid(struct _mcf_object_template *object);
/*------------------------------------------------------------------------------
* Data structure defintion.
*----------------------------------------------------------------------------*/
#define MCF_MUTEX_LOCK(_lock) \
if (kal_query_systemInit() == KAL_FALSE) { \
kal_take_enh_mutex(_lock); \
}
#define MCF_MUTEX_UNLOCK(_lock) \
if (kal_query_systemInit() == KAL_FALSE) { \
kal_give_enh_mutex(_lock); \
}
#define MCF_IS_VALID_OBJECT_WO_LOCK(_object) \
((_object) != NULL && (_object)->ref_count == 2)
#define MCF_IS_VALID_OBJECT(_object) \
mcf_is_object_valid((struct _mcf_object_template *)_object)
#define MCF_R_LOCK_OBJECT(_object, _lock) \
MCF_MUTEX_LOCK(_lock); \
if (MCF_IS_VALID_OBJECT_WO_LOCK(_object) && ((_object)->writer_cnt == 0)) { \
++((_object)->reader_cnt); \
} else { \
(_object) = NULL; \
} \
MCF_MUTEX_UNLOCK(_lock)
#define MCF_R_UNLOCK_OBJECT(_object, _lock) \
ASSERT((_object)); \
MCF_MUTEX_LOCK(_lock); \
ASSERT((_object)->reader_cnt > 0); \
--((_object)->reader_cnt); \
MCF_MUTEX_UNLOCK(_lock)
#define MCF_INIT_OBJECT_BEGIN(_object, _lock) \
ASSERT(_object); \
MCF_MUTEX_LOCK(_lock); \
ASSERT((_object)->ref_count == 0); \
(_object)->ref_count = 1; \
MCF_MUTEX_UNLOCK(_lock)
#define MCF_INIT_OBJECT_END(_object, _lock) \
ASSERT(_object); \
MCF_MUTEX_LOCK(_lock); \
ASSERT(_object->ref_count == 1); \
(_object)->ref_count = 2; \
(_object)->reader_cnt = 0; \
(_object)->writer_cnt = 0; \
MCF_MUTEX_UNLOCK(_lock)
#define MCF_DEINIT_OBJECT_BEGIN(_object, _lock) \
MCF_MUTEX_LOCK(_lock); \
if (MCF_IS_VALID_OBJECT_WO_LOCK(_object)) { \
--((_object)->ref_count); \
while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
MCF_MUTEX_UNLOCK(_lock); \
kal_sleep_task(MCF_DEL_OBJECT_SLEEP_TICKS); \
MCF_MUTEX_LOCK(_lock); \
} \
ASSERT((_object)->ref_count == 1); \
} else { \
(_object) = NULL; \
} \
MCF_MUTEX_UNLOCK(_lock)
#define MCF_DEINIT_OBJECT_END(_object, _lock) \
MCF_MUTEX_LOCK(_lock); \
ASSERT((_object)->ref_count == 1); \
ASSERT((_object)->reader_cnt == 0); \
ASSERT((_object)->writer_cnt == 0); \
(_object)->ref_count = 0; \
MCF_MUTEX_UNLOCK(_lock)
#define MCF_W_LOCK_OBJECT(_object, _lock) \
MCF_MUTEX_LOCK(_lock); \
if (MCF_IS_VALID_OBJECT_WO_LOCK(_object)) { \
while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
MCF_MUTEX_UNLOCK(_lock); \
kal_sleep_task(MCF_W_LOCK_OBJECT_SLEEP_TICKS); \
MCF_MUTEX_LOCK(_lock); \
} \
if (MCF_IS_VALID_OBJECT_WO_LOCK(_object)) { \
++((_object)->writer_cnt); \
} else { \
(_object) = NULL; \
MCF_MUTEX_UNLOCK(_lock); \
} \
} else { \
(_object) = NULL; \
MCF_MUTEX_UNLOCK(_lock); \
}
#define MCF_W_UNLOCK_OBJECT(_object, _lock) \
ASSERT((_object)); \
ASSERT((_object)->writer_cnt == 1); \
--((_object)->writer_cnt); \
MCF_MUTEX_UNLOCK(_lock)
/* Safely convert between Read & Write lock at the same time. */
#define MCF_R_TO_W_LOCK_OBJECT(_object, _lock) \
MCF_MUTEX_LOCK(_lock); \
if (MCF_IS_VALID_OBJECT_WO_LOCK(_object)) { \
ASSERT((_object)->reader_cnt > 0); \
--((_object)->reader_cnt); \
while ((_object)->reader_cnt != 0 || (_object)->writer_cnt != 0) { \
MCF_MUTEX_UNLOCK(_lock); \
kal_sleep_task(MCF_W_LOCK_OBJECT_SLEEP_TICKS); \
MCF_MUTEX_LOCK(_lock); \
} \
if (MCF_IS_VALID_OBJECT_WO_LOCK(_object)) { \
++((_object)->writer_cnt); \
} else { \
(_object) = NULL; \
MCF_MUTEX_UNLOCK(_lock); \
} \
} else { \
(_object) = NULL; \
MCF_MUTEX_UNLOCK(_lock); \
}
#define MCF_W_TO_R_LOCK_OBJECT(_object, _lock) \
ASSERT((_object)); \
ASSERT((_object)->reader_cnt == 0); \
ASSERT((_object)->writer_cnt == 1); \
--((_object)->writer_cnt); \
++((_object)->reader_cnt); \
MCF_MUTEX_UNLOCK(_lock)
/*------------------------------------------------------------------------------
* Functions for Synchronization
*----------------------------------------------------------------------------*/
struct _mcf_object_template {
MCF_DECLARE_OBJECT
};
static INLINE kal_bool mcf_is_object_valid(struct _mcf_object_template *object)
{
kal_bool ret;
MCF_MUTEX_LOCK(mcf_enhmutex_g);
ret = MCF_IS_VALID_OBJECT_WO_LOCK(object)? KAL_TRUE:KAL_FALSE;
MCF_MUTEX_UNLOCK(mcf_enhmutex_g);
return ret;
}
#endif /* __INC_MCF_OBJECT_H */