1 /* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 1997-2020, University of Amsterdam 7 VU University Amsterdam 8 CWI, Amsterdam 9 All rights reserved. 10 11 Redistribution and use in source and binary forms, with or without 12 modification, are permitted provided that the following conditions 13 are met: 14 15 1. Redistributions of source code must retain the above copyright 16 notice, this list of conditions and the following disclaimer. 17 18 2. Redistributions in binary form must reproduce the above copyright 19 notice, this list of conditions and the following disclaimer in 20 the documentation and/or other materials provided with the 21 distribution. 22 23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 #ifndef PL_GLOBAL_H_INCLUDED 38 #define PL_GLOBAL_H_INCLUDED 39 #include "pl-allocpool.h" 40 41 #ifndef GLOBAL /* global variables */ 42 #define GLOBAL extern 43 #endif 44 45 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 46 This module packs SWI-Prolog global data-structures into two structures. 47 The structure PL_global_data contains all global data that is related to 48 the state of the system as a whole, and PL_local_data contains all data 49 that is related to a Prolog thread. 50 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 51 52 /******************************* 53 * CODE DATA * 54 *******************************/ 55 56 typedef struct 57 { 58 #if VMCODE_IS_ADDRESS 59 unsigned char *_dewam_table; /* decoding table */ 60 intptr_t _dewam_table_offset; /* offset of 1st */ 61 void **_interpreter_jmp_table; /* interpreters table */ 62 /* must be last! (why?) */ 63 code _wam_table[I_HIGHEST]; /* code --> address */ 64 #else 65 int struct_may_not_be_empty; /* empty structure is illegal */ 66 #endif 67 struct /* see initSupervisors() */ 68 { code exit[3]; /* I_EXIT */ 69 code next_clause[3]; /* S_NEXTCLAUSE */ 70 code virgin[3]; /* S_VIRGIN */ 71 code undef[3]; /* S_UNDEF */ 72 code dynamic[3]; /* S_DYNAMIC */ 73 code incr_dynamic[3]; /* S_INCR_DYNAMIC */ 74 code thread_local[3]; /* S_THREAD_LOCAL */ 75 code multifile[3]; /* S_MULTIFILE */ 76 code staticp[3]; /* S_STATIC */ 77 code wrapper[3]; /* S_WRAP */ 78 code trie_gen[3]; /* S_TRIE_GEN */ 79 } supervisors; 80 } PL_code_data_t; 81 82 typedef struct 83 { atom_t file; /* current source file */ 84 IOPOS position; /* Line, line pos, char and byte */ 85 } source_location; 86 87 /******************************* 88 * GLOBAL DATA * 89 *******************************/ 90 91 struct PL_global_data 92 { pl_defaults_t defaults; /* system default settings */ 93 pl_options_t options; /* command-line options */ 94 State stateList; /* list of loaded states */ 95 int initialised; /* Heap is initialised */ 96 int io_initialised; /* I/O system has been initialised */ 97 cleanup_status cleaning; /* Inside PL_cleanup() */ 98 int halt_cancelled; /* Times halt was cancelled */ 99 int bootsession; /* -b boot compilation */ 100 int debug_level; /* Maintenance debugging: 0..9 */ 101 struct bit_vector *debug_topics; /* debug topics enabled */ 102 103 struct 104 { void * DB; /* program resource database */ 105 atom_t handle; /* Symbol for DB */ 106 } resources; 107 108 struct 109 { sig_handler handlers[MAXSIGNAL]; /* How Prolog preceives signals */ 110 #ifdef HAVE_SIGNAL 111 int sig_alert; /* our alert signal */ 112 #endif 113 } signals; 114 #ifdef O_LOGICAL_UPDATE 115 volatile ggen_t _generation; /* generation of the database */ 116 #ifdef ATOMIC_GENERATION_HACK 117 volatile gen_t _last_generation; /* see pl-inline.h, global_generation() */ 118 #endif 119 #endif 120 121 struct 122 { int os_argc; /* main(int argc, char **argv) */ 123 char ** os_argv; 124 int appl_argc; /* Application options */ 125 char ** appl_argv; 126 int notty; /* -tty: do not use ioctl() */ 127 int optimise; /* -O: optimised compilation */ 128 int packs; /* --no-packs: no packs */ 129 } cmdline; 130 131 struct 132 { char * CWDdir; 133 size_t CWDlen; 134 char * executable; /* Running executable */ 135 #ifdef __WINDOWS__ 136 char * module; /* argv[0] module passed */ 137 #endif 138 } paths; 139 140 struct 141 { size_t atoms; /* No. of atoms defined */ 142 size_t atom_string_space; /* # bytes used to store atoms */ 143 size_t atom_string_space_freed;/* # bytes in freed atoms */ 144 size_t stack_space; /* # bytes on stacks */ 145 int functors; /* No. of functors defined */ 146 int predicates; /* No. of predicates defined */ 147 int modules; /* No. of modules in the system */ 148 size_t clauses; /* No. clauses */ 149 size_t codes; /* No. of VM codes generated */ 150 double user_cputime; /* User CPU time (whole process) */ 151 double system_cputime; /* Kernel CPU time (whole process) */ 152 struct 153 { int created; /* # created hash tables */ 154 int destroyed; /* # destroyed hash tables */ 155 } indexes; 156 #ifdef O_PLMT 157 int threads_created; /* # threads created */ 158 int threads_finished; /* # finished threads */ 159 int engines_created; /* # engines created */ 160 int engines_finished; /* # engines threads */ 161 double thread_cputime; /* Total CPU time of threads */ 162 #endif 163 } statistics; 164 165 #ifdef O_PROFILE 166 struct 167 { struct PL_local_data *thread; /* Thread being profiled */ 168 } profile; 169 #endif 170 171 struct 172 { Module user; /* user module */ 173 Module system; /* system predicate module */ 174 } modules; 175 176 struct 177 { Table modules; /* atom --> module */ 178 } tables; 179 180 #if O_PLMT 181 struct /* Shared table data */ 182 { struct trie *variant_table; /* Variant --> table */ 183 alloc_pool *node_pool; /* Node allocation pool for tries */ 184 counting_mutex mutex; /* Sync completion */ 185 #ifdef __WINDOWS__ 186 CONDITION_VARIABLE cvar; 187 #else 188 pthread_cond_t cvar; 189 #endif 190 struct trie_array *waiting; /* thread --> trie we are waiting for */ 191 } tabling; 192 #endif 193 194 struct 195 { Table record_lists; /* Available record lists */ 196 } recorded_db; 197 198 struct 199 { ArithF *functions; /* index --> function */ 200 size_t functions_allocated; /* Size of above array */ 201 } arith; 202 203 struct 204 { size_t highest; /* Highest atom index */ 205 atom_array array; 206 AtomTable table; /* hash-table */ 207 int lookups; /* # atom lookups */ 208 int cmps; /* # string compares for lookup */ 209 int initialised; /* atoms have been initialised */ 210 #ifdef O_ATOMGC 211 int gc; /* # atom garbage collections */ 212 int gc_active; /* Atom-GC is in progress */ 213 int rehashing; /* Atom-rehash in progress */ 214 size_t builtin; /* Locked atoms (atom-gc) */ 215 size_t no_hole_before; /* You won't find a hole before here */ 216 size_t margin; /* # atoms to grow before collect */ 217 size_t non_garbage; /* # atoms for after last AGC */ 218 int64_t collected; /* # collected atoms */ 219 size_t unregistered; /* # candidate GC atoms */ 220 double gc_time; /* Time spent on atom-gc */ 221 PL_agc_hook_t gc_hook; /* Current hook */ 222 #endif 223 atom_t *for_code[256]; /* code --> one-char-atom */ 224 PL_blob_t *types; /* registered atom types */ 225 int text_rank; /* next rank for text types */ 226 int nontext_rank; /* next rank for non-text types */ 227 } atoms; 228 229 struct 230 { Table breakpoints; /* Breakpoint table */ 231 } comp; 232 233 struct 234 { ExtensionCell _ext_head; /* head of registered extensions */ 235 ExtensionCell _ext_tail; /* tail of this chain */ 236 237 InitialiseHandle initialise_head; /* PL_initialise_hook() */ 238 InitialiseHandle initialise_tail; 239 PL_dispatch_hook_t dispatch_events; /* PL_dispatch_hook() */ 240 241 unsigned int signature; /* Foreign predicate signature */ 242 int _loaded; /* system extensions are loaded */ 243 } foreign; 244 245 #ifdef O_GMP 246 struct 247 { int initialised; /* is GMP initialised? */ 248 int keep_alloc_functions; /* do not change allocation */ 249 } gmp; 250 #endif 251 252 struct /* pl-format.c */ 253 { Table predicates; 254 } format; 255 256 struct 257 { Table table; /* flag key --> flag */ 258 } flags; 259 260 struct 261 { Table table; /* global (read-only) features */ 262 } prolog_flag; 263 264 struct 265 { size_t highest; /* Next index to handout */ 266 functor_array array; /* index --> functor */ 267 FunctorTable table; /* hash-table */ 268 int rehashing; /* Table is being rehashed */ 269 } functors; 270 271 struct 272 { Code catch_exit_address; /* See findCatchExit() */ 273 } exceptions; 274 275 struct 276 { struct 277 { struct event_list *onabort; /* Thread aborted */ 278 struct event_list *onerase; /* erased clause or dbref */ 279 struct event_list *onbreak; /* breakpoint change */ 280 struct event_list *onframefinish; /* Debugged frame finished */ 281 #ifdef O_PLMT 282 struct event_list *onthreadexit; /* thread exit hook */ 283 #endif 284 struct event_list *onuntable; /* Untable after reload */ 285 } hook; 286 } event; 287 288 struct 289 { Table tmp_files; /* Known temporary files */ 290 struct 291 { CanonicalDir *entries; 292 unsigned size; 293 } dir_table; /* Canonical OS dirs */ 294 char * myhome; /* expansion of ~ */ 295 char * fred; /* last expanded ~user */ 296 char * fredshome; /* home of fred */ 297 OnHalt on_halt_list; /* list of onhalt hooks */ 298 OnHalt exit_hooks; /* how to exit from PL_halt() */ 299 int halting; /* process is shutting down */ 300 int gui_app; /* Win32: Application is a gui app */ 301 IOFUNCTIONS iofunctions; /* initial IO functions */ 302 IOFUNCTIONS org_terminal; /* IO+Prolog terminal functions */ 303 } os; 304 305 struct 306 { Procedure dgarbage_collect1; 307 Procedure catch3; 308 Procedure reset3; 309 Procedure dmeta_call1; /* $meta_call/1 */ 310 Procedure true0; 311 Procedure fail0; 312 Procedure equals2; /* =/2 */ 313 Procedure is2; /* is/2 */ 314 Procedure strict_equal2; /* ==/2 */ 315 Procedure not_strict_equal2; /* \==/2 */ 316 Procedure exception_hook4; 317 Procedure print_message2; 318 Procedure foreign_registered2; /* $foreign_registered/2 */ 319 Procedure prolog_trace_interception4; 320 Procedure prolog_break_hook6; /* prolog:break_hook/6 */ 321 Procedure portray; /* portray/1 */ 322 Procedure dcall1; /* $call/1 */ 323 Procedure call3; /* call/3*/ 324 Procedure setup_call_catcher_cleanup4; /* setup_call_catcher_cleanup/4 */ 325 Procedure undefinterc4; /* $undefined_procedure/4 */ 326 Procedure dthread_init0; /* $thread_init/0 */ 327 Procedure dc_call_prolog0; /* $c_call_prolog/0 */ 328 Procedure dinit_goal3; /* $init_goal/3 */ 329 #ifdef O_ATTVAR 330 Procedure dwakeup1; /* system:$wakeup/1 */ 331 Procedure portray_attvar1; /* $attvar:portray_attvar/1 */ 332 #endif 333 Procedure comment_hook3; /* prolog:comment_hook/3 */ 334 Procedure tune_gc3; /* prolog:tune_gc */ 335 Procedure trie_gen_compiled2; 336 Procedure trie_gen_compiled3; 337 338 int static_dirty; /* #static dirty procedures */ 339 #ifdef O_CLAUSEGC 340 Table dirty; /* Table of dirty procedures */ 341 #endif 342 } procedures; 343 344 struct 345 { ClauseRef lingering; /* Unlinked clause refs */ 346 size_t lingering_count; /* # Unlinked clause refs */ 347 int cgc_active; /* CGC is running */ 348 int64_t cgc_count; /* # clause GC calls */ 349 int64_t cgc_reclaimed; /* # clauses reclaimed */ 350 double cgc_time; /* Total time spent in CGC */ 351 size_t dirty; /* # dirty clauses */ 352 size_t erased; /* # erased pending clauses */ 353 size_t erased_size; /* memory used by them */ 354 size_t erased_size_last; /* memory used by them after last CGC */ 355 size_t db_erased_refs; /* Clause references on erased clauses */ 356 int cgc_space_factor; /* Max total/margin garbage */ 357 double cgc_stack_factor; /* Price to scan stack space */ 358 double cgc_clause_factor; /* Pce to scan clauses */ 359 } clauses; 360 361 struct 362 { size_t highest; /* highest source file index */ 363 size_t no_hole_before; /* All filled before here */ 364 srcfile_array array; /* index --> file */ 365 Table table; /* name --> file */ 366 } files; 367 368 #ifdef HAVE_TGETENT 369 struct 370 { int initialised; /* initialisation status */ 371 char *_string_area; /* static area for tgetent */ 372 char *_buf_area; /* another one */ 373 Table _capabilities; /* User-level capability table */ 374 } terminal; 375 #endif 376 377 #ifdef O_PLMT 378 struct 379 { int enabled; /* threads are enabled */ 380 Table mutexTable; /* Name --> mutex table */ 381 int mutex_next_id; /* next id for anonymous mutexes */ 382 #ifdef __WINDOWS__ 383 HINSTANCE instance; /* Win32 process instance */ 384 #endif 385 counting_mutex *mutexes; /* Registered mutexes */ 386 PL_thread_info_t *free; /* Free threads */ 387 int highest_allocated; /* Highest with info struct */ 388 int thread_max; /* Size of threads array */ 389 int highest_id; /* Highest Id of life thread */ 390 int peak_id; /* Highest Id of any thread */ 391 PL_thread_info_t **threads; /* Pointers to thread-info */ 392 struct 393 { pthread_mutex_t mutex; 394 pthread_cond_t cond; 395 unsigned int requests; 396 unsigned int initialized; /* mutex and condvar are initialized */ 397 } gc; 398 struct 399 { pthread_mutex_t mutex; 400 pthread_cond_t cond; 401 } index; 402 } thread; 403 #endif /*O_PLMT*/ 404 405 #ifdef O_LOCALE 406 struct 407 { Table localeTable; /* Name --> locale table */ 408 PL_locale *default_locale; /* System wide default */ 409 } locale; 410 #endif 411 412 struct stack combined_stack; /* ID for combined stack */ 413 }; 414 415 416 /******************************* 417 * LOCAL DATA * 418 *******************************/ 419 420 #define LD_MAGIC 0x3cfd82b4 /* Valid local-data structure */ 421 422 struct PL_local_data 423 { uintptr_t magic; /* LD_MAGIC */ 424 LocalFrame environment; /* Current local frame */ 425 Choice choicepoints; /* Choice-point chain */ 426 FliFrame foreign_environment; /* Current foreign context */ 427 QueryFrame query; /* Currently open query */ 428 Word mark_bar; /* Mark globals > this one */ 429 #ifdef O_GVAR 430 Word frozen_bar; /* Frozen part of the global stack */ 431 #endif 432 Code fast_condition; /* Fast condition support */ 433 pl_stacks_t stacks; /* Prolog runtime stacks */ 434 uintptr_t bases[STG_MASK+1]; /* area base addresses */ 435 int alerted; /* Special mode. See updateAlerted() */ 436 int slow_unify; /* do not use inline unification */ 437 int critical; /* heap is being modified */ 438 int break_level; /* current break level */ 439 Stack outofstack; /* thread is out of stack */ 440 int trim_stack_requested; /* perform a trim-stack */ 441 #ifdef O_PLMT 442 int exit_requested; /* Thread is asked to exit */ 443 #endif 444 int in_arithmetic; /* doing arithmetic */ 445 int in_print_message; /* Inside printMessage() */ 446 gen_t gen_reload; /* reload generation */ 447 void * glob_info; /* pl-glob.c */ 448 IOENC encoding; /* default I/O encoding */ 449 struct PL_local_data *next_free; /* see maybe_free_local_data() */ 450 451 struct 452 { int pending[2]; /* PL_raise() pending signals */ 453 int current; /* currently processing signal */ 454 int is_sync; /* current signal is synchronous */ 455 } signal; 456 457 struct 458 { int active; /* doing pipe I/O */ 459 jmp_buf context; /* context of longjmp() */ 460 } pipe; 461 462 struct 463 { char *getstr_buffer; /* getString() buffer */ 464 size_t getstr_buffer_size; /* size of getstr_buffer */ 465 struct wic_state *current_state; /* qlf-creation state */ 466 } qlf; 467 468 struct 469 { atom_t current; /* current global prompt */ 470 atom_t first; /* how to prompt first line */ 471 int first_used; /* did we do the first line? */ 472 int next; /* prompt on next read operation */ 473 } prompt; 474 475 source_location read_source; /* file, line, char of last term */ 476 477 struct 478 { term_t term; /* exception term */ 479 term_t bin; /* temporary handle for exception */ 480 term_t printed; /* already printed exception */ 481 term_t tmp; /* tmp for errors */ 482 term_t pending; /* used by the debugger */ 483 term_t fr_rewritten; /* processed by exception_hook() */ 484 int in_hook; /* inside exception_hook() */ 485 int processing; /* processing an exception */ 486 exception_frame *throw_environment; /* PL_throw() environments */ 487 } exception; 488 489 #ifdef O_ATTVAR 490 struct 491 { term_t head; /* Head of wakeup list */ 492 term_t tail; /* Tail of this list */ 493 term_t gc_attvars; /* place for attvars during GC */ 494 Word attvars; /* linked list of all attvars */ 495 int call_residue_vars_count; /* # call_residue_vars/2 active */ 496 } attvar; 497 #endif 498 499 struct 500 { term_t dummy; /* see trimStacks() */ 501 } trim; 502 503 struct 504 { term_t h[TMP_PTR_SIZE]; /* temporary handles. See unify_ptrs */ 505 int top; /* Top-of-stack index */ 506 } tmp; 507 508 #ifdef O_GVAR 509 struct 510 { Table nb_vars; /* atom --> value */ 511 int grefs; /* references to global stack */ 512 } gvar; 513 #endif 514 515 struct 516 { int64_t inferences; /* inferences in this thread */ 517 uintptr_t last_cputime; /* milliseconds last CPU time */ 518 uintptr_t last_systime; /* milliseconds last SYSTEM time */ 519 uintptr_t last_real_time; /* Last Real Time (seconds since Epoch) */ 520 double start_time; /* When Thread was started */ 521 double last_walltime; /* Last Wall time (m-secs since start) */ 522 double user_cputime; /* User saved CPU time */ 523 double system_cputime; /* Kernel saved CPU time */ 524 } statistics; 525 526 #ifdef O_GMP 527 struct 528 { int persistent; /* do persistent operations */ 529 size_t allocated; /* memory allocated */ 530 ar_context *context; /* current allocation context */ 531 mp_mem_header *head; /* linked list of allocated chunks */ 532 mp_mem_header *tail; 533 } gmp; 534 #endif 535 536 #ifdef O_PROFILE 537 struct 538 { int active; /* profiler is on */ 539 int accounting; /* we are accounting */ 540 int sum_ok; /* siblings are counted */ 541 struct call_node *current; /* `current' node */ 542 struct call_node *roots; /* list of root-nodes */ 543 uintptr_t samples; /* profile samples */ 544 uintptr_t ticks; /* profile ticks total */ 545 uintptr_t accounting_ticks; /* Ticks in profCall() and friends */ 546 uintptr_t nodes; /* #Recorded nodes */ 547 double time_at_last_tick; /* Time at last statistics tick */ 548 double time_at_start; /* Time at last start */ 549 double time; /* recorded CPU time */ 550 } profile; 551 #endif /* O_PROFILE */ 552 553 struct 554 { Module typein; /* module for type in goals */ 555 Module source; /* module we are reading clauses in */ 556 } modules; 557 558 struct 559 { intptr_t generator; /* See PL_atom_generator() */ 560 atom_t unregistering; /* See PL_unregister_atom() */ 561 } atoms; 562 563 struct 564 { VarDef * vardefs; /* compiler variable analysis */ 565 int nvardefs; 566 int filledVars; 567 } comp; 568 569 struct 570 { Buffer buffered; /* Buffered events */ 571 int delay_nesting; /* How deeply is delay nested? */ 572 573 #ifdef O_PLMT 574 struct 575 { struct event_list *onthreadexit; /* thread exit hook */ 576 } hook; 577 #endif 578 } event; 579 580 struct 581 { struct 582 { Number base; 583 Number top; 584 Number max; 585 } stack; 586 #ifdef O_GMP 587 struct 588 { gmp_randstate_t state; 589 int initialised; 590 } random; 591 struct 592 { size_t max_rational_size; 593 atom_t max_rational_size_action; 594 } rat; 595 #endif 596 struct 597 { unsigned int flags; /* FTL_* */ 598 } f; 599 } arith; 600 601 #if O_CYCLIC 602 struct 603 { segstack lstack; /* Stack for cycle-links */ 604 segstack vstack; /* Stack for visited marks */ 605 } cycle; 606 #endif 607 608 struct 609 { struct tbl_component *component; /* active component */ 610 struct trie *variant_table; /* Variant --> table */ 611 alloc_pool *node_pool; /* Node allocation pool for tries */ 612 int has_scheduling_component; /* A leader was created */ 613 int in_answer_completion; /* Running answer completion */ 614 term_t delay_list; /* Global delay list */ 615 term_t idg_current; /* Current node in IDG (trie symbol) */ 616 struct 617 { atom_t max_table_subgoal_size_action; 618 size_t max_table_subgoal_size; 619 atom_t max_table_answer_size_action; 620 size_t max_table_answer_size; 621 atom_t max_answers_for_subgoal_action; 622 size_t max_answers_for_subgoal; 623 } restraint; 624 } tabling; 625 626 struct 627 { 628 #ifdef __BEOS__ 629 status_t dl_error; /* dlopen() emulation in pl-beos.c */ 630 #endif 631 int rand_initialised; /* have we initialised random? */ 632 #ifdef O_DDE 633 unsigned dde_instance; /* Actually DWORD */ 634 #endif 635 } os; 636 637 struct 638 { Table table; /* Feature table */ 639 pl_features_t mask; /* Masked access to booleans */ 640 int write_attributes; /* how to write attvars? */ 641 occurs_check_t occurs_check; /* Unify and occurs check */ 642 access_level_t access_level; /* Current access level */ 643 } prolog_flag; 644 645 struct 646 { FindData find; /* /<ports> <goal> in tracer */ 647 } trace; 648 649 struct 650 { struct findall_bag *bags; /* Known bags */ 651 struct findall_bag *default_bag; /* Bag we keep around */ 652 #if defined(O_ATOMGC) && defined(O_PLMT) 653 simpleMutex mutex; /* Atom GC scanning synchronization */ 654 #endif 655 } bags; 656 657 struct 658 { AbortHandle _abort_head; /* PL_abort_hook() */ 659 AbortHandle _abort_tail; 660 661 buffer _discardable_buffer; /* PL_*() character buffers */ 662 string_stack string_buffers; /* PL_*() string buffers */ 663 664 int SP_state; /* For SICStus interface */ 665 } fli; 666 667 struct /* Local IO stuff */ 668 { IOSTREAM *streams[6]; /* handles for standard streams */ 669 st_check stream_type_check; /* Check bin/text streams? */ 670 /* do not copy from parent */ 671 struct input_context *input_stack; /* maintain input stream info */ 672 struct output_context *output_stack; /* maintain output stream info */ 673 int portray_nesting; /* depth of portray nesting */ 674 } IO; 675 676 struct 677 { fid_t numbervars_frame; /* Numbervars choice-point */ 678 } var_names; 679 680 #ifdef O_LIMIT_DEPTH 681 struct 682 { uintptr_t limit; 683 uintptr_t reached; 684 } depth_info; 685 #endif 686 687 #ifdef O_INFERENCE_LIMIT 688 struct 689 { int64_t limit; /* Raise at this count */ 690 } inference_limit; 691 #endif 692 693 definition_refs predicate_references; /* Referenced predicates */ 694 695 pl_shift_status_t shift_status; /* Stack shifter status */ 696 pl_debugstatus_t _debugstatus; /* status of the debugger */ 697 struct btrace *btrace_store; /* C-backtraces */ 698 699 #ifdef O_PLMT 700 struct 701 { intptr_t magic; /* PL_THREAD_MAGIC (checking) */ 702 struct _PL_thread_info_t *info; /* info structure */ 703 /* Communication */ 704 message_queue messages; /* Message queue */ 705 struct _thread_sig *sig_head; /* Head of signal queue */ 706 struct _thread_sig *sig_tail; /* Tail of signal queue */ 707 DefinitionChain local_definitions; /* P_THREAD_LOCAL predicates */ 708 simpleMutex scan_lock; /* Hold for asynchronous scans */ 709 alert_channel alert; /* How to alert the thread */ 710 } thread; 711 #endif 712 713 #ifdef O_LOCALE 714 struct 715 { PL_locale *current; /* Current locale */ 716 } locale; 717 #endif 718 719 struct 720 { size_t erased_skipped; /* # erased clauses skipped */ 721 int64_t cgc_inferences; /* Inferences at last cgc consider */ 722 } clauses; 723 724 struct 725 { DefinitionChain nesting; /* Nesting chain in the autoloader */ 726 Definition loop; /* We are looping on this def */ 727 } autoload; 728 729 struct 730 { intptr_t _total_marked; /* # marked global cells */ 731 intptr_t _trailcells_deleted; /* # garbage trailcells */ 732 intptr_t _relocation_chains; /* # relocation chains (debugging) */ 733 intptr_t _relocation_cells; /* # relocation cells */ 734 intptr_t _relocated_cells; /* # relocated cells */ 735 intptr_t _needs_relocation; /* # cells that need relocation */ 736 intptr_t _local_marked; /* # marked local -> global ptrs */ 737 intptr_t _marks_swept; /* # marks swept */ 738 intptr_t _marks_unswept; /* # marks swept */ 739 intptr_t _alien_relocations; /* # alien_into_relocation_chain() */ 740 intptr_t _local_frames; /* frame count for debugging */ 741 intptr_t _choice_count; /* choice-point count for debugging */ 742 int *_start_map; /* bitmap with legal global starts */ 743 sigset_t saved_sigmask; /* Saved signal mask */ 744 int64_t inferences; /* #inferences at last GC */ 745 pl_gc_status_t status; /* Garbage collection status */ 746 #ifdef O_CALL_RESIDUE 747 int marked_attvars; /* do not GC attvars */ 748 #endif 749 int active; /* GC is running in this thread */ 750 gc_stats stats; /* GC performance history */ 751 752 /* These must be at the end to be */ 753 /* able to define O_DEBUG in only */ 754 /* some modules */ 755 #if defined(O_DEBUG) || defined(SECURE_GC) 756 intptr_t _trailtops_marked; /* # marked trailtops */ 757 Word *_mark_base; /* Array of marked cells addresses */ 758 Word *_mark_top; /* Top of this array */ 759 Table _check_table; /* relocation address table */ 760 Table _local_table; /* marked local variables */ 761 int _relocated_check; /* Verify relocated addresses? */ 762 unsigned int incr_seed; /* Seed for random stack increments */ 763 #endif 764 } gc; 765 }; 766 767 GLOBAL PL_global_data_t PL_global_data; 768 GLOBAL PL_code_data_t PL_code_data; 769 GLOBAL PL_local_data_t PL_local_data; 770 #ifdef O_MULTIPLE_ENGINES 771 GLOBAL PL_local_data_t *PL_current_engine_ptr; 772 #endif 773 774 #define GD (&PL_global_data) 775 #define CD (&PL_code_data) 776 777 #define functor_array (GD->functors.array) 778 #define systemDefaults (GD->defaults) 779 780 #define environment_frame (LD->environment) 781 #define fli_context (LD->foreign_environment) 782 #define source_file_name (LD->read_source.file) 783 #define source_line_no (LD->read_source.position.lineno) 784 #define source_line_pos (LD->read_source.position.linepos) 785 #define source_char_no (LD->read_source.position.charno) 786 #define source_byte_no (LD->read_source.position.byteno) 787 #define exception_term (LD->exception.term) 788 #define exception_bin (LD->exception.bin) 789 #define exception_printed (LD->exception.printed) 790 #define gc_status (LD->gc.status) 791 #define debugstatus (LD->_debugstatus) 792 #define depth_limit (LD->depth_info.limit) 793 #define depth_reached (LD->depth_info.reached) 794 #define base_addresses (LD->bases) 795 #define Suser_input (LD->IO.streams[0]) 796 #define Suser_output (LD->IO.streams[1]) 797 #define Suser_error (LD->IO.streams[2]) 798 #define Scurin (LD->IO.streams[3]) 799 #define Scurout (LD->IO.streams[4]) 800 #define Sprotocol (LD->IO.streams[5]) 801 #define Sdin Suser_input /* not used for now */ 802 #define Sdout Suser_error 803 804 #ifdef VMCODE_IS_ADDRESS 805 #define dewam_table (CD->_dewam_table) 806 #define dewam_table_offset (CD->_dewam_table_offset) 807 #define wam_table (CD->_wam_table) 808 #define interpreter_jmp_table (CD->_interpreter_jmp_table) 809 #endif /*VMCODE_IS_ADDRESS*/ 810 811 #endif /*PL_GLOBAL_H_INCLUDED*/ 812