📄 pc_locks.c
字号:
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, ¤t_events, NU_SUSPEND);
#else
NU_Wait_For_Events(wait_handle, NU_EVENT_OR_CONSUME, events, ¤t_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 + -