×

kernel 汇编实时运行核心的汇编源代码

消耗积分:2 | 格式:rar | 大小:16 | 2010-02-25

刘洋

分享资料个

kernel 汇编实时运行核心的汇编源代码.rar

/*
Listing 1      Scheduling Algorithm
(C) Copyright 1986 Ken Berry.
All rights reserved.
Copies may be made for non-commercial, private use only.
*/

#define _F 0   /* false */
#define _T 1   /* true */
#define _E -1   /* error */

#define _NULL 0   /* null pointer */

typedef char pointer;  /* pointer type */
typedef char logical;  /* logical type */
typedef unsigned selector; /* 8086 selector type */

struct sys_parm   /* register storage block for 8086 interface */
{
  union {unsigned sys_rax; struct {char sys_ral, sys_rah;} sys_byt;} sys_ra;
  union {unsigned sys_rbx; struct {char sys_rbl, sys_rbh;} sys_byt;} sys_rb;
  union {unsigned sys_rcx; struct {char sys_rcl, sys_rch;} sys_byt;} sys_rc;
  union {unsigned sys_rdx; struct {char sys_rdl, sys_rdh;} sys_byt;} sys_rd;
#define sys_ax sys_ra.sys_rax
#define sys_al sys_ra.sys_byt.sys_ral
#define sys_ah sys_ra.sys_byt.sys_rah
#define sys_bx sys_rb.sys_rbx
#define sys_bl sys_rb.sys_byt.sys_rbl
#define sys_bh sys_rb.sys_byt.sys_rbh
#define sys_cx sys_rc.sys_rcx
#define sys_cl sys_rc.sys_byt.sys_rcl
#define sys_ch sys_rc.sys_byt.sys_rch
#define sys_dx sys_rd.sys_rdx
#define sys_dl sys_rd.sys_byt.sys_rdl
#define sys_dh sys_rd.sys_byt.sys_rdh
  unsigned sys_bp;  /* base pointer */
  unsigned sys_si;  /* source index */
  unsigned sys_di;  /* destination index */
  unsigned sys_sp;  /* stack pointer */
  unsigned sys_cs;  /* code segment */
  unsigned sys_ds;  /* data segment */
  unsigned sys_ss;  /* stack segment */
  unsigned sys_es;  /* extra segment */
  unsigned sys_pf;  /* 80286 processor flags */
#define SYS_OF 0x0800       /* overflow flag- 1: lost significance */
#define SYS_DF 0x0400       /* direction flag- 1: strings auto-decrement */
#define SYS_IF 0x0200       /* interrupt flag- 1: enable interrupts */
#define SYS_TF 0x0100       /* trap flag- 1: interrupt every instruction */
#define SYS_SF 0x0080       /* sign flag- 1: result negative */
#define SYS_ZF 0x0040       /* zero flag- 1: result 0 */
#define SYS_AF 0x0010       /* auxiliary carry flag- 1: carry from bit 3 */
#define SYS_PF 0x0004       /* parity flag- 1: even number of 1's */
#define SYS_CF 0x0001       /* carry flag- 1: carry from bit 8 or 16 */
  unsigned sys_sw;  /* status word */
#define SYS_TS 0x0008       /* task switch */
#define SYS_EM 0x0004       /* processor extension emulation */
#define SYS_MP 0x0002       /* monitor processor extension */
#define SYS_PE 0x0001       /* protection enable */
  unsigned sys_ip;  /* instruction pointer */
  unsigned sys_res;  /* unused */
};

struct t_xstck
{
  unsigned t_xbase;  /* application stack base (overflow detection) */
  unsigned t_xes;  /* es */
  unsigned t_xbp;  /* bp */
  unsigned t_xdi;  /* di */
  unsigned t_xsi;  /* si */
  unsigned t_xdx;  /* dx */
  unsigned t_xcx;  /* cx */
  unsigned t_xbx;  /* bx */
  unsigned t_xax;  /* ax */
  unsigned t_xds;  /* ds */
  unsigned t_xip;  /* ip */
  unsigned t_xcs;  /* cs */
  unsigned t_xpf;  /* pf */
  unsigned t_retip;  /* return address */
};

