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

📄 pc_locks.c

📁 嵌入式操作系统Nucleus Plus中使用的文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    and is the native handle type of your kernel environment.

****************************************************************************/

WAIT_HANDLE_TYPE pc_alloc_lock()                                     /*__fn__*/
{
WAIT_HANDLE_TYPE h;
static WAIT_HANDLE_TYPE current_h = 0;
    if (current_h < NUF_FIRST_EVENT_NUMBER)
        current_h = NUF_FIRST_EVENT_NUMBER;
    h = current_h;
    current_h += 1;
    return(h);
}

/******************************************************************************
    PC_WAIT_LOCK - Wait for a message on the lock channel.

 Description:
    The file system code needs to block on handle. Wait for a wakeup on the
    channel.
    
    
 Returns
    Nothing

****************************************************************************/

VOID pc_wait_lock(WAIT_HANDLE_TYPE wait_handle)                       /*__fn__*/
{
#if (PLUS)
UNSIGNED current_events;
UNSIGNED events;

    events =(UNSIGNED) ~0;
#else
unsigned current_events;
unsigned events;

    events =(unsigned) ~0;
#endif

    /* First release the File system semaphore */
    fs_release();
    /* Now block waiting for an evbent on the channel */
#if (PLUS)
    NU_Retrieve_Events(&NUFP_RTX_To_PLUS_Events[wait_handle], events,
                        NU_OR_CONSUME, &current_events, NU_SUSPEND);
#else
    NU_Wait_For_Events(wait_handle, NU_EVENT_OR_CONSUME, events, &current_events,
                       NU_WAIT_FOREVER);
#endif  /*  PLUS  */
    /* Now reclaim the file system semaphore */
    fs_reclaim();
}


/******************************************************************************
    PC_WAKE_LOCK - Wake up anyone waiting on the channel.

 Description:
        
    Decrement the semaphore at lock_handle. If any callers to 
    to pc_wake_lock(handle, YES) are waiting on the semaphore they will
    wake up if the sem count drops to zero.
    
 Returns
    Nothing

****************************************************************************/

VOID pc_wake_lock(WAIT_HANDLE_TYPE wait_handle)                      /*__fn__*/
{
#if (PLUS)
    /*  events is not used by PLUS. */
#else
unsigned    events;
    events =(unsigned) ~0;
#endif
    /* Signal tasks waiting in wait_lock */
#if (PLUS)
    NU_Set_Events(&NUFP_RTX_To_PLUS_Events[wait_handle],
                    (UNSIGNED) ~0, NU_OR);
#else
    NU_Set_Events(wait_handle, NU_EVENT_OR, events);
#endif  /*  PLUS  */
}



/* Fine grained multitasking control routines */
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !!!!!!!           These routines are portable          !!!!!!!!!!!!!!!!!!!
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/

IMPORT _PC_BDEVSW pc_bdevsw[];

/******************************************************************************
    PC_DRIVE_ENTER - An API call will use a drive. If exclusive is YES wait
                     for access and lock the drive.

 Description
    The file manager is entering code which will touch the drive at driveno.
    If exclusive is true we must wait until the the drive is unused by any other
    process. If the drive is being used exclusively by another process we
    must wait for the other process to release it.

 Returns
    Nothing
****************************************************************************/

VOID pc_drive_enter(COUNT driveno, BOOL exclusive)               /*__fn__*/
{
IMPORT LOCKOBJ drive_locks[];
    pc_generic_enter(&drive_locks[driveno], exclusive);
}

/******************************************************************************
    PC_DRIVE_EXIT  - An API call has completed and is returning. Wake up any
                     process waiting for the drive to become available.

 Description
    The file manager is leaving code which touched the drive at driveno.
    Makes sure any process waiting for drive is awake.

 Returns
    Nothing
****************************************************************************/

VOID  pc_drive_exit(COUNT driveno)                                  /*__fn__*/
{
IMPORT LOCKOBJ drive_locks[];
    pc_generic_exit(&drive_locks[driveno]);
}

/******************************************************************************
    PC_INODE_ENTER - The file system will be touching a file or directory
                     at pinode. If exclusive is YES lock the finode.

 Description
            The file system will be touching the file or directory at pinode
            If exclusive is true the file or directory will modified and
            must be locked. Otherwise we wait until no-one else has exclusive
            access and increase the open count.

 Returns
    Nothing
****************************************************************************/

VOID pc_inode_enter(FINODE *pinode, BOOL exclusive)               /*__fn__*/
{
    pc_generic_enter(&pinode->lock_object, exclusive);
}

