home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / xplatfrm / tierra / tierra.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-26  |  16.2 KB  |  627 lines

  1. /* tierra.c  28-10-91  main module of Tierra Synthetic Life Simulator */
  2. /** Tierra Simulator V3.0: Copyright (c) 1991 Thomas S. Ray **/
  3.  
  4. #include "license.h"
  5.  
  6. #ifndef lint
  7. static char     sccsid[] = "%W% %G%";
  8. #endif
  9.  
  10. #include "tierra.h"
  11. #include "declare.h"
  12. #include "soup_in.h"
  13. #include <sys/types.h>
  14. #include <fcntl.h>
  15. #include <signal.h>
  16. #ifdef unix
  17. #include <unistd.h>
  18. #endif
  19.  
  20. I32s          FindCell;
  21. I32s          itime, mtime;
  22. struct event  FindTime;
  23. int           run_flag;    /* NEW GLOBAL */
  24.  
  25. #define    _DBGMainModule
  26. #include "debug.h"        /* some useful debugging stuff */
  27. #undef    _DBGMainModule
  28.  
  29. #ifdef SOCKETS
  30.  
  31. #include "alreques.h"        /* request constants, ids, etc. */
  32. #include "allayer.h"        /* public header for AL Layer */
  33. #include "tlayer.h"        /* public header for T layer */
  34. #include "tlayerp.h"
  35.  
  36. static void    _t_memory_stats P_(( unsigned char which, void *indata,
  37.             int inlen, void **outdata, int *outdatalen ));
  38. static void    _t_sim_runcontrol P_(( unsigned char which, void *data,
  39.             int datalen ));
  40.  
  41. static void    _t_init_birthdeath P_(( ALtCLink *clink ));
  42.  
  43. static TtMonInitRoutine         _t_myinitroutines[] = {
  44.   { ALrdBirthDeath, _t_init_birthdeath }
  45. };
  46.  
  47. static void _t_init_birthdeath( clink )
  48.     ALtCLink  *clink;
  49. {
  50.   Pcells                ce;
  51.   I32s                  i;
  52.  
  53.   TRepBirthDeathInit( clink, 1 );
  54.   for ( i = 0; i < CellsSize; i++ ) {
  55.     ce = cells + i;
  56.     if ( ce->ld ) {
  57.       if ( ce->mm.s )
  58.         TRepBirthDirect( clink, ce->mm.p, ce->mm.s );
  59.       if ( ce->md.s )
  60.         TRepBirthDirect( clink, ce->md.p, ce->md.s );
  61.     }
  62.   }
  63.   TRepBirthDeathInit( clink, 0 );
  64. }
  65.  
  66. static void _t_memory_stats( which, indata, inlen, outdata, outdatalen )
  67.   u_char    which;
  68.   void        *indata;
  69.   int        inlen;
  70.   void        **outdata;
  71.   int        *outdatalen;
  72. {   ALrtMemStats  *ms;
  73.  
  74.     if (( ms = (ALrtMemStats *)ALMalloc(sizeof(ALrtMemStats))) ==
  75.         (ALrtMemStats *)NULL)
  76.     {   sprintf(mes[0], "_t_memory_stats: can't malloc");
  77.         FEError(1);
  78.         exit(1);
  79.     }
  80.     ms->memsize = SoupSize;
  81.     *outdata = ms;
  82.     *outdatalen = sizeof(ALrtMemStats);
  83. }
  84. /*-----------------------------------------------------------------------*/
  85. static void
  86. _t_query_org( which, indata, inlen, outdata, outdatalen )
  87.   u_char        which;
  88.   void          *indata;
  89.   int           inlen;
  90.   void          **outdata;
  91.   int           *outdatalen;
  92. {
  93.   ALrtQueryOrg          *qo;
  94.   ALrtOrgInfo           *oi;
  95.  
  96.   FILE *dan_fp;
  97.   I32s  tpci;
  98.   I8s   tmd;
  99.   I8s tstr[200];
  100.   Pgl g;
  101.   I32s  tl=1;
  102.   I32s dan_fd, tsz;
  103.  
  104.   qo = (ALrtQueryOrg *)indata;
  105.   fprintf( stderr, "QueryOrg: received query for [ %d : %d ]\n",
  106.            qo->start, qo->length );
  107.  
  108.   if ((IsFree(ad(qo->start))))
  109.      {
  110.        if (( oi = (ALrtOrgInfo *)ALMalloc( 1 )
  111.            ) == (ALrtOrgInfo *)NULL ) {
  112.          fprintf( stderr, "_t_query_org: can't malloc\n" );
  113.          exit( 1 );
  114.       }
  115.       *oi = '@';
  116.       *outdata = oi;
  117.       *outdatalen = 1;
  118.      }
  119.  else {
  120.     WhichCell(ad(qo->start),&tpci,&tmd);
  121.     if (tmd == 'm')
  122.     {
  123.     extract(tpci);
  124.     sprintf(tstr,"arg x %s%4.4d.gen %s\n",GenebankPath,
  125.             (cells+tpci)->d.gen.size, (cells+tpci)->d.gen.label);
  126.     system(tstr);
  127.  
  128.     sprintf(tstr,"%4.4d%s",(cells+tpci)->d.gen.size, 
  129.        (cells+tpci)->d.gen.label);
  130.     
  131.     dan_fd = open(tstr,O_RDONLY);
  132.     if( dan_fd < 0 ) {
  133.        fprintf(stderr,"temp gene file can't read");
  134.         perror("moo");
  135.        exit(-666);
  136.        }
  137.      tsz = (int)lseek(dan_fd,0L,SEEK_END); 
  138.      lseek(dan_fd,0L,SEEK_SET); 
  139.      if (( oi = (ALrtOrgInfo *)ALMalloc( (tsz ) + 20)  
  140.         ) == (ALrtOrgInfo *)NULL ) {
  141.       fprintf( stderr, "_t_query_org: can't malloc\n" );
  142.       exit( 1 );
  143.     }
  144.     *oi = ' ';
  145.     tl = read(dan_fd,oi,tsz) ;
  146.     if (tl < 0){
  147.        fprintf(stderr,"temp gene file can't read");
  148.         perror("moo");
  149.        exit(-666);
  150.        }
  151.     close(dan_fd);   
  152.     sprintf(tstr,"rm %4.4d%s\n",(cells+tpci)->d.gen.size, 
  153.        (cells+tpci)->d.gen.label);
  154.     system(tstr); 
  155.     *outdata = oi;
  156.     *outdatalen = tsz +1; 
  157.     }
  158.     else
  159.     {
  160.      if (( oi = (ALrtOrgInfo *)ALMalloc(100)  
  161.         ) == (ALrtOrgInfo *)NULL ) {
  162.       fprintf( stderr, "_t_query_org: can't malloc\n" );
  163.       exit( 1 );
  164.       }
  165.     sprintf(oi,"\nchild data: yet yet able to display\n\n");
  166.     *outdata = oi;
  167.     *outdatalen = 100;
  168.     }
  169.  
  170. }
  171. }
  172.  
  173.  
  174.  
  175. /*-----------------------------------------------------------------------*/
  176. /* this routine is nto finished, but helps in monitoring runs
  177.    till the tty version of ov is ready  */
  178. static void
  179. _t_query_size(size_class)
  180. I32s size_class;
  181. {
  182. I32s top_buf,tc,tl,c,t,thit;
  183. typedef struct size_buf {
  184.    I32s count;
  185.    I8s *gene;
  186.    I32s moves;
  187.    I32s flags;
  188.    I32s bits;
  189.    } bf;
  190.    bf buf[10];
  191.  
  192. if((size_class < 1) || (size_class > 20000)) return;
  193.  
  194. thit = 0;
  195. top_buf = -1;
  196.  
  197. for(t=0; t< 10; t++)
  198.    {
  199.    buf[t].count=0;
  200.    buf[t].moves=0;
  201.    buf[t].gene=NULL;
  202.    buf[t].bits=0;
  203.    buf[t].flags=0;
  204.    }
  205.  
  206. for(c = 2; c < CellsSize; c++)
  207.    {
  208.    if (
  209.       ((cells+c)->ld) &&
  210.       ((cells+c)->mm.s == size_class)) 
  211.       {
  212.       for(t = 0; t < 10; t++)
  213.      {
  214.      if (buf[t].gene == NULL ) { thit = 0; t = 500; break;}
  215.          if (strcmp((cells+c)->d.gen.label,buf[t].gene)== 0 )
  216.         {
  217.         thit = 1;
  218.             buf[t].count++;
  219.         buf[t].flags += (cells+c)->d.flags - (cells+c)->d.d1.flags;
  220.         buf[t].moves += (cells+c)->d.mov_daught;
  221.             /* buf[t].bits |= (cells+c)->d.bits; */
  222.         t = 500;
  223.  
  224.         }
  225.        }
  226.       if (thit== 0)
  227.             {
  228.         thit =1;
  229.         top_buf += (top_buf < 11) ? 1 : 0;
  230.         if (top_buf > 10) break;
  231.             buf[top_buf].gene = (cells+c)->d.gen.label;
  232.             buf[top_buf].count++;
  233.             /* buf[top_buf].bits |= (cells+c)->d.bits;  */
  234.             buf[top_buf].flags += (cells+c)->d.flags - (cells+c)->d.d1.flags;
  235.             buf[top_buf].moves += (cells+c)->d.mov_daught;
  236.             }
  237.  
  238.       }
  239.    }
  240.  sprintf(mes[0],"==========================================================");
  241.  sprintf(mes[1],"TIERRA: Size Class %d (first 10)",size_class);
  242.  sprintf(mes[2],"==========================================================");
  243.  sprintf(mes[3],"Gene:\t#\t%% Mem\tErrs\tMove\tBits");
  244.  FEError(4);
  245.  
  246.    for(t= 0; t < 10; t++)
  247.       {
  248.       if (buf[t].count < 1) break;
  249.       sprintf(mes[0],"%3.3s\t%d\t%d\t%d\t%d\t%d",
  250.     buf[t].gene,
  251.     buf[t].count,
  252.     (int) (100.0 * buf[t].count * size_class / SoupSize),
  253.     (int) (buf[t].flags / buf[t].count),
  254.     (int) (buf[t].moves / buf[t].count),
  255.     buf[t].bits
  256.     );
  257.       FEError(1); 
  258.       }
  259.     }
  260. /*-----------------------------------------------------------------------*/
  261.  
  262. static void _t_sim_runcontrol( which, data, datalen )
  263.   u_char    which;
  264.   void        *data;
  265.   int        datalen;
  266. {   switch (which)
  267.     {   case ALrsPauseSim:  run_flag = 0; break;
  268.         case ALrsResumeSim: run_flag = 1; break;
  269.         default:
  270.         {   sprintf(mes[0], "_t_sim_runcontrol: unknown state request: %d",
  271.                 which);
  272.             FEError(1);
  273.         }
  274.         break;
  275.     }
  276. }
  277.  
  278. #endif    /* SOCKETS */
  279.  
  280. /* THE CODE IN SHUTD IS NOT IS NOT FINISHED ,
  281.    when I get acces to a pc, i will fully test it out ... */
  282.  
  283. void shutd(sig,code,scp,addr)
  284.     I32s  sig,code;
  285.     /* struct sigcontext *scp; */
  286.     I32s *scp; /* DO NOT USE !!!!! */
  287.     I8s  *addr;
  288. {
  289.    I8s  answer;
  290.    I32s tsz;
  291.    I8s  data[85];
  292.  
  293.    sprintf(mes[0],"\tTIERRA: trapped a signal! # %d @ %d",sig, InstExe.i);
  294.    FEMessage(1);
  295. #ifdef SOCKETS
  296.    sprintf(mes[0],"\tTIERRA: port %d",TS.port);
  297.    FEMessage(1);
  298. #endif
  299.    sprintf(mes[0],"\tTIERRA: trapped a signal! # %d @ %d",sig, InstExe.i);
  300.    FEError(1);
  301. #ifdef SOCKETS
  302.    sprintf(mes[0],"\tTIERRA: port %d",TS.port);
  303.    FEError(1);
  304. #endif
  305.    sprintf(mes[0],"Variable | siZe info | Save soup | save & Quit | ");
  306.    sprintf(mes[1],"Exit     | Continue  | {v,z,s,q,e,c}");
  307.    FEError(2);
  308.    fgets(data,84,stdin);
  309.    sscanf(data,"%c", &answer);
  310.    if (answer == 'e') exit(-666);
  311.    if (answer == 'v') 
  312.    {
  313.       sprintf(mes[0],"To alter any global variable from soup_in, type\n");
  314.       sprintf(mes[1],"the variable name (using proper case), a space,\n");
  315.       sprintf(mes[2],"an equal sign, a space, and the new value.\n");
  316.       sprintf(mes[3],"Use no space at start of line.  Some examples:\n");
  317.       sprintf(mes[4],"alive = 0");
  318.       sprintf(mes[5],"DistProp = .6");
  319.       sprintf(mes[6],"GenebankPath = newpath/");
  320.       FEError(7);
  321.       fgets(data,84,stdin);
  322.       if (!GetAVar(data))
  323.       {   sprintf(mes[0],"Not a valid soup_in variable: %s", data);
  324.           FEError(1);
  325.       }
  326.    }
  327.  
  328.    if (answer == 'z')
  329.       {
  330.       sprintf(mes[0],"Enter a size class ( eg: 80 ) to examine ");
  331.       FEError(1);
  332.       fgets(data,84,stdin);
  333.       sscanf(data,"%d", &tsz);
  334. /*    _t_query_size(tsz); */
  335.       }
  336.  
  337.    if (answer == 's')
  338.    {  WriteSoup(1);
  339.       sprintf(mes[0],"TIERRA Soup Written ...");
  340.       FEError(1);
  341.    }
  342.    if (answer == 'q')
  343.    {  WriteSoup(1);
  344.       sprintf(mes[0],"TIERRA Soup Written ...");
  345.       FEError(1);
  346.       exit(-333);
  347.    }
  348.    sprintf(mes[0],"Continuing from interupt...");
  349.    FEError(1);
  350. }
  351.  
  352. int main(argc,argv)
  353.     int   argc;
  354.     char  *argv[];
  355. {
  356.  
  357.     signal(SIGINT, shutd);
  358.  
  359.     if (argc > 1) 
  360.     {   sprintf(soup_fn,"%s", argv[1]);
  361.     }
  362.     else
  363.     {
  364. #ifdef IBM3090
  365.         strcpy(soup_fn,"soup_in.io.d");
  366. #else
  367.         strcpy(soup_fn,"soup_in");
  368. #endif
  369.     }
  370. #ifdef SOCKETS
  371.     setpgrp( 0, getpid() );    /* SHOULD BE DONE AS PART OF SV!!! */
  372.  
  373.     TInitialise( _t_myinitroutines, 1, argc, argv );
  374.  
  375.     TRegisterQueryhandler( ALrqMemStats, _t_memory_stats );
  376.     TRegisterQueryhandler( ALrqQueryOrg, _t_query_org );
  377.     /* TRegisterQueryhandler( ALrqQueryOrg, _t_query_size ); */
  378.  
  379.     TRegisterStatehandler( ALrsPauseSim, _t_sim_runcontrol );
  380.     TRegisterStatehandler( ALrsResumeSim, _t_sim_runcontrol );
  381.  
  382. #endif
  383.  
  384.     run_flag = 1;
  385.     GetSoup(); 
  386.     life();
  387.     WriteSoup(1);
  388.     return 0;
  389. }
  390.  
  391. void life() /* doles out time slices and death */
  392. {   while(InstExe.m < alive)
  393.     {   if ( run_flag == 1 )
  394.         {   (*slicer)();
  395.             ReapCheck();
  396.         }
  397.         else
  398.             sleep( 1 );
  399. #ifdef SOCKETS
  400.         TCheckRequestQueue();
  401. #endif
  402.     }
  403. }
  404.  
  405. void TimeSlice(ci, size_slice)
  406. I32s  ci, size_slice;
  407. {   Pcells  ce = cells + ci;
  408.     I16s          di;  /* decoded instruction */
  409.  
  410.     ce->d.ib += size_slice;
  411.     for(is.ts = ce->d.ib; is.ts > 0; )
  412.     {   di = FetchDecode(ci);
  413.         (*id[di].execute)(ci);
  414.         ce = cells + ci;
  415.         IncrementIp(ci);
  416.         SystemWork(ci);
  417.     }
  418. }
  419.  
  420. I16s FetchDecode(ci)
  421. I32s  ci;
  422. {   Pcells  ce = cells + ci;
  423.     I16s    di;
  424.  
  425.     di = soup[ce->c.ip][ce->c.tr].inst;
  426.     is.oip = ce->c.ip;
  427.     (*id[di].parse)(ci);
  428.     return di;
  429. }
  430.  
  431. void IncrementIp(ci)
  432. I32s  ci;
  433. {   Pcells  ce = cells + ci;
  434.  
  435.     ce->c.ip += is.iip;
  436.     ce->c.ip = ad(ce->c.ip);
  437.     ce->d.ib -= is.dib;
  438.     is.ts -= is.dib;
  439.     if (WatchExe)
  440.         GenExExe(ci, is.oip);
  441. }
  442.  
  443. void SystemWork(ci)
  444. I32s  ci;
  445.     (cells + ci)->d.inst++;
  446.     if((cells + ci)->c.fl)
  447.     {   (cells + ci)->d.flags++;
  448.     if(!(cells + ci)->d.dm)
  449.             UpRprIf(ci);
  450.     }
  451.     CountMutRate++;
  452.     if(CountMutRate >= RateMut && RateMut)
  453.     {   mutate();
  454.         TotMut++;
  455.         CountMutRate = tlrand() % RateMut;
  456.     }
  457.     if(isolate) extract(extr);
  458.     InstExe.i++;
  459.     if(InstExe.i > 1000000L)
  460.     {   InstExe.i %= 1000000L; InstExe.m++;
  461.         if(DropDead && (InstExe.m > LastDiv.m + DropDead))
  462.         {   sprintf(mes[0],
  463.                 "SystemWork: soup has died, saving system to disk");
  464.             FEMessage(1);
  465.             WriteSoup(1);
  466.             exit(0);
  467.         }
  468.         if(!(InstExe.m % SaveFreq)) WriteSoup(0);
  469.         plan();
  470.     }
  471. }
  472.  
  473. void mutate()
  474. {   Ind   i;
  475.  
  476.     i = tlrand() % SoupSize;
  477.     mut_site(soup + i, tcrand() % 2);
  478.     MutBookeep(i);
  479. }
  480.  
  481. void mut_site(s, t)
  482. HpInst  s;
  483. I8s     t;
  484. {   s[0][t].inst ^= (1 << (tirand() % (I16s) INSTBITNUM)); }
  485.  
  486. void ReapCheck() /* kill some cells if necessary */
  487. {   I32s  i, t, dtime;
  488.     struct event  result;
  489.  
  490.     if(DistFreq < 0 || !reaped || (!DistNext.m && !DistNext.i)) return;
  491.     dtime = SubEvent(&InstExe, &DistNext, &result);
  492.     if(dtime > 0)
  493.     {   Disturb = InstExe;
  494.         DistNext.m = DistNext.i = 0L;
  495.         t = (I32s) (DistProp * (float) NumCells);
  496.         if(t == NumCells)
  497.             t--;
  498.         for(i = 0; i < t; i++)
  499.             reaper(0);
  500.     }
  501. }
  502.  
  503. void reaper(ex)
  504. I8s  ex;  /* is a creature executing now ? */
  505. {   Pcells  ce; /* cell to be reaped */
  506.     I32s    l_top, rtime; /* local TopReap */
  507.     struct event  result;
  508.     Pcells  nc; /* daughter of cell to be reaped */
  509.     FpInst  in;
  510.     I32s    i, j;
  511.  
  512.     if(ex && TopReap == ThisSlice)
  513.         DownReaper(TopReap);
  514.     if(ex && DistFreq > 0 && !DistNext.m && !DistNext.i)
  515.     {   rtime = SubEvent(&InstExe, &Disturb, &result);
  516.         rtime = (I32s) (DistFreq * (float) rtime);
  517.         DistNext = Disturb = InstExe;
  518.         DistNext.m += rtime / 1000000L;
  519.         DistNext.i += rtime % 1000000L;
  520.         DistNext.m += DistNext.i / 1000000L;
  521.         DistNext.i %= 1000000L;
  522.     }
  523.     if(NumCells == 1)
  524.     {   sprintf(mes[0],
  525.             "Tierra reaper error 0, attempt to reap last creature");
  526.         if (!hangup)
  527.             FEMessage(1);
  528.         else
  529.         {   sprintf(mes[1],"core being saved");
  530.             FEMessage(2);
  531.         }
  532.         while(hangup) ;
  533.         WriteSoup(1);
  534.         exit(0);
  535.     }
  536.     ce = cells + TopReap; l_top = TopReap;
  537. #ifdef ERROR
  538.     if(!ce->ld || !NumCells || (!ce->mm.s && !ce->md.s))
  539.     {   sprintf(mes[0],
  540.             "Tierra reaper error 1, attempt to reap non-existant cell");
  541.         if (!hangup)
  542.             FEMessage(1);
  543.         else
  544.         {   sprintf(mes[1],"core being saved");
  545.             FEMessage(2);
  546.         }
  547.         while(hangup) ;
  548.         WriteSoup(1);
  549.         exit(0);
  550.     }
  551. #endif
  552.     if(ce->mm.s)
  553.     {
  554. #ifdef ERROR
  555.         if(ce->mm.p < 0 || ce->mm.p >= SoupSize)
  556.         {   sprintf(mes[0],
  557.     "Tierra reaper error 2: attemp to deallocate main memory not in soup");
  558.             if (!hangup)
  559.                 FEMessage(1);
  560.             else
  561.             {   sprintf(mes[1],"core being saved");
  562.                 FEMessage(2);
  563.             }
  564.             while(hangup) ;
  565.             WriteSoup(1);
  566.             exit(0);
  567.         }
  568. #endif
  569.         for(i = 0; i < ce->mm.s; i++)
  570.         {   in = soup + ad(ce->mm.p + i);
  571.             for (j = 0; j < PLOIDY; j++)
  572.                 in[0][j].write = in[0][j].read = in[0][j].exec = 0;
  573.         }
  574.         MemDealloc(ce->mm.p,ce->mm.s);
  575.     }
  576.     if(ce->md.s)
  577.     {
  578. #ifdef ERROR
  579.         if(ce->md.p < 0 || ce->md.p >= SoupSize)
  580.         {   sprintf(mes[0],"Tierra reaper error 3: attemp to deallocate \
  581.                 daughter memory not in soup");
  582.             if (!hangup)
  583.                 FEMessage(1);
  584.             else
  585.             {   sprintf(mes[1],"core being saved");
  586.                 FEMessage(2);
  587.             }
  588.             while(hangup) ;
  589.             WriteSoup(1);
  590.             exit(0);
  591.         }
  592. #endif
  593.         for(i = 0; i < ce->mm.s; i++)
  594.         {   in = soup + ad(ce->mm.p + i);
  595.             for (j = 0; j < PLOIDY; j++)
  596.                 in[0][j].write = in[0][j].read = in[0][j].exec = 0;
  597.         }
  598.         if(ce->d.ni > -1) /* cleanup daughter cpu */
  599.         {   nc = cells + ce->d.ni;
  600.             if(nc->d.is) /* cleanup daughter instruction pointer */
  601.                 RmvFrmSlicer(ce->d.ni);
  602.             NumCells--;
  603.             InitCell(ce->d.ni);
  604.         }
  605.         MemDealloc(ce->md.p,ce->md.s);
  606.     }
  607.     RmvFrmSlicer(l_top);
  608.     RmvFrmReaper(l_top);
  609.     ReapBookeep(l_top);
  610. /*  InitCell(ci); done in ReapBookeep(ci); */
  611. }
  612.  
  613. I32s SubEvent(event1, event2, result) /* subtract e2 from e1 */
  614. struct event  *event1, *event2, *result;
  615. {   result->m =  event1->m - event2->m;
  616.     result->m += (event1->i - event2->i) / 1000000L;
  617.     result->i =  (event1->i - event2->i) % 1000000L;
  618.     if(result->m <= 0)
  619.         return result->i + (result->m * 1000000L);
  620.     if(result->i < 0)
  621.     {   --result->m;
  622.         result->i += 1000000L;
  623.     }
  624.     return result->i + (result->m * 1000000L);
  625. }
  626.