struct t_task
{
  char t_type;   /* task type */
#define T_X 0x80  /* execute queue */
#define T_W 0x40  /* wait queue */
#define T_P 0x20  /* priority queue */
#define T_SW 0x10  /* secondary wait queue */
#define T_ATASK 0x01  /* abreviated task */
  unsigned t_wttk;  /* wait tick count */
  unsigned t_cls;  /* priority queue index */
  struct t_task *t_pqtsk,*t_nqtsk; /* queue linkage */
  struct t_task *t_ratsk,*t_pstsk,*t_nstsk,*t_fdtsk,*t_ldtsk; /* family */
  struct sys_parm t_ps;  /* processor status */
  unsigned t_xtm0;  /* execution time accumulator */
  unsigned t_xtm1;
  unsigned t_xtm2;
  pointer *t_axstk;  /* execution stack pointer */
};

extern pointer *sys_task; /* current task control table pointer */
#define _tsk ( ( struct t_task * ) sys_task ) /* task control table ref */

#define T_SCLS 4  /* number of scheduling classes */

struct t_scls   /* scheduling class queue */
{
  unsigned t_sfrq;  /* scheduling frequency */
  int t_sct;   /* queue length */
  struct t_task *t_fqtsk,*t_lqtsk; /* queue header */
};

struct t_schd   /* scheduling control table */
{
  int t_xct;   /* execution queue length */
  struct t_task *t_fxtsk, *t_lxtsk; /* execution queue header */
  int t_wct;   /* wait queue length */
  struct t_task *t_fwtsk, *t_lwtsk; /* wait queue header */
  int t_swct;   /* secondary wait queue length */
  struct t_task *t_fswtsk, *t_lswtsk; /* secondary wait queue header */
  int t_sclsl;   /* scheduling class index limit */
  struct t_scls **t_sclsp; /* scheduling class array pointer */
};

extern pointer *sys_tsch; /* task scheduling control table pointer */
#define _tschd ( ( struct t_schd * ) sys_tsch ) /* quick pointer */

/*
t__krnl    * security kernel *
*/
t__krnl()
/*
This is the security kernel.  It never returns, being the most trusted
software in the system. The current contents in t__crtss and t__crtsp
are used to set the stack for when the current task is resumed. */
{
  extern logical t_astrm; /* tick termination flag */
  extern selector t__crtss; /* current task ss storage */
  extern pointer *t__crtsp; /* current task sp storage */
  extern unsigned tmr_tkct; /* tick clock */
  int xtskct;   /* task queue count (at entry) */
  int ttc;   /* task termination code */
  _tsk -> t_ps.sys_ss = t__crtss; /* set current task stack */
  _tsk -> t_ps.sys_sp = t__crtsp;
  while(_T)   /* find executable task */
  {
    xtskct = _tschd -> t_xct; /* save task count */
    if ( t_astrm ) t__wtst( tmr_tkct ); /* process wait tasks */
    if ( xtskct == 0 ) t__sch(); /* schedule application tasks if necessary */
    sys_task = _tschd -> t_fxtsk; /* set next task address */
    if ( sys_task != _NULL )  /* test for executable task available */
    {
      _tschd -> t_xct--; /* decrement executing task count */
      _tschd -> t_fxtsk = _tsk -> t_nqtsk; /* delink task */
      if ( _tschd -> t_fxtsk == _NULL )
 _tschd -> t_lxtsk = _NULL;
      else _tschd -> t_fxtsk -> t_pqtsk = _NULL;
      _tsk -> t_type &= ~T_X; /* indicate task not in execution queue */
      ttc = t__xtsk( sys_task ); /* execute application task */
      if ( !sys_task ) continue; /* test for task terminated */
      if ( ttc < 0 ) t__inxq(); /* insert task into execution queue */
      else if ( ttc == 0 ) t__inpq(); /* insert task into priority queue */
      else t__inwq( ttc ); /* insert into wait queue */
    }
  }
}

