init_xsb.c

00001 /* File:      init_xsb.c
00002 ** Author(s): Warren, Swift, Xu, Sagonas, Johnson, Rao
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
00006 ** Copyright (C) ECRC, Germany, 1990
00007 ** 
00008 ** XSB is free software; you can redistribute it and/or modify it under the
00009 ** terms of the GNU Library General Public License as published by the Free
00010 ** Software Foundation; either version 2 of the License, or (at your option)
00011 ** any later version.
00012 ** 
00013 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00014 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00015 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00016 ** more details.
00017 ** 
00018 ** You should have received a copy of the GNU Library General Public License
00019 ** along with XSB; if not, write to the Free Software Foundation,
00020 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00021 **
00022 ** $Id: init_xsb.c,v 1.98 2006/07/14 16:49:36 tswift Exp $
00023 ** 
00024 */
00025 
00026 
00027 #include "xsb_config.h"
00028 #include "xsb_debug.h"
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 
00034 #ifdef WIN_NT
00035 #include <windows.h>
00036 #include <direct.h>
00037 #include <io.h>
00038 #include <fcntl.h>
00039 #include <process.h>
00040 #else
00041 #include <unistd.h>     
00042 #include <stddef.h>
00043 #include <sys/wait.h>
00044 #endif
00045 
00046 #include "auxlry.h"
00047 #include "cell_xsb.h"
00048 #include "error_xsb.h"
00049 #include "inst_xsb.h"
00050 #include "psc_xsb.h"
00051 #include "hash_xsb.h"
00052 #include "heap_xsb.h"
00053 #include "memory_xsb.h"
00054 #include "register.h"
00055 #include "tries.h"
00056 #include "choice.h"
00057 #include "flags_xsb.h"
00058 #include "loader_xsb.h"
00059 #include "extensions_xsb.h"
00060 #include "macro_xsb.h"
00061 #include "tr_utils.h"
00062 #include "export.h"
00063 #include "io_builtins_xsb.h"
00064 #include "timer_defs_xsb.h"
00065 #include "sig_xsb.h"
00066 #include "thread_xsb.h"
00067 #include "varstring_xsb.h"
00068 #include "struct_manager.h"
00069 #include "trie_internals.h"
00070 /*-----------------------------------------------------------------------*/
00071 
00072 /* Sizes of the Data Regions in K-byte blocks
00073    ------------------------------------------ */
00074 #ifdef BITS64
00075 #define PDL_DEFAULT_SIZE         (64*2)
00076 #define GLSTACK_DEFAULT_SIZE    (768*2)
00077 #define TCPSTACK_DEFAULT_SIZE   (768*2)
00078 #define COMPLSTACK_DEFAULT_SIZE  (64*2)
00079 #else
00080 #define PDL_DEFAULT_SIZE         64
00081 #define GLSTACK_DEFAULT_SIZE    768
00082 #define TCPSTACK_DEFAULT_SIZE   768
00083 #define COMPLSTACK_DEFAULT_SIZE  64
00084 #endif
00085 
00086 #ifndef fileno                          /* fileno may be a  macro */
00087 extern int    fileno(FILE *f);          /* this is defined in POSIX */
00088 #endif
00089 /* In WIN_NT, this gets redefined into _fdopen by wind2unix.h */
00090 extern FILE *fdopen(int fildes, const char *type);
00091 
00092 #if defined(GENERAL_TAGGING)
00093 extern void extend_enc_dec_as_nec(void *,void *);
00094 #endif
00095 
00096 long pspacesize[NUM_CATS_SPACE] = {0};  /* actual space dynamically allocated by loader.c */
00097 
00098 /* The SLG-WAM data regions
00099    ------------------------ */
00100 #ifndef MULTI_THREAD
00101 System_Stack
00102 pdl = {NULL, NULL, 0,
00103        PDL_DEFAULT_SIZE},             /* PDL                   */
00104   glstack = {NULL, NULL, 0,
00105              GLSTACK_DEFAULT_SIZE},     /* Global + Local Stacks */
00106     tcpstack = {NULL, NULL, 0,
00107                 TCPSTACK_DEFAULT_SIZE},   /* Trail + CP Stack      */
00108       complstack = {NULL, NULL, 0,
00109                     COMPLSTACK_DEFAULT_SIZE};   /* Completion Stack  */
00110 #else
00111 static System_Stack
00112 init_pdl = {NULL, NULL, 0,
00113        PDL_DEFAULT_SIZE},             /* PDL                   */
00114   init_glstack = {NULL, NULL, 0,
00115              GLSTACK_DEFAULT_SIZE},     /* Global + Local Stacks */
00116     init_tcpstack = {NULL, NULL, 0,
00117                 TCPSTACK_DEFAULT_SIZE},   /* Trail + CP Stack      */
00118       init_complstack = {NULL, NULL, 0,
00119                     COMPLSTACK_DEFAULT_SIZE};   /* Completion Stack  */
00120 #endif
00121 
00122 Exec_Mode xsb_mode;     /* How XSB is run: interp, disassem, user spec, etc. */
00123 int max_threads_glc;
00124 
00125 int xsb_profiling_enabled = 0;
00126 
00127 /* from pathname_xsb.c */
00128 DllExport extern char * call_conv strip_names_from_path(char*, int);
00129 
00130 Cell answer_return_inst;
00131 Cell resume_compl_suspension_inst;
00132 Cell resume_compl_suspension_inst2;
00133 Cell check_complete_inst;
00134 Cell hash_handle_inst;
00135 Cell fail_inst;
00136 Cell dynfail_inst;
00137 Cell trie_fail_unlock_inst;
00138 Cell halt_inst;
00139 Cell proceed_inst;
00140 
00141 #ifdef MULTI_THREAD
00142 /* Used to create detached thread -- process global. */
00143 pthread_attr_t detached_attr_gl;
00144 
00145 #endif
00146 
00147 extern void reset_stat_total(void); 
00148 extern void perproc_reset_stat(void); 
00149 
00150 extern double realtime_count_gl;
00151 
00152 
00153 /* these three are from orient_xsb.c */
00154 extern char *install_dir_gl; 
00155 extern char *xsb_config_file_gl; /* configuration.P */
00156 extern char *user_home_gl; /* the user HOME dir or install dir, if HOME is null */
00157 
00158 /*==========================================================================*/
00159 
00160 static void display_file(char *infile_name)
00161 {
00162   FILE *infile;
00163   char buffer[MAXBUFSIZE];
00164 
00165   if ((infile = fopen(infile_name, "r")) == NULL) {
00166     xsb_error("\nCan't open `%s'; XSB installation might be corrupted\n",
00167               infile_name);
00168     exit(1);
00169   }
00170 
00171   while (fgets(buffer, MAXBUFSIZE-1, infile) != NULL)
00172     fprintf(stdmsg, "%s", buffer);
00173 
00174   fclose(infile);
00175 }
00176 
00177 
00178 static void version_message(void)
00179 {
00180   char licensemsg[MAXPATHLEN], configmsg[MAXPATHLEN];
00181   char *stripped_config_file;
00182 
00183   sprintf(licensemsg, "%s%cetc%ccopying.msg", install_dir_gl, SLASH, SLASH);
00184   stripped_config_file = strip_names_from_path(xsb_config_file_gl, 2);
00185   sprintf(configmsg, "%s%cbanner.msg", 
00186           stripped_config_file, SLASH);
00187 
00188   display_file(configmsg);
00189   fprintf(stdmsg, "\n");
00190   display_file(licensemsg);
00191 
00192   exit(0);
00193 }
00194 
00195 static void help_message(void)
00196 {
00197   char helpmsg[MAXPATHLEN];
00198 
00199   sprintf(helpmsg, "%s%cetc%chelp.msg", install_dir_gl, SLASH, SLASH);
00200   puts("");
00201   display_file(helpmsg);
00202 
00203   exit(0);
00204 }
00205 
00206 
00207 /*==========================================================================*/
00208 
00209 /* Initialize System Flags
00210    ----------------------- */
00211 static void init_flags(CTXTdecl)
00212 {
00213   int i;
00214   for (i=0; i<MAX_FLAGS; i++) flags[i] = 0;
00215   for (i=0; i<MAX_PRIVATE_FLAGS; i++) pflags[i] = 0;
00216   pflags[SYS_TIMER]  = TIMEOUT_ERR; /* start with expired timer */
00217   flags[BANNER_CTL] = 1;           /* a product of prime numbers; each prime
00218                                       determines which banner isn't shown */
00219   flags[NUM_THREADS] = 1;          /* 1 thread will be run at start */
00220   pflags[BACKTRACE] = 1;           /* Backtrace on error by default */
00221   pflags[CLAUSE_GARBAGE_COLLECT] = 1;           /* Clause GC on by default */
00222 }
00223 
00224 /*==========================================================================*/
00225 
00226 /* In MT engine, now providing a separate mutex (default type) for
00227    each io stream.  */
00228 
00229 char    standard_input_glc[]      = "stdin";
00230 char    standard_output_glc[]      = "stdout";
00231 char    standard_error_glc[]      = "stderr";
00232 char    standard_warning_glc[]      = "stdwarn";
00233 char    standard_message_glc[]      = "stdmsg";
00234 char    standard_debug_glc[]      = "stddbg";
00235 char    standard_feedback_glc[]      = "stdfdbk";
00236 
00237 static void init_open_files(void)
00238 {
00239   int i, msg_fd, dbg_fd, warn_fd, fdbk_fd;
00240 
00241 #ifdef MULTI_THREAD
00242   pthread_mutexattr_t attr_std ;
00243   pthread_mutexattr_init( &attr_std ) ;
00244 #endif
00245 
00246   open_files[0].file_ptr = stdin;
00247   open_files[0].io_mode = 'r';
00248   open_files[0].stream_type = CONSOLE_STREAM;
00249   open_files[0].file_name = standard_input_glc;
00250 
00251   open_files[1].file_ptr = stdout;
00252   open_files[1].io_mode = 'w';
00253   open_files[1].stream_type = CONSOLE_STREAM;
00254   open_files[1].file_name = standard_output_glc;
00255 
00256   open_files[2].file_ptr = stderr;
00257   open_files[2].io_mode = 'w';
00258   open_files[2].stream_type = CONSOLE_STREAM;
00259   open_files[2].file_name = standard_error_glc;
00260 
00261   /* stream for xsb warning msgs */
00262   if ((warn_fd = dup(fileno(stderr))) < 0)
00263     xsb_exit("Can't open the standard stream for warnings\n");
00264   stdwarn = fdopen(warn_fd, "w");
00265   open_files[3].file_ptr = stdwarn;
00266   open_files[3].io_mode = 'w';
00267   open_files[3].stream_type = CONSOLE_STREAM;
00268   open_files[3].file_name = standard_warning_glc;
00269 
00270   /* stream for xsb normal msgs */
00271   if ((msg_fd = dup(fileno(stderr))) < 0)
00272      xsb_exit("Can't open the standard stream for messages\n");
00273   stdmsg = fdopen(msg_fd, "w");
00274   open_files[4].file_ptr = stdmsg;
00275   open_files[4].io_mode = 'w';
00276   open_files[4].stream_type = CONSOLE_STREAM;
00277   open_files[4].file_name = standard_message_glc;
00278 
00279   /* stream for xsb debugging msgs */
00280   if ((dbg_fd = dup(fileno(stderr))) < 0)
00281      xsb_exit("Can't open the standard stream for debugging messages\n");
00282   stddbg = fdopen(dbg_fd, "w");
00283   open_files[5].file_ptr = stddbg;
00284   open_files[5].io_mode = 'w';
00285   open_files[5].stream_type = CONSOLE_STREAM;
00286   open_files[5].file_name = standard_debug_glc;
00287 
00288   /* stream for xsb feedback msgs */
00289   if ((fdbk_fd = dup(fileno(stdout))) < 0)
00290      xsb_exit("Can't open the standard stream for XSB feedback messages\n");
00291   stdfdbk = fdopen(fdbk_fd, "w");
00292   open_files[6].file_ptr = stdfdbk;
00293   open_files[6].io_mode = 'w';
00294   open_files[6].stream_type = CONSOLE_STREAM;
00295   open_files[6].file_name = standard_feedback_glc;
00296 
00297   /* NT doesn't seem to think that dup should preserve the buffering mode of
00298      the original file. So we make all new descriptors unbuffered -- dunno if
00299      this is good or bad. Line-buffering _IOLBF is the coarsest that can be
00300      allowed. Without the buffering NT users won't see anything on the
00301      screen. -mk */
00302   /* We should use setvbuf, but -no-cygwin doesn't seem to do the
00303      right thing with it, but it does with setbuf.... go figure. -dsw */
00304 
00305   setbuf(stdmsg, NULL);
00306   setbuf(stdwarn, NULL);
00307   setbuf(stddbg, NULL);
00308   setbuf(stdfdbk, NULL);
00309   setbuf(stderr, NULL);
00310 
00311   for (i=MIN_USR_OPEN_FILE; i < MAX_OPEN_FILES; i++) open_files[i].file_ptr = NULL;
00312 
00313 #ifdef MULTI_THREAD
00314   if( pthread_mutexattr_settype( &attr_std, PTHREAD_MUTEX_RECURSIVE_NP )<0 )
00315     xsb_exit( "[THREAD] Error initializing mutexes" ) ;
00316 
00317   for( i = 0; i < MAX_OPEN_FILES ; i++ ) {
00318     pthread_mutex_init(OPENFILES_MUTEX(i) , &attr_std ) ;
00319   }
00320 #endif
00321 }
00322 
00323 /*==========================================================================*/
00324 
00325 /* if command line option is long --optionname, then the arg here is
00326    'optionname'. Process it and return.
00327 */
00328 static void process_long_option(char *option,int *ctr,char *argv[],int argc)
00329 {
00330   if (0==strcmp(option, "nobanner")) {
00331     flags[BANNER_CTL] *= NOBANNER;
00332   } else if (0==strcmp(option, "quietload")) {
00333     flags[BANNER_CTL] *= QUIETLOAD;
00334   } else if (0==strcmp(option, "noprompt")) {
00335     flags[BANNER_CTL] *= NOPROMPT;
00336   } else if (0==strcmp(option, "help")) {
00337     help_message();
00338   } else if (0==strcmp(option, "version")) {
00339     version_message();
00340   } else if (0==strcmp(option, "max_threads")) {
00341     if ((int) (*ctr) < argc) {
00342       (*ctr)++;
00343       sscanf(argv[*ctr], "%d", &max_threads_glc);
00344     }
00345     else xsb_warn("Missing size value for --max_threads");
00346   }
00347 
00348   return;
00349 }
00350 
00351 /*==========================================================================*/
00352 /* Currently done on process startup after init_para(). Do not use elsewhere, 
00353    to avoid problems with multi-threading. */
00354 
00355 FILE *stream_err, *stream_out; 
00356 
00357 void perform_IO_Redirect(CTXTdeclc int argc, char *argv[])
00358 {
00359 int i;
00360 
00361 init_flags(CTXT);       // We set one of them
00362 
00363 /*
00364         This needs to be done early so that embedded applications can catch meaningful 
00365         initialization failures in the log files
00366 */
00367 for (i=1; i<argc; i++)
00368         { /* check to see if should redirect output */
00369         if (!strcmp(argv[i],"-q"))
00370                 {
00371                 stream_err = freopen("XSB_errlog", "w+", stderr);
00372                 flags[STDERR_BUFFERED] = 1;
00373                 stream_out = freopen("XSB_outlog", "w", stdout);
00374                 break;
00375                 }
00376         }
00377 }
00378 
00379 /*==========================================================================*/
00380 /* Initialize System Parameters: This is done only on process start
00381  * up, not on thread startup */
00382 
00383 char *init_para(CTXTdeclc int argc, char *argv[])
00384 {
00385   int i;
00386   char warning[80];
00387   /* Boot module is usually the loader that loads the Prolog code of XSB.
00388   ** Or it can be a code to disassemble.
00389   ** Cmd loop driver is usually the XSB interpreter (x_interp.P).
00390   ** However, it can be any program that communicates with XSB and drives its
00391   ** comand loop.
00392   */
00393   char *boot_module, *cmd_loop_driver;
00394   char cmd_line_goal[MAXBUFSIZE+1] = "";
00395   int  strlen_instdir, strlen_initfile, strlen_2ndfile;
00396 
00397 #ifdef MULTI_THREAD
00398   init_system_mutexes() ;
00399   init_system_threads(th) ;
00400 #endif
00401 
00402   init_open_files();
00403 
00404   /* init statistics. structures */
00405   perproc_reset_stat();
00406 
00407 #ifndef MULTI_THREAD
00408   reset_stat_total();
00409 #endif
00410 
00411   max_threads_glc = MAX_THREADS;
00412   pflags[STACK_REALLOC] = TRUE;
00413 #ifdef GC
00414   pflags[GARBAGE_COLLECT] = INDIRECTION_SLIDE_GC;
00415 #else
00416   pflags[GARBAGE_COLLECT] = NO_GC;
00417 #endif
00418   flags[DCG_MODE] = XSB_STYLE_DCG;
00419 
00420   /* Set default Prolog files. 
00421      File extension XSB_OBJ_EXTENSION_STRING added later. */
00422 #ifdef WIN_NT
00423   boot_module = "\\syslib\\loader";
00424 #else
00425   boot_module = "/syslib/loader";
00426 #endif
00427 
00428   /* File extensions are automatically added for Loader-loaded files. */
00429 #ifdef WIN_NT
00430   cmd_loop_driver = "\\syslib\\x_interp";
00431 #else
00432   cmd_loop_driver = "/syslib/x_interp";
00433 #endif
00434 
00435 
00436   xsb_mode = DEFAULT;
00437   pflags[TABLING_METHOD] = VARIANT_EVAL_METHOD;
00438 
00439   /* Modify Parameters Using Command Line Options
00440      -------------------------------------------- */
00441   for (i=1; i<argc; i++) {
00442     if (*argv[i] != '-') {        /* command-line module specified */
00443       if (xsb_mode != DEFAULT)
00444         help_message();
00445       xsb_mode = CUSTOM_CMD_LOOP_DRIVER;
00446       cmd_loop_driver = argv[i];
00447       continue;
00448     }
00449 
00450     /* Otherwise, get command-line switch (and arg).
00451        Will dump core if the accompanying argument is omitted. */
00452     switch((argv[i][1])) {
00453     case 'r':
00454       pflags[STACK_REALLOC] = FALSE;
00455       break;
00456     case 'g':
00457       i++;
00458 #ifdef GC
00459       if (i < argc) {
00460         if (strcmp(argv[i],"sliding")==0)
00461           pflags[GARBAGE_COLLECT] = SLIDING_GC;
00462         else
00463         if (strcmp(argv[i],"copying")==0)
00464           pflags[GARBAGE_COLLECT] = COPYING_GC;
00465         else
00466         if (strcmp(argv[i],"indirection")==0)
00467           pflags[GARBAGE_COLLECT] = INDIRECTION_SLIDE_GC;
00468         else
00469         if (strcmp(argv[i],"none")==0)
00470           pflags[GARBAGE_COLLECT] = NO_GC;
00471         else
00472         xsb_warn("Unrecognized garbage collection type");
00473       } else
00474         xsb_warn("Missing garbage collection type");
00475 #else
00476       xsb_warn("-g option does not make sense in this XSB configuration");
00477 #endif
00478       break;
00479     case 'u':
00480       if (argv[i][2] != '\0')
00481 #ifndef MULTI_THREAD
00482         sscanf(argv[i]+2, "%ld", &pdl.init_size);
00483 #else
00484         sscanf(argv[i]+2, "%ld", &init_pdl.init_size);
00485 #endif
00486       else {
00487         i++;
00488         if (i < argc)
00489 #ifndef MULTI_THREAD
00490           sscanf(argv[i], "%ld", &pdl.init_size);
00491 #else
00492           sscanf(argv[i], "%ld", &init_pdl.init_size);
00493 #endif
00494         else
00495           xsb_warn("Missing size value for -u");
00496       }
00497       break;
00498     case 'm':
00499       if (argv[i][2] != '\0')
00500 #ifndef MULTI_THREAD
00501         sscanf(argv[i]+2, "%ld", &glstack.init_size);
00502 #else
00503         sscanf(argv[i]+2, "%ld", &init_glstack.init_size);
00504 #endif
00505       else {
00506         i++;
00507         if (i < argc)
00508 #ifndef MULTI_THREAD
00509           sscanf(argv[i], "%ld", &glstack.init_size);
00510 #else
00511           sscanf(argv[i], "%ld", &init_glstack.init_size);
00512 #endif
00513         else
00514           xsb_warn("Missing size value for -m");
00515       }
00516       break;
00517     case 'c':
00518       if (argv[i][2] != '\0')
00519 #ifndef MULTI_THREAD
00520         sscanf(argv[i]+2, "%ld", &tcpstack.init_size);
00521 #else
00522         sscanf(argv[i]+2, "%ld", &init_tcpstack.init_size);
00523 #endif
00524       else {
00525         i++;
00526         if (i < argc)
00527 #ifndef MULTI_THREAD
00528           sscanf(argv[i], "%ld", &tcpstack.init_size);
00529 #else
00530           sscanf(argv[i], "%ld", &init_tcpstack.init_size);
00531 #endif
00532         else
00533           xsb_warn("Missing size value for -c");
00534       }
00535       break;
00536     case 'o':
00537       if (argv[i][2] != '\0')
00538 #ifndef MULTI_THREAD
00539         sscanf(argv[i]+2, "%ld", &complstack.init_size);
00540 #else
00541         sscanf(argv[i]+2, "%ld", &init_complstack.init_size);
00542 #endif
00543       else {
00544         i++;
00545         if (i < argc)
00546 #ifndef MULTI_THREAD
00547           sscanf(argv[i], "%ld", &complstack.init_size);
00548 #else
00549           sscanf(argv[i], "%ld", &init_complstack.init_size);
00550 #endif
00551         else
00552           xsb_warn("Missing size value for -o");
00553       }
00554       break;
00555 #ifndef MULTI_THREAD
00556     case 's':
00557       flags[TRACE_STA] = 1;
00558       asynint_val |= MSGINT_MARK;
00559       break;
00560 #else
00561       sprintf(warning, "-s option not available with multi-threaded engine.");
00562       xsb_warn(warning);
00563 #endif
00564     case 'S':
00565       pflags[TABLING_METHOD] = SUBSUMPTIVE_EVAL_METHOD;
00566       break;
00567     case 'd':
00568       if ( (xsb_mode != DEFAULT) && (xsb_mode != CUSTOM_BOOT_MODULE) )
00569         help_message();
00570       xsb_mode = DISASSEMBLE;
00571       break;
00572     case 'T': 
00573       flags[HITRACE] = 1;
00574       asynint_val |= MSGINT_MARK; 
00575       break;
00576     case 't': 
00577 #ifdef DEBUG_VM
00578       flags[PIL_TRACE] = 1;
00579       flags[HITRACE] = 1;
00580       asynint_val |= MSGINT_MARK;
00581 #else
00582       xsb_exit("-t option unavailable for this executable (non-debug mode)");
00583 #endif
00584       break;
00585     case 'i':
00586       if (xsb_mode != DEFAULT)
00587         help_message();
00588       xsb_mode = INTERPRETER;
00589       break;
00590     case 'l':
00591       flags[LETTER_VARS] = 1;
00592       break;
00593     case 'n':
00594       if (xsb_mode != DEFAULT)
00595         help_message();
00596       xsb_mode = C_CALLING_XSB;
00597 #ifdef WIN_NT
00598       cmd_loop_driver = "\\syslib\\xcallxsb";
00599 #else
00600       cmd_loop_driver = "/syslib/xcallxsb";
00601 #endif
00602       break;
00603     case 'B':
00604       if (xsb_mode == DEFAULT)
00605         xsb_mode = CUSTOM_BOOT_MODULE;
00606       else if (xsb_mode != DISASSEMBLE)   /* retain disassemble command for */
00607         help_message();                /* -d -f <file> AWA -f <file> -d */
00608       if (argv[i][2] != '\0')
00609         boot_module = argv[i]+2;
00610       else {
00611         i++;
00612         if (i < argc)
00613            boot_module = argv[i];
00614          else
00615            xsb_warn("Missing boot module's file name");
00616       }
00617       break;
00618     case 'D':
00619       if (xsb_mode == DEFAULT)
00620         xsb_mode = CUSTOM_CMD_LOOP_DRIVER;
00621       else if (xsb_mode != CUSTOM_BOOT_MODULE)
00622         help_message();
00623       if (argv[i][2] != '\0')
00624         cmd_loop_driver = argv[i]+2;
00625       else {
00626         i++;
00627         if (i < argc)
00628            cmd_loop_driver = argv[i];
00629          else
00630            xsb_warn("Missing top-level command loop driver's file name");
00631       }
00632       break;
00633     case 'e': {
00634       char *tmp_goal=NULL;
00635       if (argv[i][2] != '\0')
00636         tmp_goal = argv[i]+2;
00637       else {
00638         i++;
00639         if (i < argc)
00640            tmp_goal = argv[i];
00641          else
00642            xsb_warn("Missing command line goal");
00643       }
00644 
00645       if (strchr(tmp_goal, '.') == NULL) {
00646         xsb_exit("\n\nTerminating `.' missing in command line goal:\n\t`%s'",
00647                  tmp_goal);
00648       }
00649 
00650       if ((strlen(cmd_line_goal) + strlen(tmp_goal)) >= MAXBUFSIZE)
00651         xsb_exit("\n\nCommand line goal is too long (> %d)\n\n", MAXBUFSIZE);
00652       strcat(cmd_line_goal, " ");
00653       strcat(cmd_line_goal, tmp_goal);
00654       break;
00655     }
00656     case 'h':
00657       help_message();
00658       break;
00659     case 'v':
00660       version_message();
00661       break;
00662     case '-': /* this was a long option of the form --optionname */
00663       process_long_option(argv[i]+2,&i,argv,argc);
00664       break;
00665     case 'p':
00666       xsb_profiling_enabled = 1;
00667       break;
00668     case 'q':
00669       break;
00670     default:
00671       sprintf(warning, "Unknown command line option %s", argv[i]);
00672       xsb_warn(warning);
00673     } /* switch */
00674   } /* for */
00675   /* Done with command line arguments */
00676 
00677   /* This is where we will be looking for the .xsb directory */
00678   flags[USER_HOME] = (Cell) mem_alloc(strlen(user_home_gl) + 1,OTHER_SPACE);
00679   strcpy( (char *)flags[USER_HOME], user_home_gl );
00680 
00681   /* install_dir is computed dynamically at system startup (in orient_xsb.c).
00682      Therefore, the entire directory tree can be moved --- only the relative
00683      positions count.
00684 
00685      Initializing these flags could probably be done in init_flags --
00686      which would be cleaner.  However, this would mean rearranging
00687      main_xsb.c
00688   */ 
00689   flags[INSTALL_DIR] = (Cell) mem_alloc(strlen(install_dir_gl) + 1,OTHER_SPACE);   
00690   strcpy( (char *)flags[INSTALL_DIR], install_dir_gl );
00691 
00692   /* loader uses CONFIG_NAME flag before xsb_configuration is loaded */
00693   flags[CONFIG_NAME] = (Cell) mem_alloc(strlen(CONFIGURATION) + 1,OTHER_SPACE);
00694   strcpy( (char *)flags[CONFIG_NAME], CONFIGURATION );
00695 
00696   flags[CONFIG_FILE] = (Cell) mem_alloc(strlen(xsb_config_file_gl) + 1,OTHER_SPACE);
00697   strcpy( (char *)flags[CONFIG_FILE], xsb_config_file_gl );
00698 
00699   /* the default for cmd_line_goal goal is "" */
00700   flags[CMD_LINE_GOAL] = (Cell) mem_alloc(strlen(cmd_line_goal) + 1,OTHER_SPACE);
00701   strcpy( (char *)flags[CMD_LINE_GOAL], cmd_line_goal );
00702   
00703 
00704   /* Set the Prolog startup files.
00705      ----------------------------- */
00706   /* Default execution mode is to load and run the interpreter. */
00707   if (xsb_mode == DEFAULT)
00708     xsb_mode = INTERPRETER;
00709 
00710   strlen_instdir = strlen(install_dir_gl);
00711   strlen_initfile = strlen(boot_module)+XSB_OBJ_EXTENSION_LENGTH;
00712   strlen_2ndfile = strlen(cmd_loop_driver);
00713 
00714   switch(xsb_mode) {
00715   case INTERPRETER:
00716   case C_CALLING_XSB:
00717     /*
00718      *  A "short-cut" option in which the loader is the loader file and
00719      *  an XSB-supplied "server" program is the interpreter file.  Since
00720      *  it is known where these files exist, the full paths are built.
00721      */
00722     flags[BOOT_MODULE] = (Cell) mem_alloc(strlen_instdir + strlen_initfile + 1,OTHER_SPACE);
00723     flags[CMD_LOOP_DRIVER] = (Cell)mem_alloc(strlen_instdir + strlen_2ndfile + 1,OTHER_SPACE);
00724     sprintf( (char *)flags[BOOT_MODULE],
00725              "%s%s%s",
00726              install_dir_gl, boot_module, XSB_OBJ_EXTENSION_STRING );
00727     sprintf( (char *)flags[CMD_LOOP_DRIVER],
00728              "%s%s",
00729              install_dir_gl, cmd_loop_driver );
00730     break;
00731   case CUSTOM_BOOT_MODULE:
00732     /*
00733      *  The user has specified a private loader to be used instead of the
00734      *  standard one and possibly a top-level command loop driver as well.  In
00735      *  either case, we can 
00736      *  make no assumptions as to where these files exist, and so the 
00737      *  user must supply an adequate full path name in each case (including
00738      *  extension).
00739      */
00740     flags[BOOT_MODULE] = (Cell) mem_alloc(strlen_initfile + 1,OTHER_SPACE);
00741     flags[CMD_LOOP_DRIVER ] = (Cell) mem_alloc(strlen_2ndfile + 1,OTHER_SPACE);
00742     strcpy( (char *)flags[BOOT_MODULE], boot_module );
00743     strcpy( (char *)flags[CMD_LOOP_DRIVER], cmd_loop_driver );
00744     break;
00745   case CUSTOM_CMD_LOOP_DRIVER:
00746     /*
00747      *  The user has specified a private top-level command loop.
00748      *  The filename can be absolute; however if not, it will
00749      *  be looked for in XSB's library path.
00750      */
00751     flags[BOOT_MODULE] = (Cell) mem_alloc(strlen_instdir + strlen_initfile + 1,OTHER_SPACE);
00752     flags[CMD_LOOP_DRIVER ] = (Cell) mem_alloc(strlen_2ndfile + 1,OTHER_SPACE);
00753     sprintf( (char *)flags[BOOT_MODULE],
00754              "%s%s%s",
00755              install_dir_gl, boot_module, XSB_OBJ_EXTENSION_STRING );
00756     strcpy( (char *)flags[CMD_LOOP_DRIVER ], cmd_loop_driver );
00757     break;
00758   case DISASSEMBLE:
00759     /*
00760      *  A loader file should have been specified for disassembling.
00761      *  Should include extension and all.
00762      */
00763     flags[BOOT_MODULE] = (Cell) mem_alloc(strlen_initfile + 1,OTHER_SPACE);
00764     strcpy( (char *)flags[BOOT_MODULE], boot_module );
00765     break;
00766   default:
00767     xsb_exit("Setting startup files: Bad XSB mode!");
00768     break;
00769   }
00770 
00771   /* Other basic initializations
00772      --------------------------- */
00773   realtime_count_gl = real_time();
00774 
00775   return ( (char *) flags[BOOT_MODULE] );
00776 
00777 } /* init_para() */
00778 
00779 /*==========================================================================*/
00780 #ifdef MULTI_THREAD
00781 
00782 void set_init_glstack_size(int s)
00783 {
00784         init_glstack.size = s ;
00785 }
00786 
00787 void set_init_tcpstack_size(int s)
00788 {
00789         init_tcpstack.size = s ;
00790 }
00791 
00792 void set_init_pdl_size(int s)
00793 {
00794         init_pdl.size = s ;
00795 }
00796 
00797 void set_init_complstack_size(int s)
00798 {
00799         init_complstack.size = s ;
00800 }
00801 
00802 
00803 
00804 /* To be called each time a thread is created: initializes
00805  * thread-private memory areas that are cleaned up in
00806  * cleanup_thread_structures() */
00807 
00808 
00809 void init_thread_structures(CTXTdecl)
00810 {
00811 
00812   interrupt_reg = &interrupt_counter;
00813 
00814   asynint_code = 0;
00815   asynint_val = 0;
00816 
00817   pdl           = init_pdl ;
00818   glstack       = init_glstack ;
00819   tcpstack      = init_tcpstack ;
00820   complstack    = init_complstack ;
00821 
00822   findall_solutions = NULL;
00823 
00824 #define MAXSBUFFS 30
00825   LSBuff = (VarString **)mem_calloc(sizeof(VarString *),MAXSBUFFS,OTHER_SPACE);
00826 
00827   /* vars for io_builtins_XXX */
00828   opstk_size = 0;
00829   funstk_size = 0;
00830   funstk = NULL;
00831   opstk = NULL;
00832   rc_vars = (struct vartype *)mem_alloc(MAXVAR*sizeof(struct vartype),OTHER_SPACE);
00833 
00834   /* vars for token_xsb_XXX */
00835   token = (struct token_t *)mem_alloc(sizeof(struct token_t),OTHER_SPACE);
00836   strbuff = NULL;
00837   lastc = ' ';
00838   strbuff_len = InitStrLen;
00839 
00840   random_seeds = 0;
00841 
00842   /* used in trie_lookup */
00843   a_tstCCPStack = (struct tstCCPStack_t *)mem_alloc(sizeof(struct tstCCPStack_t),OTHER_SPACE);
00844   a_variant_cont = (struct VariantContinuation *)mem_alloc(sizeof(struct VariantContinuation),OTHER_SPACE);
00845   a_tstCPStack = (struct tstCPStack_t *)mem_alloc(sizeof(struct tstCPStack_t),OTHER_SPACE);
00846 
00847   asrtBuff = (struct asrtBuff_t *)mem_alloc(sizeof(struct asrtBuff_t),OTHER_SPACE);
00848   asrtBuff->Buff = NULL;
00849   asrtBuff->Buff_size = 512;
00850   asrtBuff->Loc = NULL;
00851   asrtBuff->BLim = 0;
00852   asrtBuff->Size = 0;
00853   i_have_dyn_mutex = 0;
00854 
00855   last_answer = (VarString *)mem_alloc(sizeof(VarString),OTHER_SPACE);
00856   XSB_StrInit(last_answer);
00857   OldestCl = retracted_buffer;
00858   NewestCl = retracted_buffer;
00859 
00860 /*  call_intercept = init_call_intercept ; */
00861 
00862   private_tif_list.first = NULL;
00863   private_tif_list.last = NULL;
00864   private_deltf_chain_begin = NULL;
00865   private_delcf_chain_begin = NULL;
00866 
00867   /******** Initialize Private structure managers ********/
00868 
00869   private_smTableBTN  = 
00870     (struct Structure_Manager*) mem_alloc(sizeof(struct Structure_Manager),
00871                                           MT_PRIVATE_SPACE);
00872   SM_InitDeclDyna(private_smTableBTN,BasicTrieNode, BTNs_PER_BLOCK,
00873                   "Basic Trie Node (Private)");
00874 
00875   private_smTableBTHT  = 
00876     (struct Structure_Manager*) mem_alloc(sizeof(struct Structure_Manager),
00877                                           MT_PRIVATE_SPACE);
00878   SM_InitDeclDyna(private_smTableBTHT,BasicTrieHT, BTHTs_PER_BLOCK,
00879                   "Basic Trie Hash Table (Private)");
00880 
00881   private_smTSTN = 
00882     (struct Structure_Manager*) mem_alloc(sizeof(struct Structure_Manager),
00883                                           MT_PRIVATE_SPACE);
00884   SM_InitDeclDyna(private_smTSTN,TS_TrieNode, TSTNs_PER_BLOCK,
00885                   "Time-Stamped Trie Node (Private)");
00886 
00887   private_smTSTHT  = 
00888     (struct Structure_Manager*) mem_alloc(sizeof(struct Structure_Manager),
00889                                           MT_PRIVATE_SPACE);
00890   SM_InitDeclDyna(private_smTSTHT,TST_HashTable, TSTHTs_PER_BLOCK,
00891                     "Time-Stamped Trie Hash Table (Private)");
00892 
00893   private_smTSIN  = 
00894     (struct Structure_Manager*) mem_alloc(sizeof(struct Structure_Manager),
00895                                           MT_PRIVATE_SPACE);
00896   SM_InitDeclDyna(private_smTSIN,TS_IndexNode, TSINs_PER_BLOCK,
00897                             "Time-Stamp Indexing Node (Private)");
00898 
00899   private_smVarSF  = 
00900     (struct Structure_Manager*) mem_alloc(sizeof(struct Structure_Manager),
00901                                           MT_PRIVATE_SPACE);
00902   SM_InitDeclDyna(private_smVarSF,variant_subgoal_frame,
00903                   SUBGOAL_FRAMES_PER_BLOCK,"Variant Subgoal Frame (Private)");
00904 
00905   private_smProdSF  = 
00906     (struct Structure_Manager*) mem_alloc(sizeof(struct Structure_Manager),
00907                                           MT_PRIVATE_SPACE);
00908   SM_InitDeclDyna(private_smProdSF,subsumptive_producer_sf,
00909                   SUBGOAL_FRAMES_PER_BLOCK,
00910                   "Subsumptive Producer Subgoal Frame (Private)");
00911 
00912   private_smConsSF  = 
00913     (struct Structure_Manager*) mem_alloc(sizeof(struct Structure_Manager),
00914                                           MT_PRIVATE_SPACE);
00915   SM_InitDeclDyna(private_smConsSF,subsumptive_consumer_sf,
00916                   SUBGOAL_FRAMES_PER_BLOCK,
00917                   "Subsumptive Consumer Subgoal Frame (Private)");
00918 
00919   private_smALN  = 
00920     (struct Structure_Manager*) mem_alloc(sizeof(struct Structure_Manager),
00921                                           MT_PRIVATE_SPACE);
00922   SM_InitDeclDyna(private_smALN,AnsListNode, ALNs_PER_BLOCK,
00923                   "Answer List Node (Private)");
00924 
00925   num_gc = 0;
00926   total_time_gc = 0;
00927   total_collected = 0;
00928 
00929   token_too_long_warning = 1;
00930 
00931   /***************/
00932 
00933 /* This is here just for the first thread - others initialize its xsb tid
00934    on xsb_thread_run - the first thread has always tid = 0 */
00935   th->tid = 0 ;
00936 #ifdef SHARED_COMPL_TABLES
00937   th->waiting_for_thread = NULL ;
00938 #endif
00939 #ifdef CONC_COMPL
00940   pthread_cond_init( &th->cond_var, NULL );
00941   th->completing = FALSE;
00942   th->last_ans = 1;
00943 #endif
00944 }
00945 
00946 void cleanup_thread_structures(CTXTdecl)
00947 {
00948   free(glstack.low) ;
00949   free(tcpstack.low) ;
00950   free(complstack.low) ;
00951   free(pdl.low) ;
00952 
00953   /* these are allocated in init_thread_structures() */
00954   mem_dealloc(LSBuff,sizeof(VarString *)*MAXSBUFFS,OTHER_SPACE);
00955   mem_dealloc(rc_vars,MAXVAR*sizeof(struct vartype),OTHER_SPACE);
00956   mem_dealloc(token,sizeof(struct token_t),OTHER_SPACE); 
00957   mem_dealloc(a_tstCCPStack,sizeof(struct tstCCPStack_t),OTHER_SPACE);
00958   mem_dealloc(a_variant_cont,sizeof(struct VariantContinuation),OTHER_SPACE);
00959   mem_dealloc(a_tstCPStack,sizeof(struct tstCPStack_t),OTHER_SPACE);
00960   mem_dealloc(asrtBuff,sizeof(struct asrtBuff_t),OTHER_SPACE);
00961   mem_dealloc(last_answer,sizeof(VarString),OTHER_SPACE);
00962 
00963   XSB_StrDestroy(tsgLBuff1);
00964   XSB_StrDestroy(tsgLBuff2);
00965   XSB_StrDestroy(tsgSBuff1);
00966   XSB_StrDestroy(tsgSBuff2);
00967 
00968   mem_dealloc(tsgLBuff1,sizeof(VarString),OTHER_SPACE);
00969   mem_dealloc(tsgLBuff2,sizeof(VarString),OTHER_SPACE);
00970   mem_dealloc(tsgSBuff1,sizeof(VarString),OTHER_SPACE);
00971   mem_dealloc(tsgSBuff2,sizeof(VarString),OTHER_SPACE);
00972 
00973   free_trie_aux_areas(CTXT) ;
00974 
00975   mem_dealloc(private_smTableBTN,sizeof(struct Structure_Manager),
00976               MT_PRIVATE_SPACE);
00977   mem_dealloc(private_smTableBTHT,sizeof(struct Structure_Manager),
00978               MT_PRIVATE_SPACE);
00979   mem_dealloc(private_smTSTN,sizeof(struct Structure_Manager),
00980               MT_PRIVATE_SPACE);
00981   mem_dealloc(private_smTSTHT,sizeof(struct Structure_Manager),
00982               MT_PRIVATE_SPACE);
00983   mem_dealloc(private_smTSIN,sizeof(struct Structure_Manager),
00984               MT_PRIVATE_SPACE); 
00985   mem_dealloc(private_smVarSF,sizeof(struct Structure_Manager),
00986               MT_PRIVATE_SPACE);
00987   mem_dealloc(private_smProdSF,sizeof(struct Structure_Manager),
00988               MT_PRIVATE_SPACE); 
00989   mem_dealloc(private_smConsSF,sizeof(struct Structure_Manager),
00990               MT_PRIVATE_SPACE); 
00991   mem_dealloc(private_smALN,sizeof(struct Structure_Manager),
00992               MT_PRIVATE_SPACE); 
00993 }
00994 #endif /* MULTI_THREAD */
00995 
00996 /*==========================================================================*/
00997 /* Initialize Memory Regions and Related Variables.  Done whenever
00998    threads are initialized.
00999 
01000    If non-null, use input parameters for initial sizes (for greater
01001    freedom in thread allocation) ; otherwise use process-level
01002    defaults.  
01003    ----------------------------------------------- */
01004 
01005 void init_machine(CTXTdeclc int glsize, int tcpsize, 
01006                   int complstacksize, int pdlsize)
01007 {
01008   void tstInitDataStructs(CTXTdecl);
01009   /* set special SLG_WAM instruction addresses */
01010   /* these need only be done on process initialization, but there's a core-dump
01011      if you move them to init_machine() */
01012 
01013   cell_opcode(&answer_return_inst) = answer_return;
01014   cell_opcode(&resume_compl_suspension_inst) = resume_compl_suspension;
01015   cell_opcode(&resume_compl_suspension_inst2) = resume_compl_suspension;
01016   cell_opcode(&check_complete_inst) = check_complete;
01017   cell_opcode(&hash_handle_inst) = hash_handle;
01018   cell_opcode(&fail_inst) = fail;
01019   cell_opcode(&dynfail_inst) = dynfail;
01020   cell_opcode(&trie_fail_unlock_inst) = trie_fail_unlock;
01021   cell_opcode(&halt_inst) = halt;
01022   cell_opcode(&proceed_inst) = proceed;         /* returned by load_obj */
01023 
01024   init_newtrie(CTXT);
01025 
01026 #ifdef MULTI_THREAD
01027   init_thread_structures(CTXT);
01028 #endif
01029 
01030   tsgLBuff1 = (VarString *)mem_alloc(sizeof(VarString),OTHER_SPACE);
01031   XSB_StrInit(tsgLBuff1);
01032   tsgLBuff2 = (VarString *)mem_alloc(sizeof(VarString),OTHER_SPACE);
01033   XSB_StrInit(tsgLBuff2);
01034   tsgSBuff1 = (VarString *)mem_alloc(sizeof(VarString),OTHER_SPACE);
01035   XSB_StrInit(tsgSBuff1);
01036   tsgSBuff2 = (VarString *)mem_alloc(sizeof(VarString),OTHER_SPACE);
01037   XSB_StrInit(tsgSBuff2);
01038 
01039   /* Allocate Stack Spaces and set Boundary Parameters
01040      ------------------------------------------------- */
01041 
01042   if (pdlsize == 0) {
01043   pdl.low = (byte *)malloc(pdl.init_size * K);
01044   } else {
01045     pdl.low = (byte *)malloc(pdlsize * K);
01046   }
01047   if (!pdl.low)
01048     xsb_exit("Not enough core for the PDL Stack!");
01049   pdl.high = pdl.low + pdl.init_size * K;
01050   pdl.size = pdl.init_size;
01051 
01052   if (glsize == 0) {
01053     glstack.low = (byte *)malloc(glstack.init_size * K);
01054   } else {
01055     glstack.low = (byte *)malloc(glsize * K);
01056   }    
01057   if (!glstack.low)
01058     xsb_exit("Not enough core for the Global and Local Stacks!");
01059   glstack.high = glstack.low + glstack.init_size * K;
01060   glstack.size = glstack.init_size;
01061 
01062 #if defined(GENERAL_TAGGING)
01063   extend_enc_dec_as_nec(glstack.low,glstack.high);
01064 #endif
01065 
01066   if (tcpsize == 0) {
01067     tcpstack.low = (byte *)malloc(tcpstack.init_size * K);
01068   } else {
01069     tcpstack.low = (byte *)malloc(tcpsize * K);
01070   }    
01071   if (!tcpstack.low)
01072     xsb_exit("Not enough core for the Trail and Choice Point Stack!");
01073   tcpstack.high = tcpstack.low + tcpstack.init_size * K;
01074   tcpstack.size = tcpstack.init_size;
01075 
01076   if (complstacksize == 0) {
01077     complstack.low = (byte *)malloc(complstack.init_size * K);
01078   } else {
01079     complstack.low = (byte *)malloc(complstacksize * K);
01080   }
01081   if (!complstack.low)
01082     xsb_exit("Not enough core for the Completion Stack!");
01083   complstack.high = complstack.low + complstack.init_size * K;
01084   complstack.size = complstack.init_size;
01085 
01086   /* -------------------------------------------------------------------
01087      So, the layout of the memory looks as follows:
01088 
01089      pdl.low
01090              /\
01091      pdlreg   |
01092      pdl.high
01093      ===================
01094      glstack.low
01095      hreg   |
01096            \/
01097            /\
01098      ereg   |
01099      glstack.high
01100      ===================
01101      tcpstack.low
01102      trreg  |
01103            \/
01104            /\
01105      breg   |
01106      tcpstack.high
01107      ===================
01108      complstack.low
01109              /\
01110      openreg  |
01111      complstack.high
01112      --------------------------------------------------------------------- */
01113 
01114   /* Initialize Registers
01115      -------------------- */
01116   cpreg = (pb) &halt_inst;              /* halt on final success */
01117 
01118   pdlreg = (CPtr)(pdl.high) - 1;
01119 
01120 /*   interrupt_reg = (CPtr)(glstack.low); */
01121   bld_int(interrupt_reg, 0);
01122 
01123   hbreg = hreg = (CPtr)(glstack.low);
01124   
01125   /* Use first word in the heap as the global variable, exported to
01126      Prolog via the 'globalvar/1' builtin */
01127   bld_free(hreg);
01128   hreg++;
01129 
01130   ebreg = ereg = (CPtr)(glstack.high) - 1;
01131 
01132   *(ereg-1) = (Cell) cpreg;
01133 
01134   trreg = (CPtr *)(tcpstack.low);
01135   *(trreg) = (CPtr) trreg;
01136 
01137   reset_freeze_registers;
01138   openreg = ((CPtr) complstack.high);
01139   delayreg = NULL;
01140 
01141   /* Place a base choice point frame on the CP Stack: this choice point
01142      is needed for cut -- make sure you initialize all its fields.
01143      ------------------------------------------------------------------ */
01144   bfreg = breg = (CPtr)(tcpstack.high) - CP_SIZE;
01145   cp_pcreg(breg) = (pb) &halt_inst;       /* halt on last failure */
01146   cp_ebreg(breg) = ebreg;
01147   cp_hreg(breg) = hreg;
01148   cp_trreg(breg) = trreg;
01149   cp_ereg(breg) = ereg;
01150   cp_prevbreg(breg) = breg;               /* note ! */
01151   cp_pdreg(breg) = delayreg;
01152 #ifdef CP_DEBUG
01153   cp_psc(breg) = 0;
01154 #endif
01155   cp_prevtop(breg) = (CPtr)(tcpstack.high) - 1;
01156 
01157   /* init trie stuff */
01158 
01159 #ifdef MULTI_THREAD
01160   th->trie_locked = 0 ;
01161 #endif
01162   reg_array_size = DEFAULT_ARRAYSIZ;
01163   num_vars_in_var_regs = -1;
01164   init_trie_aux_areas(CTXT);
01165   tstInitDataStructs(CTXT);
01166 } /* init_machine() */
01167 
01168 Psc make_code_psc_rec(char *name, int arity, Psc mod_psc) {
01169   Pair temp;
01170   int new;
01171   Psc new_psc;
01172   temp = (Pair)insert(name, (byte) arity, mod_psc, &new);
01173   new_psc = pair_psc(temp);
01174   set_data(new_psc, mod_psc);
01175   set_env(new_psc, T_UNLOADED);
01176   set_type(new_psc, T_ORDI);
01177   if (mod_psc != global_mod) link_sym(new_psc, global_mod); /* Add to global module as well */
01178   return new_psc;
01179 }
01180 
01181 /*==========================================================================*/
01182 
01183 /* Initialize Standard PSC Records and Thread Attributes
01184    ------------------------------- */
01185 void init_symbols(void)
01186 {
01187   Psc  tables_psc, standard_psc;
01188   Pair temp, tp;
01189   int  i, new_indicator;
01190 #ifdef MULTI_THREAD
01191   int status;
01192 #endif
01193 
01194   inst_begin_gl = 0;
01195   symbol_table.table = (void **)mem_calloc(symbol_table.size, sizeof(Pair),ATOM_SPACE);
01196   string_table.table = (void **)mem_calloc(string_table.size, sizeof(char *),STRING_SPACE);
01197 
01198   /* insert mod name global */
01199   /*tp = insert_module(T_MODU, "global");       / loaded */
01200   tp = insert_module(T_MODU, "usermod");        /* loaded */
01201   set_data(pair_psc(tp), (Psc)USERMOD_PSC);     /* initialize global mod PSC */
01202   global_mod = pair_psc(tp);
01203 
01204   /* insert "."/2 into global list */
01205   temp = (Pair)insert(".", 2, global_mod, &new_indicator);
01206   list_pscPair = temp;
01207   list_psc = pair_psc(temp);
01208   list_dot_string = get_name(list_psc);
01209 
01210   if_psc = pair_psc(insert(":-", 2, global_mod, &new_indicator));
01211 
01212   /* insert symbol "$BOX$"/3 */
01213   box_psc = pair_psc(insert("$BOX$", 3, global_mod, &new_indicator));
01214 
01215   delay_psc = pair_psc(insert("DL", 3, global_mod, &new_indicator));
01216 
01217   standard_psc = pair_psc(insert_module(0, "standard"));        /* unloaded */
01218 
01219   true_psc = make_code_psc_rec("true", 0, standard_psc);
01220   true_string = get_name(true_psc);
01221   
01222   comma_psc = make_code_psc_rec(",", 2, standard_psc);
01223 
01224   colon_psc = make_code_psc_rec(":", 2, standard_psc);
01225 
01226   /* insert symbol tnot/1 into module tables */
01227   tables_psc = pair_psc(insert_module(0, "tables"));            /* unloaded */
01228 
01229   tnot_psc = make_code_psc_rec("tnot", 1, tables_psc);
01230 
01231   /* insert "[]"/0 into String Table */
01232   nil_string = string_find("[]", 1);
01233 
01234   /*
01235    * Initialize ret PSCs.  Notice that ret_psc[0] is set to a pointer
01236    * to STRING "ret".
01237    */
01238   ret_psc[0] = (Psc) string_find("ret", 1);
01239   for (i = 1; i < MAX_ARITY; i++) ret_psc[i] = NULL;
01240 
01241   /* Finally, eagerly insert pscs used for resource errors.  This way,
01242      we don't have to worry abt the symbol table growing when we're
01243      thowing a memory error. */
01244   temp = (Pair)insert("$$exception_ball", (byte)2, 
01245                                         pair_psc(insert_module(0,"standard")), 
01246                       &new_indicator);
01247   temp = (Pair) insert("error",3,global_mod,&new_indicator);
01248   temp = (Pair) insert("resource_error",1,global_mod,&new_indicator);
01249 
01250   #ifdef MULTI_THREAD
01251   status = pthread_attr_init(&detached_attr_gl);
01252   if (status != 0) 
01253     xsb_exit("Cannot init pthread attr detached state during system initialization");
01254   
01255   status = pthread_attr_setdetachstate(&detached_attr_gl,PTHREAD_CREATE_DETACHED);
01256   if (status != 0) 
01257     xsb_exit("Cannot set pthread attr detached state during system initialization");
01258 
01259   #endif
01260 
01261 }
01262 
01263 /*==========================================================================*/

Generated on Wed Jul 26 13:30:41 2006 for XSB by  doxygen 1.4.5