⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmtengin.c

📁 简单实现多任务的C语言库 可以实现各个任务间的简单的消息通讯
💻 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 + -