/*
t__wtst    test waiting tasks
*/
t__wtst( tc)
unsigned tc;
/*
The wait queue is traversed.  All tasks with a wait value of tc are executed.
_F is always returned. */
{
  while(_T)   /* traverse wait queue */
  {
    sys_task = _tschd -> t_fwtsk; /* set current task pointer */
    if ( !sys_task ) break; /* test for no waiting tasks */
    _tsk -> t_type &= ~T_W; /* remove task from wait queue */
    _tsk -> t_type |= T_X; /* indicate task in execution queue */
    if ( _tsk -> t_wttk > tc ) break; /* test for effective end of list */
    --_tschd -> t_wct;  /* decrement waiting task  count */
    _tschd -> t_fwtsk = _tsk -> t_nqtsk; /* delink from wait queue */
    if ( _tsk -> t_nqtsk == _NULL )
      _tschd -> t_lwtsk = _NULL;
    else _tsk -> t_nqtsk -> t_pqtsk = _NULL;
    _tsk -> t_pqtsk = _NULL; /* insert at top of execution queue */
    _tsk -> t_nqtsk = _tschd -> t_fxtsk;
    _tschd -> t_fxtsk = sys_task;
    ++_tschd -> t_xct;  /* increment executable task count */
    if ( _tschd -> t_lxtsk == _NULL )
      _tschd -> t_lxtsk = sys_task;
    else _tsk -> t_nqtsk -> t_pqtsk = sys_task;
  }
  return _F;   /* return */
}

/*
t__sch    schedule task
*/
t__sch()
/*
This function searches the priority queues and links tasks ready for execution
into the execution queue. The return is always _F. */
{
  struct t_scls **a;  /* priority queue pointer array pointer */
  struct t_scls *q;  /* priority queue pointer */
  int i,j;   /* iteration variables */
  a = _tschd -> t_sclsp; /* set pointer array address */
/*  while(_T)      * nonterminating task *
  { */
    for ( i = 0; i < _tschd -> t_sclsl; ++i ) /* traverse queues */
    {
      q = a[i];   /* set priority queue pointer */
      for ( j = 0; j++ t_sfrq; ) /* schedule tasks from priority queue */
      {
 if ( q -> t_fqtsk == _NULL ) break; /* test for queue empty */
 if ( _tschd -> t_lxtsk ) /* link to end of execution queue */
   _tschd -> t_lxtsk -> t_nqtsk = q -> t_fqtsk;
 else _tschd -> t_fxtsk = q -> t_fqtsk;
 q -> t_fqtsk -> t_type &= ~T_P; /* indicate not in priority queue */
 q -> t_fqtsk -> t_pqtsk = _tschd -> t_lxtsk;
 _tschd -> t_lxtsk = q -> t_fqtsk;
 q -> t_fqtsk = q -> t_fqtsk -> t_nqtsk; /* update queue header */
 _tschd -> t_lxtsk -> t_nqtsk = _NULL;
 if ( q -> t_fqtsk == _NULL )
   q -> t_lqtsk = _NULL;
 else q -> t_fqtsk -> t_pqtsk = _NULL;
 q -> t_sct --;  /* decrement queue count */
 ++ _tschd -> t_xct; /* increment execution queue length */
 _tschd -> t_lxtsk -> t_type |= T_X; /* ind. task in execution queue */
      }
    }
/*    t_rels();      * return to bottom of execution queue *
  }*/
  return _F;   /* return */
}

/*
t__inxq    insert task into execution queue
*/
t__inxq()
/*
The current task is inserted into the execution queue. _F is always returned.
*/
{
  _tsk -> t_wttk = 0;  /* indicate not waiting for system tick */
  if ( _tschd -> t_lxtsk == _NULL ) /* test for execution queue empty */
  {
    _tschd -> t_fxtsk = sys_task; /* insert in empty queue */
    _tsk -> t_pqtsk = _NULL;
  }
  else    /* execution queue not empty */
  {
    _tschd -> t_lxtsk -> t_nqtsk = sys_task; /* insert at end of queue */
    _tsk -> t_pqtsk = _tschd -> t_lxtsk;
  }
  _tsk -> t_nqtsk = _NULL; /* new task at end of list */
  _tschd -> t_lxtsk = sys_task;
  _tschd -> t_xct++;  /* increment executable task count */
  _tschd -> t_lxtsk -> t_type |= T_X; /* indicate task in execution queue */
  return _F;   /* return */
}

/*
t__secw    process secondary wait queue
*/
t__secw()
/*
This program executes every 64K system ticks. It moves the secondary
wait queue to the primary wait queue and changes the type of the waiting
tasks. */
{
  struct t_task *tsk;  /* task control table pointer */
  char swtflg;   /* system state flag */
  extern int tmr_tkct;  /* tick clock  */
  while(_T)   /* nonterminating task */
  {
    t__syntr( &swtflg ); /* enter system state */
    for ( tsk = _tschd -> t_fwtsk; tsk; tsk = tsk -> t_nqtsk ) /* traverse */
    {
      tsk -> t_type &= ~T_SW;
      tsk -> t_type |= T_W; /* change task type */
    }
    _tschd -> t_wct = _tschd -> t_swct; /* append secondary wait queue */
    _tschd -> t_fwtsk = _tschd -> t_fswtsk;
    _tschd -> t_lwtsk = _tschd -> t_lswtsk;
    _tschd -> t_fswtsk = _tschd -> t_lswtsk = _NULL; /* empty sec. queue */
    _tschd -> t_swct = 0;
    t__inwq( 0xFFFF - tmr_tkct ); /* insert self into wait queue at end */
    sys_task = _NULL;  /* remove task from kernel control */
    t_term();   /* suspend execution */
  }
}

/*
t__inwq    insert task into wait queue
*/
t__inwq(tc)
unsigned tc;
/*
The  current task is inserted into the wait queue.  tc is the number of system
ticks that the task is to wait. _F is always returned. */
{
  extern unsigned tmr_tkct; /* tick clock */
  unsigned crtk;  /* current tick */
  crtk = tmr_tkct;  /* set current system tick */
  _tsk -> t_wttk = tc + crtk; /* compute reactivation time */
  if ( _tsk -> t_wttk >= crtk ) /* test for task in wait queue */
  { t__inwt( &_tschd -> t_wct ); /* insert in wait queue */
    _tsk -> t_type |= T_W;
  }else    /* task in secondary wait queue */
  { t__inwt( &_tschd -> t_swct ); /* insert in secondary wait queue */
    _tsk -> t_type |= T_SW;
  }return _F;   /* indicate task inserted */
}

/*
t__inwt    insert into wait or secondary wait queue
*/
struct t_wtq
{
  int wct;   /* wait queue length */
  struct t_task *frs,*lst; /* queue header */
};
t__inwt( w )
struct t_wtq *w;
/*
The t_wtq structure is implicitly contained in the scheduling control table
(t_schd structure).  The current task is inserted into the queue. _F is always
returned. */
{
  struct t_task *p;  /* task pointer */
  unsigned tc;   /* reactivation time */
  tc = _tsk -> t_wttk;  /* set reactivation time */
  ++w -> wct;   /* increment queue length */
  for ( p = w -> frs; p; p = p -> t_nqtsk ) /* traverse queue */
  {
    if ( tc < p -> t_wttk ) /* test for task earlier */
    {
      _tsk -> t_nqtsk = p; /* insert within queue */
      _tsk -> t_pqtsk = p -> t_pqtsk;
      p -> t_pqtsk = sys_task;
      if ( ( p = _tsk -> t_pqtsk ) ) p -> t_nqtsk = sys_task;
      else w -> frs = sys_task;
      return _F;  /* indicate task inserted */
    }
  }
  if ( ( p = w -> lst ) ) /* test for wait queue not empty */
  {
    p -> t_nqtsk = w -> lst = sys_task; /* insert at end of queue */
    _tsk -> t_pqtsk = p;
    _tsk -> t_nqtsk = _NULL;
  }
  else    /* wait queue empty */
  {
    w -> frs = w -> lst = sys_task; /* initialize wait queue */
    _tsk -> t_nqtsk = _tsk -> t_pqtsk = _NULL;
  }
  return _F;   /* indicate task inserted */
}

/*
t__inpq    insert into priority queue
*/
t__inpq()
/*
The current task is inserted into its priority queue. _F is always returned.
*/
{
  struct t_scls *q;  /* priority queue pointer */
  _tsk -> t_wttk = 0;  /* indicate not waiting for tick */
  q = _tschd -> t_sclsp[ _tsk -> t_cls ]; /* set priority queue address */
  _tsk -> t_pqtsk = q -> t_lqtsk; /* link task into priority queue */
  _tsk -> t_nqtsk = _NULL;
  if ( q -> t_lqtsk == _NULL ) q -> t_fqtsk = sys_task;
  else q -> t_lqtsk -> t_nqtsk = sys_task;
  q -> t_lqtsk = sys_task;
  ++q -> t_sct;   /* increment queue length */
  _tsk -> t_type |= T_P; /* indicate task in priority queue */
  return _F;   /* return */
}

/*
t__xtsk    execute task
*/
t__xtsk( t )
struct t_task *t;
/*
Task t is executed. The returned value is the termination code.
*/
{
  extern unsigned t_mnxtm; /* minimum execution time */
  extern unsigned t_syxtm[]; /* system pseudo time accumulator */
  extern logical t_astrm; /* application termination flag */
  extern int t__crtss; /* current task ss storage */
  extern int t__crtsp; /* current task sp storage */
  int ttc;   /* return value storage */
  unsigned atm;   /* accumulated time */
  unsigned rtm;   /* reference time */
  int xtm;   /* execution time */
  atm = 0;   /* initialize accumulated execution time */
  while(_T)   /* execute task */
  {
    rtm = t -> t_xtm0;  /* set reference time */
    t_rtmark( &t -> t_xtm0 ); /* accumulate pseudo time */
    ttc = t__dspap( t -> t_ps.sys_ss, t -> t_ps.sys_sp ); /* execute task */
    t -> t_ps.sys_ss = t__crtss; /* store ss */
    t -> t_ps.sys_sp = t__crtsp; /* store sp */
    t_rtmark( &t_syxtm ); /* accumulate pseudo time */
    if ( ( ttc != 0 ) || !t_astrm ) break; /* test for not tick termination */
    xtm = t -> t_xtm0 - rtm; /* compute execution time */
    if ( xtm < rtm ) xtm = -xtm;
    atm += xtm;   /* accumulate execution time */
    if ( atm >= t_mnxtm ) break; /* test for minimum time satisfied */
  }
  return ttc;   /* return */
}
/*
t__init    initialize task system
*/
t__init()
/*
This function initializes the task system. _F is the normal return. _E is
returned if the system cannot be initialized. */
{
#define WSTK 252  /* t_wqupd stack size */
  extern struct sys_parm sys_stat; /* initial processor status */
  extern struct t_task *t_wqupd; /* secondary wait queue update task */
  extern selector sys_dgrp; /* data segment selector storage */
  extern char *sys_ssbs; /* system stack pointer */
  extern unsigned sys_sssz; /* system stack length */
  extern char tmr_ilck;  /* tick service interlock */
  int t__secw();  /* wait queue update function */
  struct t_scls *cls;  /* priority queue pointer */
  struct t_scls **ary;  /* priority queue pointer array pointer */
  int i;   /* iteration variable */
  char *s;   /* pointer */
  tmr__int();   /* initialize system tick clock */
  sys_task = sys_ssbs + sys_sssz; /* set main task control table pointer */
  _tsk -> t_xtm0 =  /* initialize execution time */
  _tsk -> t_xtm1 =
  _tsk -> t_xtm2 = 0;
  if( ( sys_tsch = mm_aloc( sizeof( struct t_schd ) ) ) == _NULL )goto err1;
  if( ( ary = mm_aloc( T_SCLS*( sizeof( struct t_scls )+2 ) ) )
     == _NULL )goto err2;
  _tsk -> t_pqtsk =  /* NULL linkage */
  _tsk -> t_nqtsk =
  _tsk -> t_ratsk =
  _tsk -> t_pstsk =
  _tsk -> t_nstsk =
  _tsk -> t_fdtsk =
  _tsk -> t_ldtsk = _NULL;
  _tsk -> t_cls = 0;  /* set priority class 0 */
  _tsk -> t_wttk = 0;  /* indicate not waiting */
  for( i = 0, s = &_tsk -> t_ps;
    i++  _tsk -> t_ps.sys_cs = sys_stat.sys_cs; /* set selectors */
  _tsk -> t_ps.sys_ds =
  _tsk -> t_ps.sys_es =
  _tsk -> t_ps.sys_ss = sys_dgrp;
  _tsk -> t_axstk = _NULL; /* NULL execution stack pointer */
  _tschd -> t_xct = 1;  /* set execution task count */
  _tschd -> t_fxtsk =  /* set execution queue */
  _tschd -> t_lxtsk = sys_task;
  _tschd -> t_wct = 0;  /* indicate idle wait queue */
  _tschd -> t_fwtsk =  /* set wait queue */
  _tschd -> t_lwtsk = _NULL;
  _tschd -> t_swct = 0;  /* indicate empty secondary wait queue */
  _tschd -> t_fswtsk =  /* NULL secondary wait queue */
  _tschd -> t_lswtsk = _NULL;
  _tschd -> t_sclsl = T_SCLS; /* set priority queue count */
  _tschd -> t_sclsp = ary; /* set priority queue pointer array address */
  cls = &ary[ T_SCLS ];  /* set first t_scls pointer */
  for( i = 0; i  {
    ary[i] = cls;  /* set priority queue pointer */
    cls -> t_sfrq = 1;  /* set default frequency */
    cls -> t_sct = 0;  /* indicate empty queue */
    cls -> t_fqtsk =  /* NULL queue linkage */
    cls -> t_lqtsk = _NULL;
  }
  t_wqupd =   /* create task to update wait queue */
    t_crt( t__secw, 0, 0, WSTK, 0, 0, 0 );
  if( t_wqupd == _NULL )goto err3;
  t_wqupd -> t_wttk = 0xFFFF; /* update wait queue at wraparound time */
  t__dspsy();   /* dispatch system */
  tmr_ilck = 0x00;  /* enable tick service */
  return _F;   /* indicate task system initialized */
err3: mm_free( ary );  /* error nest */
err2: mm_free( sys_tsch );
err1: return _E;
}

/*
t__term
*/
t__term()
/*
The task system is terminated. All tasks and storage allocated by t__init are
released. The return is always _F. */
{
  extern char *sys_ssbs; /* system stack base */
  extern unsigned sys_sssz; /* system stack size */
  struct t_task *t;  /* t_task pointer */
  char trmflg;   /* system state flag storage */
  tmr__rst();   /* reset system tick clock */
  t__syntr( &trmflg );  /* enter system state */
  sys_task = sys_ssbs + sys_sssz; /* set original task address */
  while( ( t = _tsk -> t_fdtsk ) ) /* delete all created tasks */
    t_del( t, _F );
  mm_free( _tschd -> t_sclsp );
  mm_free( sys_tsch );
  return _F;   /* normal return */
}

/*
t_crt    create task
*/
t_crt( xadr, pcnt, padr, ssiz, dsiz, sadr, prty )
pointer *xadr;
unsigned pcnt;
unsigned *padr;
unsigned ssiz, dsiz;
pointer *sadr;
unsigned prty;
/*
A  new task is created with execution priority prty.  Execution will begin  at
xadr.  pcnt parameters will be passed (on the new task stack). The parameters
are  in  an array addressed by padr.  The new task will have a stack  of  ssiz
bytes  and a dynamic memory area of dsiz bytes.  dsiz may be zero to  indicate
that no dynamic memory is required.  sadr will recieve a termination code when
the  task  terminates. If sadr is _NULL, an abreviated task is created. _F  is
returned if insufficient memory  is  available.  Otherwise the address of the
t_ftask table is returned. */
{
  extern int t__halt();  /* return address */
  struct t_task *tsk;  /* task control table pointer (t_task) */
  struct t_scls *pq;  /* priority queue pointer */
  struct t_xstck *sp;  /* execution stack pointer */
  pointer *ss;   /* stack start */
  unsigned *pr;   /* parameter pointer */
  unsigned ln;   /* task control table length */
  int i;   /* iteration variable */
  char *s;   /* pointer */
  char *sptr;   /* execution stack pointer */
  logical crtflg;  /* system state flag storage */
  t__syntr( &crtflg );  /* enter system state */
  ln = sizeof( struct t_task );  /* allocate task control table */
  if( ( tsk = mm_aloc( ln ) ) == _NULL ) goto err1;
  ssiz += sizeof( struct t_xstck ); /* allocate stack */
  if( ( ss = tsk -> t_axstk = mm_aloc( ssiz ) ) == _NULL )goto err2;
  tsk -> t_type = T_ATASK; /* indicate abreviated task control table */
  tsk -> t_wttk = 0;  /* indicate not waiting */
  tsk -> t_ratsk = sys_task; /* task family linkage */
  tsk -> t_pstsk = _tsk -> t_ldtsk;
  tsk -> t_nstsk =
  tsk -> t_fdtsk =
  tsk -> t_ldtsk = _NULL;
  _tsk -> t_ldtsk = tsk;
  if( tsk -> t_pstsk == _NULL )_tsk -> t_fdtsk = tsk;
  else tsk -> t_pstsk -> t_nstsk = tsk;
  if( prty > _tschd -> t_sclsl ) /* adjust priority */
    prty = _tschd -> t_sclsl-1;
  tsk -> t_cls = prty;  /* set priority */
  pq = _tschd -> t_sclsp[ prty ]; /* set scheduling array pointer */
  ++pq -> t_sct;  /* scheduling linkage */
  tsk -> t_pqtsk = pq -> t_lqtsk;
  tsk -> t_nqtsk = _NULL;
  if( tsk -> t_pqtsk == _NULL )pq -> t_fqtsk = tsk;
  else tsk -> t_pqtsk -> t_nqtsk = tsk;
  pq -> t_lqtsk = tsk;
  tsk -> t_xtm0 =  /* no execution time yet */
  tsk -> t_xtm1 =
  tsk -> t_xtm2 = 0;
  pr = sptr = ss+ssiz-2*pcnt; /* initialize execution stack & t_ps */
  tsk -> t_ps.sys_sp =
  sp = sptr - sizeof( struct t_xstck );
  sp -> t_xbp = ss + ssiz;
  sp -> t_xbase = ss;
  while( pcnt-- )*pr++ = *padr++;
  for( i = 0, s = &tsk -> t_ps; i++ < sizeof( struct sys_parm ); )*s = 0;
  tsk -> t_ps.sys_ds =
  tsk -> t_ps.sys_es =
  tsk -> t_ps.sys_ss =
  sp -> t_xds =
  sp -> t_xes =  _tsk -> t_ps.sys_ds;
  sp -> t_xdi =
  sp -> t_xsi =
  sp -> t_xdx =
  sp -> t_xcx =
  sp -> t_xbx =
  sp -> t_xax = _NULL;
  sp -> t_xip = xadr;
  tsk -> t_ps.sys_cs =
  sp -> t_xcs =
  _tsk -> t_ps.sys_cs;
  tsk -> t_ps.sys_pf =
  sp -> t_xpf = SYS_IF;
  tsk -> t_ps.sys_ip =
  sp -> t_retip = &t__halt;
  t__syxit( &crtflg );  /* exit system state */
  return tsk;   /* return */
err3: mm_free( tsk -> t_ps.sys_ss );
err2: mm_free( tsk );
err1: t__syxit( &crtflg );
  return _NULL;
}

/*
t__halt    terminate task
*/
t__halt()
/*
If  a subtask returns into its orginal stack,  control will pass  to  t__halt.
This  function deletes the subtask and then clears the sys_task pointer  just
before returning on the system stack (to reenter the security kernel). */
{
  logical haltflg;  /* system state flag storage */
  t__syntr( &haltflg );  /* enter system state */
  t_rtmark( &_tsk -> t_ratsk -> t_xtm0 ); /* accumulate pseudo time */
  t_del( sys_task, _F ); /* delete current task */
  sys_task = _NULL;  /* indicate task terminated */
  while(_T)t_term();  /* return to security kernel */
}

/*
t_del    delete task
*/
t_del( tsk, st )
struct t_task *tsk;
int st;
/*
Task tsk is killed. st is the status returned to the calling program.
*/
{
#define tskf ( ( struct t_ftask * )tsk ) /** (t_ftask) */
  struct t_task *t;  /* task control table pointer */
  logical delflg;  /* system state flag storage */
  t__syntr( &delflg );  /* enter system state */
  while( ( t = tsk -> t_fdtsk ) )t_del( t, st ); /* delete subtasks first */
  if( tsk -> t_pstsk )  /* family linkage */
    tsk -> t_pstsk -> t_nstsk = tsk -> t_nstsk;
  else tsk -> t_ratsk -> t_ldtsk = tsk -> t_nstsk;
  if( tsk -> t_nstsk )
    tsk -> t_nstsk -> t_pstsk = tsk -> t_pstsk;
  else tsk -> t_ratsk -> t_fdtsk = tsk -> t_pstsk;
  if( tsk -> t_pqtsk )  /* queue linkage */
    tsk -> t_pqtsk -> t_nqtsk = tsk -> t_nqtsk;
  else if( ( tsk -> t_type&T_P )
       && ( _tschd -> t_sclsp[ tsk -> t_cls ] -> t_fqtsk == tsk ) )
  _tschd -> t_sclsp[ tsk -> t_cls ] -> t_fqtsk = tsk -> t_nqtsk;
  else if( ( tsk -> t_type&T_W ) && ( _tschd -> t_fwtsk == tsk ) )
    _tschd -> t_fwtsk = tsk -> t_nqtsk;
  else if( ( tsk -> t_type&T_SW ) && ( _tschd -> t_fswtsk == tsk ) )
    _tschd -> t_fswtsk = tsk -> t_nqtsk;
  else if( ( tsk -> t_type&T_X ) && ( _tschd -> t_fxtsk == tsk ) )
    _tschd -> t_fxtsk = tsk -> t_nqtsk;
  if( tsk -> t_nqtsk )tsk -> t_nqtsk -> t_pqtsk = tsk -> t_pqtsk;
  else if( ( tsk -> t_type&T_P )
       && ( _tschd -> t_sclsp[ tsk -> t_cls ] -> t_lqtsk == tsk ) )
  _tschd -> t_sclsp[tsk -> t_cls] -> t_lqtsk = tsk -> t_pqtsk;
  else if( ( tsk -> t_type&T_W ) && ( _tschd -> t_fwtsk == tsk ) )
    _tschd -> t_lwtsk = tsk -> t_pqtsk;
  else if( ( tsk -> t_type&T_SW ) && ( _tschd -> t_fswtsk == tsk ) )
    _tschd -> t_lswtsk = tsk -> t_pqtsk;
  else if( ( tsk -> t_type&T_X ) && ( _tschd -> t_fxtsk == tsk ) )
   _tschd -> t_lxtsk = tsk -> t_pqtsk;
  t = sys_task;   /* save current t_task pointer */
  sys_task = tsk -> t_ratsk; /* set ancestor task */
  mm_free( tsk -> t_ps.sys_ss ); /* free stack */
  mm_free( tsk );  /* free t_task table */
  sys_task = t;   /* restore current task pointer */
  t__syxit( &delflg );  /* exit system state */
  return _F;   /* return */
}

/*
mm_aloc    memory allocation
*/
mm_aloc(ln)
unsigned ln;
/*
ln bytes are allocated from the heap. The address of the first byte is
returned. If there is not enough available memory to satisfy the request,
_NULL is returned. */
{
  return malloc(ln);  /* allocate storage */
}

/*
mm_free    memory deallocation
*/
mm_free(st)
char *st;
/*
st is the address returned by a previous call to function mm_free. The storage
previously allocated is made available for future use. The normal return is
_F. _E is returned if st does not point to an area previously allocated by
mm_aloc. */
{
  return free(st);  /* deallocate storage */
}

/*
main    test program
*/
main()
/*
This function serves to test the task scheduler. Two tasks are created, each
of which increments a variable. The original task continually displays the
counts, as well as its own iteration number. Depressing any key will cause a
return to MS-DOS. */
{
  int ctr1, ctr2, ctr3;  /* counters */
  int count();   /* counting subroutine */
  int param[ 2 ];  /* parameter array */
  printf("tasktest (C) 1986 Ken Berry- All Rights Reserved\n");
  printf("Tele task scheduler: 1986 September 2 version (DDJ mod)\n\n");
  t__init();   /* initialize task scheduler */
  ctr1 = ctr2 = ctr3 = 0; /* initialize counters */
  param[ 0 ] = &ctr1;  /* create first task */
  param[ 1 ] = 1;
  t_crt( count, 2, ¶m, 256, 0, 0, 0);
  param[ 0 ] = &ctr2;  /* create second task */
  param[ 1 ] = 2;
  t_crt( count, 2, ¶m, 256, 0, 0, 0);
  while( !kbhit() )  /* loop until key depressed */
  {
    ++ctr3;   /* increment main loop count */
    printf("main = %d, task 1 = %d, task 2 = %d\n", ctr3, ctr1, ctr2 );
  }
  getch();   /* discard termination character */
  t__term();   /* terminate task scheduler */
  return _F;   /* return to MSvDOS */
}

count(ctr,inc)
int *ctr,inc;
{
  while(_T)   /* infinite loop */
  {
    *ctr += inc;  /* update counter */
  }
}



声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !