📄 cmtengin.c
字号:
#include "cmtlib.h"
#include "dos.h"
#pragma option -k
static unsigned int _cmttaskid;
static CMT_TASK far *_termtask;
CMT_TASK far *_cmtactivetask,far *_cmtsystemtask;
unsigned int cmt_tasksactive; /* not including system task */
/*
** Permission is hereby granted for free use of this cooperative
** multitasking library code, provided this copyright message is
** kept intact and linked into final code.
**
** Madis Kaal <mast@nomad.ee> http://www.nomad.ee
*/
char cmt_CopyRight[]="Cooperative MultiTasking engine 1.01 "
"Copyright (C) Madis Kaal <mast@nomad.ee> 1994-2000 "
"Copyright (C) Nomad Systems http://www.nomad.ee 2000";
/* ----------------------------------------------------------------
** Engine.
** ----------------------------------------------------------------
*/
/*man**************************************************************
NAME
cmt_pause - give away timeslice
SYNOPSIS
#include "cmtlib.h"
void far cdecl cmt_pause(void)
DESCRIPTION
this function switches to next task in the task list and
returns after all other tasks have gotten their share of
the CPU time. as our the multitasker is cooperative, this
function should be called as often as possible to keep
things alive. as for all cooperative multitaskers, task
switch overhead is very small and will not waste a lot of
cycles.
NOTES
do not use any 'tight loops' in your code without invoking
cmt_pause() from time to time unless you really mean it,
because you program will not multitask in this case.
******************************************************************/
void far cdecl cmt_pause(void)
{
_SI=_DI;
if (_cmtactivetask) {
if (_cmtactivetask->leavetask)
(_cmtactivetask->leavetask)();
disable();
_cmtactivetask->ss=_SS;
_cmtactivetask->sp=_SP;
_cmtactivetask=_cmtactivetask->next;
_SS=_cmtactivetask->ss;
_SP=_cmtactivetask->sp;
enable();
if (_cmtactivetask->entertask)
(_cmtactivetask->entertask)();
}
}
static void far cdecl cmt_terminate(void)
{
if (_cmtactivetask->killtask)
(_cmtactivetask->killtask)();
_SI=_DI;
_termtask=_cmtactivetask;
_termtask->prev->next=_termtask->next;
_termtask->next->prev=_termtask->prev;
_cmtactivetask=_termtask->next;
disable();
_SS=_cmtactivetask->ss;
_SP=_cmtactivetask->sp;
enable();
if (_termtask->stack)
cmt_free(_termtask->stack);
cmt_free(_termtask);
cmt_tasksactive--;
}
/*man**************************************************************
NAME
cmt_fork - create a new task
SYNOPSIS
#include "cmtlib.h"
CMT_TASK far * cdecl cmt_fork(void far cdecl (*task)(void),
unsigned int stacksize)
DESCRIPTION
this function creates a new task. in our context, task
is simply a normal C function which takes no parameters
and does not return anything. the new task gets it's own
stack of the specified size (in bytes). if stacksize is
0, then the default CMT_DEFAULTSTACKSIZE is used. the
created task is placed in the task list as the next task
to be run - next cmt_pause() switches to last task created.
DIAGNOSTICS
this function returns pointer to new task or NULL
if the task can not be created.
NOTES
due the way Borland's FP emulator is implemented, you cannot
do any floating point operations in forked tasks if you don't
have FP coprecessor (more precisely, FP emulator allocates
it's workspace from the 'system' stack and assumes that
SS never changes).
******************************************************************/
CMT_TASK far * far cdecl cmt_fork(void far cdecl (*task)(void),
unsigned int stacksize)
{
CMT_TASK far *newtask=NULL;
if (task) {
if (!_cmtactivetask) {
_cmtactivetask=cmt_malloc(sizeof(CMT_TASK));
if (_cmtactivetask) {
_cmtactivetask->next=_cmtactivetask->prev=_cmtactivetask;
_cmtactivetask->id=_cmttaskid=0;
_cmtactivetask->stack=NULL;
_cmtactivetask->ss=_SS;
_cmtactivetask->sp=_SP;
_cmtactivetask->entertask=
_cmtactivetask->leavetask=
_cmtactivetask->killtask=NULL;
_cmtsystemtask=_cmtactivetask;
}
}
if (!stacksize)
stacksize=CMT_DEFAULTSTACKSIZE;
newtask=cmt_malloc(sizeof(CMT_TASK));
if (newtask) {
newtask->stack=cmt_malloc(stacksize);
if (!newtask->stack) {
cmt_free(newtask);
return NULL;
}
newtask->ss=FP_SEG(newtask->stack);
newtask->sp=stacksize>>1;
newtask->stack[--newtask->sp]=FP_SEG(cmt_terminate);
newtask->stack[--newtask->sp]=FP_OFF(cmt_terminate);
newtask->stack[--newtask->sp]=FP_SEG(task);
newtask->stack[--newtask->sp]=FP_OFF(task);
newtask->sp=FP_OFF(newtask->stack+(newtask->sp-3));
newtask->id=++_cmttaskid;
newtask->message=NULL;
newtask->entertask=
newtask->leavetask=
newtask->killtask=NULL;
newtask->prev=_cmtactivetask;
newtask->next=_cmtactivetask->next;
_cmtactivetask->next=newtask;
newtask->next->prev=newtask;
cmt_tasksactive++;
}
}
return newtask;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -