/***********************************
  (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
 $Log: mainf.c,v $
 * Revision 2.6  1994/03/02  13:25:56  lotos
 * new function: get parameters from command line
 *
 * Revision 2.5  1993/08/05  17:34:13  lotos
 * fix correct termination for specs with exit functionality
 *
 * Revision 2.4  1993/01/18  18:25:53  lotos
 * distribution issues
 *
 * Revision 2.3  1993/01/12  14:27:15  lotos
 * report an erro if number of actual arguments is wrong
 *
 * Revision 2.2  1992/11/17  17:27:06  lotos
 * var -> rav
 * success -> xto
 * distinguish kdatum / udatum
 *
 * Revision 2.1  1992/10/20  17:49:56  lotos
 * new KT evaluation algorithm
 * new Lbeta interface
 * cleaning, code optimization, space saving, bugs, ...
 *
 * Revision 1.7  1992/09/11  16:53:54  lotos
 * fix tree re-evaluation to take care of priorities
 *
 * Revision 1.6  1992/09/02  14:43:30  lotos
 * let eval be re-evaluated during wait
 *
 * Revision 1.5  92/03/04  14:52:32  lotos
 * 100 minor bugettes
 * 
 * Revision 1.4  92/02/29  13:25:46  lotos
 * miscellaneous bug fixing
 * 
 * Revision 1.3  92/02/12  18:47:27  lotos
 * ni idea, era una version que andaba por ahi ...
 * 
 * Revision 1.2  92/01/15  12:40:33  lotos
 * a bug in frames
 * change success and values
 * 
 * Revision 1.1  92/01/14  19:24:47  lotos
 * Initial revision
 * 
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: mainf.c,v 2.6 1994/03/02 13:25:56 lotos Exp $";
#endif

#include "swbus.h"
/* LINTLIBRARY */

  value_list xto = NULL; /* xto de exito  */
  int        suc_n = 0;

  board   Kt  = NULL;

  boolean eval_retry = FALSE;

  struct Konfig konfig= {NULL, 0, 0, 0};

  /*----------------------------------------------
  --        INTERFACE START FUNCTION            --
  ----------------------------------------------*/

 
/* get parameters from command line, to be applied to lbcinit() */

PUBLIC void
cmd2lbc(argc, argv, nvals, vals)
  int argc;
  char *argv[];
  int *nvals;
  value_list *vals;
{
  int i= 0;
  value_list p= NULL;

  --argc;
  ++argv;
  if (argc != specpar)
  { fprintf(stderr, "Wrong number of specification parameters\n");
    exit(1);
  }
  if (argc != 0)
  { p= (value_list) my_malloc(argc * sizeof(value));
    do
      if (!ud_eval(TSsorts[0][i], argv[i], &p[i]))
      { fprintf(stderr, "Specification parameter #%d is wrong\n", i + 1);
	exit(1);
      }
    while (++i < argc);
  }
  *nvals= i;
  *vals= p;
}


PUBLIC void
lbcinit (nvals, vals)
    int nvals;
    value_list vals;
{
  if (nvals != specpar) {
    fprintf(stderr, "Wrong number of specification parameters\n");
    exit (1);
  }
  mem_init ();
  arena_init ();
  Kt= initial_tree ();
  spec_param (nvals, vals);  
  bctbl (fson(Kt));
}
	 

PUBLIC void
  lbcend ()
{
   cut(Kt);
   Kt= NULL;
}

  /*----------------------------------------------
  -------------- MAIN FUNCTION BODY --------------                     
  ----------------------------------------------*/

PUBLIC  boolean
  sch ()
{
  register  offert    off;
  register  boolean   eval = FALSE;
  register  boolean   w_d  = FALSE;
  
  eval_tree ();
  
  while (!(eof_rq ())) {
    off   = get_rq ();
    switch  (offer_type(off)) {
    case b_ad :
      if (ad_ok(off)) {
	ad_gl (off);
	eval = TRUE;
      }
      break;
    case b_ex :
      if (exit_ok(off)) {
	ex_gl (off);
	eval = TRUE;
      }
      break;
    case b_ii :
      i_gl (off);
      eval = TRUE;
      break;
    case  b_dl :
      if (test_delay (off)){
	evol_annot (get_leave(off));
	eval = TRUE;
      } else 
	w_d = TRUE;
      break;
    case b_wt :
      if (test_wait (off))  {
	evol_annot (get_leave(off));
	eval = TRUE;
      } else 
	w_d = TRUE;
      break;
      default :
	dumpcore ("strange node in scheduler\n");
      exit (1);
      break;
    }
    
    if (((eof_rq () && w_d) || eval)){
      eval_tree ();
      eval = FALSE;
      w_d = FALSE;
    }
  }
    
  simp_stop();
  
  if (fson(Kt) == NULL || get_type(fson(Kt))== b_st)       /*  exit sch  */
    return  TRUE;			  /*  OK */
  else  {
    dumpcore ("***  DEADLOCK  ***");
    return  FALSE;			  /*  FAIL */
  }
} 

/******************
    returning codes
       0 :   end ok
       1 :   end no  ok
       2 :   synchronization 
       3 :   wait or delay evolve
       4 :   delay or wait waiting
******************/
int
step ()
{

  offert   off;
  boolean  synch    = FALSE;
  boolean  synch_wd = FALSE;
  boolean  wt_dl    = FALSE;
  
  eval_tree ();

  while (!(eof_rq () || synch )){
    off   = get_rq ();
    
    switch  (offer_type(off)) {
    case b_ad :
      if (ad_ok(off)) {
	ad_gl (off);
	synch = TRUE;
      } 
      break;
    case b_ex :
      if (exit_ok(off)) {
	ex_gl (off);
	synch = TRUE;
      }
      break;
    case b_ii :
      i_gl(off);
      synch = TRUE;
      break;
    case  b_dl :
      if (test_delay (off)) {
	evol_annot (get_leave(off));
	synch = TRUE;
	synch_wd = TRUE;
      }  else 
	wt_dl = TRUE;
      break;
    case b_wt :
      if (test_wait (off)) { 
	evol_annot (get_leave(off));
	synch = TRUE;
	synch_wd = TRUE;
      }  else 
	wt_dl = TRUE;
      break;
      default :
	dumpcore ("strange node in scheduler\n");
      break;
    }
  }



  if (!synch && !wt_dl) {  

    simp_stop();
    if (fson(Kt) == NULL || get_type(fson(Kt))== b_st)       /*  exit sch  */
      return (0);			  /*  OK */
    else {
      dumpcore ("***  DEADLOCK  ***");
      return (1);			  /*  FAIL */
    }
  }else {
    if (synch) {
      if (synch_wd)
	return (4);
      else
	return (2);
    } else
      return (3);
  }
}

 





