⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdi_mutx.c

📁 FDI Intel开发的FLASH文件系统,功能很强大
💻 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 + -