📄 fdi_mutx.c
字号:
/* ###########################################################################
### Intel Confidential
### Copyright (c) Intel Corporation 1995-2002
### All Rights Reserved.
### -------------------------------------------------------------------------
### Project: Flash Data Integrator
###
### Module: Mutex.c - This file impliments a VXWorks like mutex semaphore
### using binary semaphores.
###
### $Archive: /FDI/SRC/FDI/fdi_mutx.c $
### $Revision: 64 $
### $Date: 10/15/04 12:21p $
### $Author: Wtiso $
### $NoKeywords $
########################################################################### */
/*
*****************************************************************
* NOTICE OF LICENSE AGREEMENT
*
* This code is provided by Intel Corp., and the use is governed
* under the terms of a license agreement. See license agreement
* for complete terms of license.
*
* YOU MAY ONLY USE THE SOFTWARE WITH INTEL FLASH PRODUCTS. YOUR
* USE OF THE SOFTWARE WITH ANY OTHER FLASH PRODUCTS IS EXPRESSLY
* PROHIBITED UNLESS AND UNTIL YOU APPLY FOR, AND ARE GRANTED IN
* INTEL'S SOLE DISCRETION, A SEPARATE WRITTEN SOFTWARE LICENSE
* FROM INTEL LICENSING ANY SUCH USE.
*****************************************************************
*/
/* E.5.0.690 Begin */
/*remove #include "fdi_type.h" */
/*#include "fdi_type.h"*/
/* E.5.0.690 End */
#include "fdi_que.h"
#ifdef CUSTOM_SEM_MTX
/*#define DEBUG_MTX*/ /* uncomment this to have logmsg's printed */
#ifdef DEBUG_MTX
#include "logLib.h"
#endif
#ifdef TEST_MSGS
#include "logLib.h"
#endif
/*
#define MAX_QUEUE_ITEMS ( (FDI_QUEUE_SIZE - sizeof(Q_DESCRIPTOR) - \
sizeof(Q_PRIORITY_HEADER)) /\
(sizeof(COMMAND) + \
sizeof(Q_ITEM_INFO)) )
*/
/* E.5.0.690 Begin */
/*move MAX_QUEUE_ITEMS to fdi_que.h */
/* E.5.0.690 End */
#define MAX_MTX_ID (Q_STATIC_SEM_CNT+MAX_QUEUE_ITEMS+1)
DWORD Max_Mtx_Id = MAX_MTX_ID;
extern SEM_MTX_ID Sem_Mtx_Create(void);
extern ERR_CODE Sem_Mtx_Destroy(SEM_MTX_ID semId);
extern ERR_CODE Sem_Mtx_Post(SEM_MTX_ID semId);
extern ERR_CODE Sem_Mtx_Try_Wait(SEM_MTX_ID semId);
extern ERR_CODE Sem_Mtx_Wait(SEM_MTX_ID semId);
SEM_MTX Mtx_Array[MAX_MTX_ID];
SEM_ID SEM_Mutex_Space;
/*
########################################################################
### Sem_Mtx_Init()
###
### DESCRIPTION: Inits. the Mutex data space and control semaphore.
###
### PARAMETERS:
### IN: None.
### OUT: None.
###
### RETURNS: None.
###
*/
ERR_CODE
Sem_Mtx_Init(void)
{
WORD cnt;
#ifdef DEBUG_MTX
logMsg("Init Sem!\n", 0, 0, 0, 0, 0, 0);
#endif
/* Initialize Mtx_Array structure */
for (cnt = 0; cnt < MAX_MTX_ID; cnt++)
{
Mtx_Array[cnt].current_task_id = 0;
Mtx_Array[cnt].wait_count = 0;
/* E.5.5.5.987 Begin */
/* E.5.5.5.987 End */
Mtx_Array[cnt].binary_sem = 0;
/* E.5.5.5.987 Begin */
/* E.5.5.5.987 End */
Mtx_Array[cnt].used = 0;
}
/* Create SEM_Mutex_Space, verify it exists, and post it */
#if(SEM_CREATE_DESTROY == TRUE)
if((SEM_Mutex_Space = SEM_BIN_CREATE()) == SEM_NULL)
#else /* SEM_CREATE_DESTROY */
if(SEM_Mutex_Space == SEM_NULL)
#endif /* SEM_CREATE_DESTROY */
return(ERR_INIT);
SEM_POST(SEM_Mutex_Space);
return(ERR_NONE);
}
/*
########################################################################
### Sem_Mtx_Create()
###
### DESCRIPTION: Creates a Mutex semaphore using a binary Semaphore.
###
### PARAMETERS:
### IN: none.
### OUT: none.
###
### RETURNS: Pointer to Mutex Semaphore Structure SEM_MTX or Null.
###
*/
SEM_MTX_ID
Sem_Mtx_Create(void)
{
WORD cnt;
/* protect Mtx semaphores space */
SEM_WAIT(SEM_Mutex_Space);
/* find an empty Mutex semaphore */
for (cnt = 0; (cnt < MAX_MTX_ID) && Mtx_Array[cnt].used; cnt++)
{}
if (cnt >= MAX_MTX_ID)
{
#ifdef DEBUG_MTX
logMsg("In the call to Sem_Mtx_Create(), No unused Mtx space was"
" found!\n", 0, 0, 0, 0, 0, 0);
#endif
SEM_POST(SEM_Mutex_Space);
return 0;
}
#if(SEM_CREATE_DESTROY == TRUE)
if ((Mtx_Array[cnt].binary_sem = SEM_BIN_CREATE()) != SEM_NULL)
{
#else /* SEM_CREATE_DESTROY */
if (Mtx_Array[cnt].binary_sem != SEM_NULL)
{
#endif /* SEM_CREATE_DESTROY */
SEM_POST(Mtx_Array[cnt].binary_sem);
/* init. the rest of the structure */
/* E.5.5.5.985 Begin */
/* Needs to be changed if 0 is a valid task id */
Mtx_Array[cnt].current_task_id = 0;
/* E.5.5.5.985 End */
Mtx_Array[cnt].wait_count = 0;
Mtx_Array[cnt].used = 1;
}
#ifdef DEBUG_MTX
else
/* if the binary semaphore could not be created Tell the world */
logMsg("In the call to Sem_Mtx_Create(), the binary semaphore could"
" not be created!\n", 0, 0, 0, 0, 0, 0);
#endif
/* let other calles to this function go */
SEM_POST(SEM_Mutex_Space);
/*
* return a pointer to the Mutex structrue or zero if it could
* not be created
*/
return (Mtx_Array[cnt].binary_sem != SEM_NULL) ? &Mtx_Array[cnt] : SEM_NULL;
}
/*
########################################################################
### Sem_Mtx_Destroy()
###
### DESCRIPTION: Closes the binary semaphore and frees the Mutex structures
### space.
###
### PARAMETERS:
### IN: semId, a pointer to the Mutex data structure.
### OUT: ERR_CODE
###
### RETURNS: ERR_NONE or ERR_SYSTEM.
###
*/
ERR_CODE
Sem_Mtx_Destroy(SEM_MTX_ID semId)
{
/* E.5.5.5.987 Begin */
ERR_CODE status = ERR_NONE;
/* E.5.5.5.987 End */
if ((semId == SEM_NULL) || !semId->used)
{
#ifdef DEBUG_MTX
logMsg("In the call to Sem_Mtx_Destroy(%X), the semId given is "
"invalid!\n", (int)semId, 0, 0, 0, 0, 0);
#endif
status = ERR_SYSTEM;
}
else
{
/* reset the data structure */
semId->current_task_id = 0;
semId->wait_count = 0;
semId->used = 0;
/* each pended task will be unpended with an error */
/* E.5.5.5.987 Begin */
#if(SEM_CREATE_DESTROY == TRUE)
/* E.5.5.5.987 End */
status = (ERR_CODE)SEM_DESTROY(semId->binary_sem);
semId->binary_sem = 0;
/* E.5.5.5.987 Begin */
#endif /* SEM_CREATE_DESTROY */
/* E.5.5.5.987 End */
}
#if(SEM_CREATE_DESTROY == FALSE)
#ifdef TEST_MSGS
logMsg("Error: Call to Sem_Mtx_Destroy not allowed (%d)\n",
(int)semId, 0, 0, 0, 0, 0);
#endif
#endif /* !SEM_CREATE_DESTROY */
return status;
}
/*
########################################################################
### Sem_Mtx_Post()
###
### DESCRIPTION: Preforms a Mutex post operation.
### - checks to see if this task already has the semaphore
### - compare calling tasks ID with current_task_ID value.
### - if it does compare
### {
### - decrement the wait_count
### - if wait_count is zero:
### {
### - zero current_task_ID field
### - post to binary_sem
### - set interrupts on
### - return result from post to binary_sem
### }
### - set interrupts on
### - return ERR_NONE
### }
### - else
### }
### - set interrupts on
### - return ERR_SYSTEM
### }
###
### PARAMETERS:
### IN: semId, a pointer to the Mutex data structure.
### OUT: ERR_CODE
###
### RETURNS: ERR_NONE, ERR_SYSTEM
###
*/
ERR_CODE
Sem_Mtx_Post(SEM_MTX_ID semId)
{
ERR_CODE status = ERR_NONE;
int task_Id = Current_Task_Pointer();
if ((semId == SEM_NULL) || !semId->used)
{
status = ERR_SYSTEM;
#ifdef DEBUG_MTX
logMsg("Call to Sem_Mtx_Post(%X) with invalid Id, "
"semId->used=%d\n", (int)semId, (semId == 0) ? 0 : semId->used,
0, 0, 0, 0);
#endif
}
else
{
/* do we own it? */
if (task_Id == semId->current_task_id)
{
/* is this the last Post to the first Wait */
if (--(semId->wait_count) == 0)
{
/* reset the task_id field */
semId->current_task_id = 0;
status = (ERR_CODE)SEM_POST(semId->binary_sem);
/* if our Post was in error tell the world!*/
if (status != ERR_NONE)
{
status = ERR_SYSTEM;
#ifdef DEBUG_MTX
logMsg("Call to Sem_Mtx_Post() produced an error when "
"calling SEM_POST semId=%d\n", (int)semId, 0, 0, 0, 0, 0);
#endif
}
}
}
else
{
status = ERR_SYSTEM;
}
}
return status;
}
/*
########################################################################
### Sem_Mtx_Try_Wait()
###
### DESCRIPTION: Preforms a Mutex Try Wait operation.
### - if task does not own the semaphore.
### {
### - try to lock, but do not pend on binary_sem
### - set the current_task_ID
### }
### - set interrupts on
### - return
###
### PARAMETERS:
### IN: semId, a pointer to the Mutex data structure.
### OUT: ERR_CODE
###
### RETURNS: ERR_NONE, or ERR_SYSTEM
###
*/
ERR_CODE
Sem_Mtx_Try_Wait(SEM_MTX_ID semId)
{
ERR_CODE status;
int task_Id = Current_Task_Pointer();
if ((semId == SEM_NULL) || !semId->used)
{
status = ERR_SYSTEM;
#ifdef DEBUG_MTX
logMsg("Call to Sem_Mtx_Try_Wait(%X) with invalid Id,"
" semId->used=%d\n", (int)semId, (semId == 0) ? 0 : semId->used,
0, 0, 0, 0);
#endif
}
else
{
/* do we own it? */
if (task_Id == semId->current_task_id)
{
semId->wait_count++;
#ifdef DEBUG_MTX
if (semId->wait_count == 0)
logMsg("Call to Sem_Mtx_Try_Wait(%X) produced an over flow on "
"wait_count @#@#.\n", (int)semId, 0, 0, 0, 0, 0);
#endif
status = ERR_NONE;
}
else
{
/* if we do not own it we should try to lock the binary semaphore, and own it. */
if ((status = (ERR_CODE)SEM_TRY_WAIT(semId->binary_sem)) == ERR_NONE)
{
/* it's our's now!*/
semId->current_task_id = task_Id;
semId->wait_count=1;
}
else
{
status = ERR_SYSTEM;
#ifdef DEBUG_MTX
logMsg("Call to Sem_Mtx_Try_Wait(%X) produced an error when calling"
" SEM_WAIT\n", (int)semId, 0, 0, 0, 0, 0);
#endif
}
}
}
return status;
}
/*
########################################################################
### Sem_Mtx_Wait()
###
### DESCRIPTION: Preforms a Mutex Wait operation.
### - if task already owns the semaphore.
### - increment wait_count
### - else
### {
### - pend on binary_sem
### - increment wait_count
### - set the current_task_ID
### }
### - set interrupts on
### - return
###
### PARAMETERS:
### IN: semId, a pointer to the Mutex data structure.
### OUT: ERR_CODE
###
### RETURNS: ERR_NONE, ERR_SYSTEM
###
*/
ERR_CODE
Sem_Mtx_Wait(SEM_MTX_ID semId)
{
ERR_CODE status;
int task_Id = Current_Task_Pointer();
if ((semId == SEM_NULL) || !semId->used)
{
status = ERR_SYSTEM;
#ifdef DEBUG_MTX
logMsg("Call to Sem_Mtx_Wait(%X) with invalid Id,"
" semId->used=%d\n", (int)semId, (semId == 0) ? 0 : semId->used,
0, 0, 0, 0);
#endif
}
else
{
/* do we own it? */
if (task_Id == semId->current_task_id)
{
semId->wait_count++;
#ifdef DEBUG_MTX
if (semId->wait_count == 0)
logMsg("Call to Sem_Mtx_Wait(%X) produced an over flow on "
"wait_count @#@#.\n", (int)semId, 0, 0, 0, 0, 0);
#endif
status = ERR_NONE;
}
else
{
/* if we do not own it we should wait on the binary semaphore. */
if ((status = (ERR_CODE)SEM_WAIT(semId->binary_sem)) == ERR_NONE)
{
/* it's our's now!*/
semId->current_task_id = task_Id;
semId->wait_count=1;
}
else
{
status = ERR_SYSTEM;
#ifdef DEBUG_MTX
logMsg("Call to Sem_Mtx_Wait(%X) produced an error when calling"
" SEM_WAIT\n", (int)semId, 0, 0, 0, 0, 0);
#endif
}
}
}
return status;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -