📄 win_ss.c
字号:
*
*/
#ifdef ANSI
DWORD WINAPI winTmrHdlr
(
void *parm /* unused */
)
#else
DWORD WINAPI winTmrHdlr(tEnt)
void *parm; /* unused */
#endif
{
/*
struct timespec ts;
*/
TRC0(mtTmrHdlr);
UNUSED(parm);
/* set up parameter to nanosleep() for 100 milliseconds */
/*
ts.tv_sec = 0;
ts.tv_nsec = WIN_TICK_CNT;
*/
/* infinite loop */
for ( ; ; )
{
/* sleep for 100 milliseconds */
Sleep(WIN_TICK_CNT);
/* update tick count */
osCp.dep.sysTicks++;
/* call the common timer tick handler */
cmPrcTmr(&osCp.dep.tmrTqCp, osCp.dep.tmrTq, winTimeout);
}
/* will not reach here */
}
/*
*
* Fun: mtTimeout
*
* Desc: Process timer event. Called from the common timer
* code when a timeout occurs.
*
* Ret: Void
*
* Notes:
*
* File: win_ss.c
*
*/
#ifdef ANSI
PUBLIC Void winTimeout
(
PTR tCb, /* control block */
S16 evnt /* event */
)
#else
PUBLIC Void winTimeout(tCb, evnt)
PTR tCb; /* control block */
S16 evnt; /* event */
#endif
{
Buffer *mBuf;
SsMsgInfo *mInfo;
CmTmrArg arg;
SsTmrEntry *tEnt;
SsTTskEntry *tTsk;
SsIdx idx;
S16 ret;
MsgLen qLen;
TRC0(winTimeout);
/* get the timer entry */
tEnt = (SsTmrEntry *) tCb;
/* if the timer was deleted, this will be NULL, so drop it */
if ( tEnt == NULL )
{
RETVOID;
}
/* lock the timer table */
if ( SLock(&osCp.tmrTblLock) != ROK )
{
#if (ERRCLASS & ERRCLS_DEBUG)
WINLOGERROR(ERRCLS_DEBUG, EMT013, ERRZERO, "Could not lock timer table");
#endif
RETVOID;
}
/* Hmmmm, the timer might have been deleted while we've been
* working at getting here, so we just skip this.
*/
if ( tEnt->used == FALSE )
{
SUnlock(&osCp.tmrTblLock);
RETVOID;
}
/* Set up and send a timer message to the destination tasks'
* demand queue.
*/
if ( SGetMsg(SS_DFLT_REGION, SS_DFLT_POOL, &mBuf) != ROK )
{
SUnlock(&osCp.tmrTblLock);
#if (ERRCLASS & ERRCLS_DEBUG)
WINLOGERROR(ERRCLS_DEBUG, EMT014, ERRZERO, "Could not get message");
#endif
RETVOID;
}
mInfo = (SsMsgInfo *)mBuf->b_rptr;
mInfo->eventInfo.event = SS_EVNT_TIMER;
mInfo->eventInfo.u.tmr.tmrIdx = tEnt->tmrId;
mInfo->pst.dstEnt = tEnt->ownerEnt;
mInfo->pst.dstInst = tEnt->ownerInst;
mInfo->pst.srcEnt = tEnt->ownerEnt;
mInfo->pst.srcInst = tEnt->ownerInst;
mInfo->pst.dstProcId = SFndProcId();
mInfo->pst.srcProcId = SFndProcId();
mInfo->pst.selector = SEL_LC_NEW;
mInfo->pst.region = DFLT_REGION;
mInfo->pst.pool = DFLT_POOL;
mInfo->pst.prior = PRIOR0;
mInfo->pst.route = RTESPEC;
mInfo->pst.event = 0;
/* get a semaphore for the TAPA task table */
SS_ACQUIRE_SEMA(&osCp.tTskTblSem, ret);
if ( ret != ROK )
{
SPutMsg(mBuf);
SUnlock(&osCp.tmrTblLock);
#if (ERRCLASS & ERRCLS_DEBUG)
WINLOGERROR(ERRCLS_DEBUG, EMT015, ret, "Could not lock TAPA task table");
#endif
RETVOID;
}
/* find the owner TAPA task */
idx = osCp.tTskIds[tEnt->ownerEnt][tEnt->ownerInst];
if ( idx == SS_TSKNC )
{
SS_RELEASE_SEMA(&osCp.tTskTblSem);
SPutMsg(mBuf);
SUnlock(&osCp.tmrTblLock);
RETVOID;
}
/* ensure that the TAPA task is hale and hearty */
tTsk = &osCp.tTskTbl[idx];
if ( !tTsk->used )
{
SS_RELEASE_SEMA(&osCp.tTskTblSem);
SPutMsg(mBuf);
SUnlock(&osCp.tmrTblLock);
RETVOID;
}
/* modify by shang 2002-7-19 22:37:59 */
#if 0 /* last code */
#else /* new code */
ssFndLenDmndQ(&tTsk->sTsk->dQ, (tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0, &qLen);
if(qLen > 750)
{
SS_RELEASE_SEMA(&osCp.tTskTblSem);
SPutMsg(mBuf);
SUnlock(&osCp.tmrTblLock);
/* restart the timer */
arg.tq = osCp.dep.tmrTq;
arg.tqCp = &osCp.dep.tmrTqCp;
arg.timers = tEnt->dep.timers;
arg.cb = (PTR) tEnt;
arg.evnt = TMR_DEF;
arg.wait = 0;
arg.tNum = NOTUSED;
arg.max = TMR_DEF_MAX;
arg.wait = tEnt->interval;
cmPlcCbTq(&arg);
RETVOID;
}
#endif /* end modify */
/* modify by shang is over 2002-7-19 22:37:59*/
/* write the timer message to the queue of the destination task */
if ( ssDmndQPutLast(&tTsk->sTsk->dQ, mBuf,
(tTsk->tskPrior * SS_MAX_MSG_PRI) + PRIOR0) != ROK )
{
SS_RELEASE_SEMA(&osCp.tTskTblSem);
SPutMsg(mBuf);
SUnlock(&osCp.tmrTblLock);
#if (ERRCLASS & ERRCLS_DEBUG)
WINLOGERROR(ERRCLS_DEBUG, EMT016, ERRZERO,
"Could not write to demand queue");
#endif
RETVOID;
}
/* release the semaphore for the TAPA task table */
SS_RELEASE_SEMA(&osCp.tTskTblSem);
/* restart the timer */
arg.tq = osCp.dep.tmrTq;
arg.tqCp = &osCp.dep.tmrTqCp;
arg.timers = tEnt->dep.timers;
arg.cb = (PTR) tEnt;
arg.evnt = TMR_DEF;
arg.wait = 0;
arg.tNum = NOTUSED;
arg.max = TMR_DEF_MAX;
arg.wait = tEnt->interval;
cmPlcCbTq(&arg);
/* unlock the timer table */
SUnlock(&osCp.tmrTblLock);
RETVOID;
}
#ifdef CONAVL
/*
*
* Fun: mtConHdlr
*
* Desc: This thread reads the console and hands over any
* data read to a user function.
*
* Ret: (thread function)
*
* Notes:
*
* File: win_ss.c
*
*/
#ifdef ANSI
PRIVATE Void *mtConHdlr
(
Ptr parm /* unused */
)
#else
PRIVATE Void *mtConHdlr(unused)
Ptr parm; /* unused */
#endif
{
int fd;
Data data;
TRC0(mtConHdlr);
UNUSED(parm);
/* check if we have a console input file handle */
if ( osCp.dep.conInFp == NULLP )
{
/* die */
RETVALUE(NULLP);
}
fd = fileno(osCp.dep.conInFp);
/* infinite loop */
for ( ; ; )
{
if ( (read(fd, &data, 1)) != 1 )
{
continue;
}
/* call rdConQ, defined by the system service user */
rdConQ(data);
}
/* not reached */
}
#endif /* CONAVL */
#ifdef SS_DRVR_SUPPORT
/*
*
* Fun: Interrupt service task handler
*
* Desc: This is the interrupt service task handler. It blocks
* on a pipe from which it reads an isFlag structure. The
* structure indicates which interrupt service task is to
* be executed. The thread identifies the task, calls the
* isTsk function and sends itself a message to repeat
* this operation until it receives a message to cease.
*
* Ret: ROK - ok
*
* Notes:
*
* File: win_ss.c
*
*/
#ifdef ANSI
DWORD WINAPI winIsrHndlr
(
Ptr tskPtr /* pointer to task entry */
)
#else
DWORD WINAPI winIsrHndlr(tskPtr)
Ptr tskPtr; /* pointer to task entry */
#endif
{
int ret;
WinIsFlag isFlag;
TRC0(winIsrHndlr);
for ( ; ; )
{
if ( _read(osCp.dep.isFildes[READ], (char *)&isFlag, sizeof(isFlag)) != sizeof(isFlag) )
{
continue;
}
if ( isFlag.id >= SS_MAX_DRVRTSKS )
{
continue;
}
switch ( isFlag.action )
{
case WIN_IS_SET:
osCp.drvrTskTbl[isFlag.id].dep.flag = TRUE;
/* call the interrupt service task activation function */
if ( NULLP != osCp.drvrTskTbl[isFlag.id].isTsk )
{
osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
}
/* send self a message to keep doing this */
isFlag.action = WIN_IS_RESET;
ret = _write(osCp.dep.isFildes[WRITE], (char *)&isFlag, sizeof(isFlag));
#if (ERRCLASS & ERRCLS_DEBUG)
if ( ret != sizeof(isFlag) )
{
WINLOGERROR(ERRCLS_DEBUG, EMT017, ERRZERO,
"write() to pipe failed");
}
#endif
break;
case WIN_IS_UNSET:
osCp.drvrTskTbl[isFlag.id].dep.flag = FALSE;
break;
case WIN_IS_RESET:
if ( osCp.drvrTskTbl[isFlag.id].dep.flag )
{
/* call the interrupt service task activation function */
if ( NULLP != osCp.drvrTskTbl[isFlag.id].isTsk )
{
osCp.drvrTskTbl[isFlag.id].isTsk(isFlag.id);
}
/* send self a message to do this again */
ret = _write(osCp.dep.isFildes[WRITE], (char *)&isFlag, sizeof(isFlag));
#if (ERRCLASS & ERRCLS_DEBUG)
if ( ret != sizeof(isFlag) )
{
WINLOGERROR(ERRCLS_DEBUG, EMT018, ERRZERO,
"write() to pipe failed");
}
#endif
}
break;
default:
/* where did THIS come from?? */
break;
}
}
/* not reached */
}
#endif /* SS_DRVR_SUPPORT */
/*
*
* Fun: mtExit
*
* Desc: Exit function, shuts down.
*
* Ret: Void
*
* Notes:
*
* File: win_ss.c
*
*/
#ifdef ANSI
PUBLIC Void winExit
(
int arg
)
#else
PUBLIC Void winExit(arg)
int arg;
#endif
{
Ticks ticks;
S8 buf[128];
TRC0(winExit);
#ifndef NOFILESYS
if ( osCp.dep.fileOutFp )
{
fclose(osCp.dep.fileOutFp);
}
#endif
SGetSysTime(&ticks);
sprintf(buf, "\n\nmtss(posix) ends\nticks: %ld\n", ticks);
SDisplay(0, buf);
exit(0);
}
/*
* interface functions
*/
/*
*
* Fun: SDisplay
*
* Desc: This function displays a string to a given output
* channel.
*
* Ret: ROK - ok
*
* Notes: Buffer should be null terminated.
*
* channel 0 is reserved for backwards compatibility
* with SPrint
*
* File: win_ss.c
*
*/
#ifdef ANSI
PUBLIC S16 SDisplay
(
S16 chan, /* channel */
Txt *buf /* buffer */
)
#else
PUBLIC S16 SDisplay(chan, buf)
S16 chan; /* channel */
Txt *buf; /* buffer */
#endif
{
TRC1(SDisplay);
#if (ERRCLASS & ERR_INT_PAR)
if ( buf == NULLP )
{
WINLOGERROR(ERRCLS_INT_PAR, EMT019, ERRZERO, "Null pointer");
RETVALUE(RFAILED);
}
#endif
#ifdef CONAVL
if ( osCp.dep.conOutFp ) fwrite(buf, strlen(buf), 1, osCp.dep.conOutFp);
#endif
/* add buy shang */
rxLog(buf);;
/* add buy shang over */
#ifndef NOFILESYS
if ( osCp.dep.fileOutFp ) fwrite(buf, strlen(buf), 1, osCp.dep.fileOutFp);
#endif
RETVALUE(ROK);
}
/*
*
* Fun: Set date and time
*
* Desc: This function is used to set the calendar
* date and time.
*
* Ret: ROK - ok
*
* Notes: Unimplemented
*
* File: win_ss.c
*
*/
#ifdef ANSI
PUBLIC S16 SSetDateTime
(
REG1 DateTime *dt /* date and time */
)
#else
PUBLIC S16 SSetDateTime(dt)
REG1 DateTime *dt; /* date and time */
#endif
{
TRC1(SSetDateTime);
UNUSED(dt);
RETVALUE(ROK);
}
/*
*
* Fun: Get date and time
*
* Desc: This function is used to determine the calendar
* date and time. This information may be used for
* some management functions.
*
* Ret: ROK - ok
* RFAILED - error
*
* Notes:
*
* File: win_ss.c
*
*/
#ifdef ANSI
PUBLIC S16 SGetDateTime
(
REG1 DateTime *dt /* date and time */
)
#else
PUBLIC S16 SGetDateTime(dt)
REG1 DateTime *dt; /* date and time */
#endif
{
/*
time_t tt;
struct tm tme;
*/
struct _SYSTEMTIME date;
TRC1(SGetDateTime);
#if (ERRCLASS & ERRCLS_INT_PAR)
if ( dt == NULLP )
{
WINLOGERROR(ERRCLS_INT_PAR, EMT020, ERRZERO, "Null pointer");
RETVALUE(RFAILED);
}
#endif
/*
time(&tt);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -