flag.c

来自「一个操作系统源代码 用于嵌入式设备 在Vc++环境下仿真 成功移植到多款处理器上」· C语言 代码 · 共 360 行

C
360
字号
////////////////////////////////////////////////////////////////////////////////
// File Name	:       Flag.c
// Create Date	:       2001-6-22 pm 01:52:44
// Written by	:		longn_qi
// Decription	:
//------------------------------------------------------------------------------
// Copyright:   CNASIC Proprietary Material
//              Copyright (c) 2001, All Rights Reserved By:
//              National ASIC System Engineering Research Center (CNASIC) 
//				SouthEast University
//
//              DISTRIBUTION PROHIBITED without written authorization from CNASIC
//------------------------------------------------------------------------------
// Modification History
//
// 2001/10/31	by longn_qi		Add function "iset_flg" and revise.
//
////////////////////////////////////////////////////////////////////////////////
/* System and Standard Header */
#include <sys\sysdebug.h>
#include <kernel\ros33\itron.h>
#include <kernel\ros33\ros33.h>
#define _SIZE_T_DEFINED

#include <windows.h>

/* Application Header */
#include "internal.h"

//--- macro and definition -----------------------------------------------------
//--- static variables ---------------------------------------------------------
//--- external variables -------------------------------------------------------
//--- shared variables ---------------------------------------------------------
//--- static functions ---------------------------------------------------------
//--- external functions -------------------------------------------------------

/* Function Definition */
//------------------------------------------------------------------------------
// Function name  : set_flg
// Description    : 
// Return type    : ER
// Argument       : ID flgid
// Argument       : UINT setptn
// Remarks        : 
// So also        : 
//------------------------------------------------------------------------------
ER set_flg( ID flgid, 
			UINT setptn )
{
    ID idTask;
    
#if ENABLE_SYSCALL_STATISTIC	
	gSyscallSta[19].sta++;
#endif

	if( g_ubSysStat == TSS_LOC )
        return E_CTX;

    if( flgid<=0 )
        return E_ID;

    if( flgid>FLG_NUM )
        return E_NOEXS;

    aFcb[flgid].uhFlgPtn |= setptn;

#if ENABLE_SYSFLG_STATISTIC	
	gSysFlgSta[flgid]++;
#endif

    if( !aFcb[flgid].idTask )
        return E_OK;

    ENTER_CS

	if( aFcb[flgid].bWaiMode & TWF_ORW )
    {
        if( !( aFcb[flgid].uhWaiPtn & aFcb[flgid].uhFlgPtn ) )
        {
			LEAVE_CS
			return E_OK;
		}
    }
    else
    {
        if( ( aFcb[flgid].uhWaiPtn & aFcb[flgid].uhFlgPtn) != aFcb[flgid].uhWaiPtn )
		{
			LEAVE_CS
			return E_OK;
		}
    }

    // flag condition matching case
    idTask = aFcb[flgid].idTask;
    aFcb[flgid].idTask = 0;
//	flgdbgprintf("clear eventflag");
    aTcb[idTask].ubStatus &= ~TTS_WAI;        // clear wait
    aTcb[idTask].ubWaitStat &= ~TTW_FLG;      // clear flag wait
    aTcb[idTask].vwWaitRet = E_OK;
    *aTcb[idTask].pFlgptn = aFcb[flgid].uhFlgPtn; // set return value (flag pattern)

    if( aFcb[flgid].bWaiMode & TWF_CLR )
        aFcb[flgid].uhFlgPtn = 0;            // clear flag

    /* clear time out task link */
    AppendTaskToReadyQueue( idTask );
//	flgdbgoutput( "task %d ready", aReadyQueue[1].idFirstTask );
    
	LEAVE_CS

	ContextSwitch( );

    return E_OK;
}

//------------------------------------------------------------------------------
// Function name  : clr_flg
// Description    : 
// Return type    : ER
// Argument       : ID flgid
// Argument       : UINT clrptn
// Remarks        : 
// So also        : 
//------------------------------------------------------------------------------
ER clr_flg( ID flgid, 
			UINT clrptn )
{
#if ENABLE_SYSCALL_STATISTIC	
	gSyscallSta[20].sta++;
#endif

    if( flgid<=0 )
        return E_ID;
    
    if( flgid>FLG_NUM )
        return E_NOEXS;
	
	ENTER_CS
    aFcb[flgid].uhFlgPtn &= clrptn;
	LEAVE_CS
    
    return E_OK;
}
    
//------------------------------------------------------------------------------
// Function name  : twai_flg
// Description    :
// Return type    : ER
// Argument       : UINT *p_flgptn
// Argument       : ID flgid
// Argument       : UINT waiptn
// Argument       : UINT wfmode
// Argument       : TMO tmout
// Remarks        :
// So also        :
//------------------------------------------------------------------------------
ER twai_flg(	UINT *p_flgptn, 
				ID flgid, 
				UINT waiptn, 
				UINT wfmode, 
				TMO tmout )
{
#if ENABLE_SYSCALL_STATISTIC	
	gSyscallSta[23].sta++;
#endif

    if( g_ubSysStat & TSS_DDSP )
        return E_CTX;

    if( flgid<=0 )
        return E_ID;
    
    if( flgid>FLG_NUM )
        return E_NOEXS;
    
    if( !waiptn || wfmode>3 || tmout<=-2 )
        return E_PAR;

    //  wait single object
    if( aFcb[flgid].idTask )
        return E_OBJ;

	ENTER_CS

    aFcb[flgid].bWaiMode = (B)wfmode;
    aFcb[flgid].uhWaiPtn = (UH)waiptn;

    *p_flgptn = aFcb[flgid].uhFlgPtn;
    
    if( wfmode & TWF_ORW )
    {
        if( waiptn & aFcb[flgid].uhFlgPtn )
        {
//            if( aFcb[flgid].bWaiMode & TWF_CLR )
//                aFcb[flgid].uhFlgPtn = 0;
			
			aFcb[flgid].uhFlgPtn &= (~waiptn);
			
			LEAVE_CS
			return E_OK;
        }
    }
    else
    {
        if( ( aFcb[flgid].uhWaiPtn & aFcb[flgid].uhFlgPtn ) == aFcb[flgid].uhWaiPtn )
        {
//            if( aFcb[flgid].bWaiMode & TWF_CLR )
//                aFcb[flgid].uhFlgPtn = 0;

			aFcb[flgid].uhFlgPtn &= (~waiptn);
            
			LEAVE_CS
			return E_OK;
        }
    }

    if( tmout == TMO_POL )
    {
#if ENABLE_SYSCALL_STATISTIC	
		gSyscallSta[23].sta--;
		gSyscallSta[22].sta++;
#endif
		LEAVE_CS
		return E_TMOUT;
	}

    /* wait flag pattern */
    aFcb[flgid].idTask = idCurTask;
//	flgdbgprintf("wait eventflag");

    aTcb[idCurTask].ubStatus |= TTS_WAI;  
    aTcb[idCurTask].ubWaitStat |= TTW_FLG;
    aTcb[idCurTask].pFlgptn = p_flgptn;

    RemoveTaskFromReadyQueue( aTcb[idCurTask].bPriority, idCurTask );
    if( tmout!=TMO_FEVR )
	{
#if ENABLE_SYSCALL_STATISTIC	
		gSyscallSta[23].sta--;
		gSyscallSta[21].sta++;
#endif
        SetTimer(	hwndClient, 
					idCurTask, 
					tmout, 
					( TIMERPROC ) PollingTimerHandler );
	}

    LEAVE_CS

	ContextSwitch( );

	aFcb[flgid].idTask = 0;

    return aTcb[idCurTask].vwWaitRet;
}

//------------------------------------------------------------------------------
// Function name  : iset_flg
// Description    : 
// Return type    : ER
// Argument       : ID flgid
// Argument       : UINT setptn
// Remarks        : 
// So also        : 
//------------------------------------------------------------------------------
ER iset_flg( ID flgid, UINT setptn )
{
	ID	idTask, idTemp;
	DWORD	temp;

#if ENABLE_SYSCALL_STATISTIC	
	gSyscallSta[56].sta++;
#endif

	if( g_ubSysStat == TSS_LOC )
        return E_CTX;

    if( flgid<=0 )
        return E_ID;

    if( flgid>FLG_NUM )
        return E_NOEXS;
	
	WaitForSingleObject( hEnEventInt, INFINITE );
	
	ENTER_CS

	temp = SuspendThread( aTcb[idCurTask].hThread );
    idTemp = idCurTask;
	flgdbgprintf( "INT!" );
	flgdbgoutput( "Suspend task(i): %d", idTemp );
	flgdbgoutput( "Suspend result(i): %ld", temp );
	if( temp == 1 )
		ResumeThread( aTcb[idTemp].hThread );

	aFcb[flgid].uhFlgPtn |= setptn;

#if ENABLE_SYSFLG_STATISTIC	
	gSysFlgSta[flgid]++;
#endif

    if( !aFcb[flgid].idTask )
        goto Restore_Handle;

    if( aFcb[flgid].bWaiMode & TWF_ORW )
    {
        if( !( aFcb[flgid].uhWaiPtn & aFcb[flgid].uhFlgPtn ) )
            goto Restore_Handle;
    }
    else
    {
        if( ( aFcb[flgid].uhWaiPtn & aFcb[flgid].uhFlgPtn) != aFcb[flgid].uhWaiPtn )
            goto Restore_Handle;
    }

	idCurTask = 0;

	// flag condition matching case
    idTask = aFcb[flgid].idTask;
    aFcb[flgid].idTask = 0;
    aTcb[idTask].ubStatus &= ~TTS_WAI;        // clear wait
    aTcb[idTask].ubWaitStat &= ~TTW_FLG;      // clear flag wait
    aTcb[idTask].vwWaitRet = E_OK;
    *aTcb[idTask].pFlgptn = aFcb[flgid].uhFlgPtn; // set return value (flag pattern)

//    if( aFcb[flgid].bWaiMode & TWF_CLR )
//        aFcb[flgid].uhFlgPtn = 0;            // clear flag
	aFcb[flgid].uhFlgPtn &= (~setptn);

    /* clear time out task link */
    AppendTaskToReadyQueue( idTask );
	
	LEAVE_CS

    if( ContextSwitch( ) != E_OK )
	{
		idCurTask = idTemp;
		flgdbgprintf("No Switch!");
		flgdbgoutput( "Resume task(i): %d", idTemp );
		temp = ResumeThread( aTcb[idTemp].hThread );
		flgdbgoutput( "Resume result(i): %ld", temp );
	}

	return E_OK;

Restore_Handle:
	flgdbgprintf("No Switch!");
	flgdbgoutput( "Resume task(i): %d", idTemp );
	temp = ResumeThread( aTcb[idTemp].hThread );
	flgdbgoutput( "Resume result(i): %ld", temp );
//	if( temp == 2 )
//		ResumeThread( aTcb[idTemp].hThread );
	LEAVE_CS

	return E_OK;
}


//----------------------------- The End of the File ----------------------------

⌨️ 快捷键说明

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