/******************************************************************************
    PC_INODE_EXIT  - The directory entry at pinode is not being used. Wake up
                     anyone who might be waiting for it.
 Description

 Returns
    Nothing
****************************************************************************/

VOID pc_inode_exit(FINODE *pinode)                                  /*__fn__*/
{
    pc_generic_exit(&pinode->lock_object);
}

/******************************************************************************
    PC_FAT_ENTER -   An API call will use a FAT. If exclusive is YES wait
                     for access and lock the drive.

 Description
    The file manager is entering code which will touch the FAT at driveno.
    Wait until the the FAT is unused by any other process. And then claim it
    for the operation to be performed.

 Returns
    Nothing
****************************************************************************/

VOID pc_fat_enter(COUNT driveno)                                      /*__fn__*/
{
IMPORT LOCKOBJ fat_locks[];
    pc_generic_enter(&fat_locks[driveno], YES);
}

/******************************************************************************
    PC_FAT_EXIT    - An API call has completed using the FAT. Wake up any
                     process waiting for the FAT to become available.

 Description
    The file manager is leaving code which touched the FAT driveno.
    Makes sure any process waiting for FAT is awake.

 Returns
    Nothing
****************************************************************************/

VOID  pc_fat_exit(COUNT driveno)                                      /*__fn__*/
{
IMPORT LOCKOBJ fat_locks[];
    pc_generic_exit(&fat_locks[driveno]);
}

/******************************************************************************
    PC_DRIVE_IO_ENTER - We are calling the block io routines. Make sure a 
                        wait channel is established.

 Description
    The file manager is entering a block read/write call. Others may wait for the 
    IO to complete. This routine is called to establish a channel which 
    others may wait on.
    pc_drive_io_exit will wake the others up.

 Returns
    Nothing
****************************************************************************/

VOID pc_drive_io_enter(COUNT driveno)                               /*__fn__*/
{
IMPORT LOCKOBJ drive_io_locks[];
    /* convert driveno to lockno. When a non re-entrant driver shares more
       then one drive the locks will be the same for each drive */    
    pc_generic_enter(&drive_io_locks[pc_bdevsw[driveno].lock_no], YES);
}

/******************************************************************************
    PC_DRIVE_IO_EXIT -  IO has completed. Wake anyone who may be waiting for it.

 Description
    The file manager completed a read/write call. We call here wake anyone
    blocked.

 Returns
    Nothing
****************************************************************************/

VOID pc_drive_io_exit(COUNT driveno)                               /*__fn__*/
{
IMPORT LOCKOBJ drive_io_locks[];
    pc_generic_exit(&drive_io_locks[pc_bdevsw[driveno].lock_no]);
}

/******************************************************************************
    PC_GENERIC_ENTER -  Generic lock routine called by others.

 Description
    Two locking operations are provided. 
    One, exclusive access to the lock is needed
    Two, Non exclusive access is needed. But we must not return if someone
    has exclusive access.

    Two accomplish this we observe the following.
    For case one the access count of the lock must be zero before we may
    claim exclusive access.
    For case two the exclusive flag may not be set.
    We OR these conditions to get our wait condition. Then we up the access 
    count and set the exclusive flag if we are seeking exclusive access.
    
 Returns
    Nothing
****************************************************************************/

VOID pc_generic_enter(LOCKOBJ *plock, BOOL exclusive)               /*__fn__*/
{
BOOL lock_state;

    lock_state =  fs_lock_task();
    while (plock->exclusive || (plock->opencount && exclusive) )
    {
        pc_wait_lock(plock->wait_handle);
    }
    plock->exclusive = exclusive;
    plock->opencount += 1;
    fs_unlock_task(lock_state);
}

/******************************************************************************
    PC_GENERIC_EXIT  - Exit a lock

 Description
    We are releasing an object which we had already locked. We decrement the
    access count. If the Access count drops to zero we clear the exclusive flag.

    Then we issue a wakeup on the channel to see if any calls to 
    pc_generic_enter may return.
    
 Returns
    Nothing
****************************************************************************/

VOID pc_generic_exit(LOCKOBJ *plock)                                /*__fn__*/
{
BOOL lock_state;

    lock_state =  fs_lock_task();

    plock->opencount -= 1;
    if (!plock->opencount)
        plock->exclusive = NO;
    pc_wake_lock(plock->wait_handle);
    fs_unlock_task(lock_state);
    NU_Relinquish();
}

#endif /*  (LOCK_METHOD == 2) */
#endif /* NUM_USERS != 1 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -