📄 fifolock.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * fifolock.c (libtkse) * * FIFO lock * * The lock which does not consume OS resource though is inefficient in processing speed. * Waiting shall be in "FIFO" type. */#include <tk/tkernel.h>#include <sys/libs.h>#include <extension/errno.h>#include <extension/proctask.h>/* ------------------------------------------------------------------------ *//* * FIFO lock wait and wake-up */#define _wai_fflock tkse_wai_fflock#define _wup_fflock tkse_wup_fflock/* ------------------------------------------------------------------------ *//* * Lock the critical sections */#define C_LOCK_DEF#define C_LOCK() _lib_lock(_LL_MISC, TRUE)#define C_UNLOCK() _lib_unlock(_LL_MISC)/* ------------------------------------------------------------------------ *//* * Invoking task ID */#define gettid() tkse_get_tid()/* ------------------------------------------------------------------------ */#define TSD_FFL_TID_M1 (-1)/* * Initialize the lock */EXPORT void InitFFLock( FiFoLock *ff ){ QueInit(&ff->q); ff->tid = 0;}/* * Lock */EXPORT ER FFLock( FiFoLock *ff ){ FiFoLock my; ID tid; ER err; C_LOCK_DEF; if ( !_isUseMT() ) { return E_OK; } err = C_LOCK(); if ( err < E_OK ) { goto err_ret1; } tid = ff->tid; if ( tid == 0 ) { /* Obtain the lock */ ff->tid = TSD_FFL_TID_M1; } else { /* Register it with the lock wait queue */ QueInsert(&my.q, &ff->q); my.tid = gettid(); } C_UNLOCK(); while ( tid != 0 ) { /* Wait for the lock */ err = _wai_fflock(); if ( err < E_OK ) { if ( err != E_DISWAI ) { goto err_ret2; } continue; } err = C_LOCK(); if ( err < E_OK ) { goto err_ret2; } tid = my.tid; if ( tid == 0 ) { /* Obtain the lock */ ff->tid = TSD_FFL_TID_M1; /* Delete from the lock wait queue */ QueRemove(&my.q); } C_UNLOCK(); } return E_OK;err_ret2: /* (It is normally impossible to reach this point) * The correct behavior is not assured when a lock wait queue is operated without locking * "_LL_FIFOLOCK". Also, an exiting without removal of queue from the lock wait queue * leads to the destruction of queue. Therefore, the correct behavior is not assured in * this case,too. Stochastically, it is better to delete from queue. */ QueRemove(&my.q);err_ret1: return err;}/* * Unlock */EXPORT ER FFUnlock( FiFoLock *ff ){ ID tid; ER err; C_LOCK_DEF; if ( !_isUseMT() ) { return E_OK; } err = C_LOCK(); if ( err < E_OK ) { goto err_ret; } tid = ((FiFoLock*)ff->q.next)->tid; /* The wait task ID */ ((FiFoLock*)ff->q.next)->tid = 0; /* Release the lock */ C_UNLOCK(); if ( tid > 0 ) { /* Release the lock wait */ err = _wup_fflock(tid); if ( err < E_OK ) { return err; } } return E_OK;err_ret: return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -