00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "xsb_config.h"
00029 #include "xsb_debug.h"
00030
00031
00032 #include "debugs/debug_attv.h"
00033
00034 #include <stdio.h>
00035 #include <signal.h>
00036 #include <string.h>
00037
00038 #ifdef WIN_NT
00039 #include <windows.h>
00040 #include <process.h>
00041 #include <winbase.h>
00042 #include <stddef.h>
00043 #include <stdlib.h>
00044 #include <winsock.h>
00045 #include <io.h>
00046 #include <string.h>
00047 #else
00048 #include <pthread.h>
00049 #include <sched.h>
00050 #include <unistd.h>
00051 #endif
00052
00053 #include "auxlry.h"
00054 #include "cell_xsb.h"
00055 #include "debug_xsb.h"
00056 #include "error_xsb.h"
00057 #include "psc_xsb.h"
00058
00059 #include "memory_xsb.h"
00060 #include "register.h"
00061 #include "heap_xsb.h"
00062 #include "deref.h"
00063 #include "flags_xsb.h"
00064 #include "binding.h"
00065 #include "trie_internals.h"
00066 #include "trassert.h"
00067 #include "choice.h"
00068 #include "token_xsb.h"
00069 #include "sig_xsb.h"
00070 #include "inst_xsb.h"
00071 #include "macro_xsb.h"
00072 #include "table_stats.h"
00073 #include "unify_xsb.h"
00074 #include "subp.h"
00075 #include "thread_xsb.h"
00076 #include "debug_xsb.h"
00077 #include "hash_xsb.h"
00078 #include "trace_xsb.h"
00079
00080
00081 extern xsbBool quotes_are_needed(char *string);
00082
00083
00084
00085 #undef IFTHEN_FAILED
00086 #define IFTHEN_FAILED return 0
00087 #undef IFTHEN_SUCCEED
00088 #define IFTHEN_SUCCEED return 1
00089
00090 double realtime_count_gl;
00091
00092 #ifndef MULTI_THREAD
00093 extern int asynint_val;
00094 extern int asynint_code;
00095 #endif
00096
00097 extern void print_mutex_use(void);
00098
00099 extern void dis(xsbBool), debug_call(CTXTdeclc Psc);
00100
00101 #ifdef LINUX
00102 static struct sigaction act, oact;
00103 #endif
00104
00105 void (*xsb_default_segfault_handler)(int);
00106
00107
00108 #ifndef MULTI_THREAD
00109 Cell attv_interrupts[20480][2];
00110 #endif
00111
00112
00113
00114
00115
00116
00117 void add_interrupt(CTXTdeclc Cell op1, Cell op2) {
00118 int num;
00119
00120 #ifndef PRE_IMAGE_TRAIL
00121 #error "PRE_IMAGE_TRAIL has to be defined for add_interrupt() !"
00122 #else
00123
00124
00125
00126
00127
00128 num = int_val(cell(interrupt_reg));
00130 push_pre_image_trail(&(attv_interrupts[num][0]), op1);
00131 attv_interrupts[num][0] = op1;
00132 push_pre_image_trail(&(attv_interrupts[num][1]), op2);
00133 attv_interrupts[num][1] = op2;
00134 num++;
00135 push_pre_image_trail(interrupt_reg, makeint(num));
00136 bld_int(interrupt_reg, num);
00137
00138 #endif
00139 }
00140
00141
00142
00143
00144
00145 Cell build_interrupt_chain(CTXTdecl) {
00146 Cell head;
00147 CPtr tmp = &head;
00148 int num, i;
00149
00150 num = int_val(cell(interrupt_reg));
00151 for (i = 0; i < num; i++) {
00152 bld_list(tmp, hreg);
00153 sreg = hreg + 2;
00154 bld_list(hreg, sreg); hreg++;
00155 if (i == (num - 1)) {
00156 bind_nil(hreg);
00157 }
00158 else
00159 tmp = hreg;
00160 bld_copy(sreg, attv_interrupts[i][0]); sreg++;
00161 bld_copy(sreg, attv_interrupts[i][1]); sreg++;
00162 hreg = sreg;
00163 }
00164
00165 #ifndef PRE_IMAGE_TRAIL
00166 #error "PRE_IMAGE_TRAIL has to be defined for synint_proc() !"
00167 #else
00168
00169 push_pre_image_trail(interrupt_reg, makeint(0));
00170 #endif
00171
00172 bld_int(interrupt_reg, 0);
00173
00174 return head;
00175 }
00176
00177
00178
00179
00180
00181 xsbBool unify(CTXTdeclc Cell rop1, Cell rop2)
00182 {
00183 register Cell op1, op2;
00184
00185 op1 = rop1; op2 = rop2;
00186
00187
00188 unify_xsb(unify);
00189
00190
00191
00192
00193
00194 }
00195
00196
00197
00198
00199
00200
00201 xsbBool are_identical_terms(Cell term1, Cell term2) {
00202
00203 begin_are_identical_terms:
00204 XSB_Deref(term1);
00205 XSB_Deref(term2);
00206
00207 if ( term1 == term2 )
00208 return TRUE;
00209
00210 if ( cell_tag(term1) != cell_tag(term2) )
00211 return FALSE;
00212
00213 if ( cell_tag(term1) == XSB_STRUCT ) {
00214 CPtr cptr1 = clref_val(term1);
00215 CPtr cptr2 = clref_val(term2);
00216 Psc psc1 = (Psc)*cptr1;
00217 int i;
00218
00219 if ( psc1 != (Psc)*cptr2 )
00220 return FALSE;
00221
00222 for ( cptr1++, cptr2++, i = 0; i < (int)get_arity(psc1)-1; cptr1++, cptr2++, i++ )
00223 if ( ! are_identical_terms(*cptr1,*cptr2) )
00224 return FALSE;
00225 term1 = *cptr1;
00226 term2 = *cptr2;
00227 goto begin_are_identical_terms;
00228 }
00229 else if ( cell_tag(term1) == XSB_LIST ) {
00230 CPtr cptr1 = clref_val(term1);
00231 CPtr cptr2 = clref_val(term2);
00232
00233 if ( are_identical_terms(*cptr1, *cptr2) ) {
00234 term1 = *(cptr1 + 1);
00235 term2 = *(cptr2 + 1);
00236 goto begin_are_identical_terms;
00237 } else return FALSE;
00238 }
00239 else return FALSE;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 void print_statistics(CTXTdeclc int amount) {
00251
00252 switch (amount) {
00253
00254 case 0:
00255 #ifndef MULTI_THREAD
00256 realtime_count_gl = real_time();
00257 perproc_reset_stat();
00258
00259 reset_stat_total();
00260 xsb_mesg("Statistics is reset.");
00261 break;
00262 #else
00263 realtime_count_gl = real_time();
00264 break;
00265 #endif
00266
00267 case 1:
00268 perproc_stat();
00269 total_stat(CTXTc real_time()-realtime_count_gl);
00270 reset_stat_total();
00271 break;
00272
00273 case 2:
00274 #ifndef MULTI_THREAD
00275 print_detailed_tablespace_stats(CTXT);
00276 break;
00277 #else
00278 fprintf(stdwarn,"statistics(2) not yet implemented for MT engine\n");
00279 break;
00280 #endif
00281
00282 case 3:
00283 #ifndef MULTI_THREAD
00284 perproc_stat();
00285 total_stat(CTXTc real_time()-realtime_count_gl);
00286 reset_stat_total();
00287 print_detailed_tablespace_stats(CTXT);
00288 print_detailed_subsumption_stats();
00289 break;
00290 #else
00291 fprintf(stdwarn,"statistics(3) not yet implemented for MT engine\n");
00292 break;
00293 #endif
00294 case 4:
00295 print_mutex_use();
00296 break;
00297 case 5:
00298 dis(0);
00299 break;
00300 case 6:
00301 dis(1);
00302 break;
00303 #ifdef CP_DEBUG
00304 case 7:
00305 print_cp_backtrace();
00306 break;
00307 #endif
00308 case 8:
00309 symbol_table_stats();
00310 string_table_stats();
00311 break;
00312 }
00313 }
00314
00315
00316
00317
00318 static void default_inthandler(int intcode)
00319 {
00320 char message[80];
00321
00322 switch (intcode) {
00323 case MYSIG_UNDEF:
00324 xsb_exit("Undefined predicate; exiting by the default handler.");
00325 break;
00326 case MYSIG_KEYB:
00327 xsb_exit("Keyboard interrupt; exiting by the default handler.");
00328 break;
00329 case MYSIG_PSC:
00330 break;
00331 default:
00332 sprintf(message,
00333 "Unknown interrupt (%d) occured; exiting by the default handler",
00334 intcode);
00335 xsb_exit(message);
00336 break;
00337 }
00338 }
00339
00340
00341
00342
00343
00344 Pair build_call(CTXTdeclc Psc psc)
00345 {
00346 register Cell arg;
00347 register Pair callstr;
00348 register int i;
00349
00350 callstr = (Pair)hreg;
00351 new_heap_functor(hreg, psc);
00352 for (i=1; i <= (int)get_arity(psc); i++) {
00353 arg = cell(reg+i);
00354 nbldval(arg);
00355 }
00356 return callstr;
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 Psc synint_proc(CTXTdeclc Psc psc, int intcode)
00368 {
00369 if (pflags[intcode+INT_HANDLERS_FLAGS_START]==(Cell)0) {
00370
00371 default_inthandler(intcode);
00372 psc = 0;
00373 } else {
00374 switch (intcode) {
00375 case MYSIG_UNDEF:
00376 SYS_MUTEX_LOCK( MUTEX_LOAD_UNDEF ) ;
00377 case MYSIG_KEYB:
00378 case MYSIG_SPY:
00379 case MYSIG_TRACE:
00380 case THREADSIG_CANCEL:
00381 case MYSIG_CLAUSE:
00382 if (psc) bld_cs(reg+1, build_call(CTXTc psc));
00383 psc = (Psc)pflags[intcode+INT_HANDLERS_FLAGS_START];
00384 bld_int(reg+2, asynint_code);
00385 pcreg = get_ep(psc);
00386 break;
00387 case MYSIG_ATTV:
00388
00389 if (psc)
00390 bld_cs(reg+2, build_call(CTXTc psc));
00391 psc = (Psc)pflags[intcode+INT_HANDLERS_FLAGS_START];
00392
00393
00394
00395
00396
00397 bld_copy(reg + 1, build_interrupt_chain(CTXT));
00398
00399 pcreg = get_ep(psc);
00400 break;
00401 default:
00402 xsb_abort("Unknown intcode in synint_proc()");
00403 }
00404 }
00405 return psc;
00406 }
00407
00408 void init_interrupt(void);
00409
00410
00411
00412 void keyint_proc(int sig)
00413 {
00414 #ifdef MULTI_THREAD
00415 th_context *th = find_context(xsb_thread_self());
00416 #endif
00417 #ifndef LINUX
00418 init_interrupt();
00419 #endif
00420 if (asynint_val & KEYINT_MARK) {
00421 xsb_abort("unhandled keyboard interrupt");
00422 } else {
00423 asynint_val |= KEYINT_MARK;
00424 asynint_code = 0;
00425 }
00426 }
00427
00428
00429
00430
00431 void init_interrupt(void)
00432 {
00433 #if (defined(LINUX))
00434 act.sa_handler = keyint_proc;
00435 sigemptyset(&act.sa_mask);
00436 act.sa_flags = 0;
00437 sigaction(SIGINT, &act, &oact);
00438 #else
00439 signal(SIGINT, keyint_proc);
00440 #endif
00441
00442 #if (defined(DEBUG_VERBOSE) || defined(DEBUG_VM) || defined(DEBUG_ASSERTIONS) || defined(DEBUG))
00443
00444 xsb_default_segfault_handler = SIG_DFL;
00445 #else
00446 xsb_default_segfault_handler = xsb_segfault_quitter;
00447 #endif
00448
00449 #ifdef SIGBUS
00450 signal(SIGBUS, xsb_default_segfault_handler);
00451 #endif
00452 signal(SIGSEGV, xsb_default_segfault_handler);
00453 }
00454
00455
00456
00457
00458
00459 void intercept(CTXTdeclc Psc psc) {
00460
00461 if (pflags[CLAUSE_INT])
00462 synint_proc(CTXTc psc, MYSIG_CLAUSE);
00463 else if (flags[DEBUG_ON] && !flags[HIDE_STATE]) {
00464 if (get_spy(psc)) {
00465 synint_proc(CTXTc psc, MYSIG_SPY);
00466 flags[HIDE_STATE]++;
00467 }
00468 else if (flags[TRACE]) {
00469 synint_proc(CTXTc psc, MYSIG_TRACE);
00470 flags[HIDE_STATE]++;
00471 }
00472 }
00473 if (flags[HITRACE])
00474 debug_call(CTXTc psc);
00475
00476 #ifndef MULTI_THREAD
00477 if (flags[TRACE_STA]) {
00478 unsigned long byte_size;
00479
00480 byte_size = (top_of_heap - (CPtr)(glstack.low) + 1) * sizeof(Cell);
00481 if ( byte_size > tds.maxgstack_count )
00482 tds.maxgstack_count = byte_size;
00483
00484 byte_size = ((CPtr)glstack.high - top_of_localstk) * sizeof(Cell);
00485 if ( byte_size > tds.maxlstack_count )
00486 tds.maxlstack_count = byte_size;
00487
00488 byte_size = (top_of_trail - (CPtr *)tcpstack.low + 1) * sizeof(CPtr);
00489 if ( byte_size > tds.maxtrail_count )
00490 tds.maxtrail_count = byte_size;
00491
00492 byte_size = ((CPtr)tcpstack.high - top_of_cpstack) * sizeof(Cell);
00493 if ( byte_size > tds.maxcpstack_count )
00494 tds.maxcpstack_count = byte_size;
00495
00496 byte_size = ((CPtr)complstack.high - top_of_complstk) * sizeof(Cell);
00497 if ( byte_size > tds.maxopenstack_count )
00498 tds.maxopenstack_count = byte_size;
00499
00500 if ((unsigned long)level_num > tds.maxlevel_num)
00501 tds.maxlevel_num = level_num;
00502 }
00503 #endif
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 #ifdef BITS64
00515 #define FLOAT_MASK 0xfffffffffffffff8
00516 #else
00517 #define FLOAT_MASK 0xfffffff8
00518 #endif
00519
00520
00521 inline float getfloatval(Cell w)
00522 {
00523 FloatConv converter;
00524 converter.i = w & FLOAT_MASK;
00525 return converter.f;
00526 }
00527
00528 inline Cell makefloat(float f)
00529 {
00530 FloatConv converter;
00531 converter.f = f;
00532 return (Cell)(( converter.i & FLOAT_MASK ) | XSB_FLOAT);
00533 }
00534
00535 inline int sign(Float num)
00536 {
00537 if (num==0.0) return 0;
00538 else if (num>0.0) return 1;
00539 else return -1;
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 int compare(CTXTdeclc const void * v1, const void * v2)
00561 {
00562 int comp;
00563 CPtr cptr1, cptr2;
00564 Cell val1 = (Cell) v1 ;
00565 Cell val2 = (Cell) v2 ;
00566
00567 XSB_Deref(val2);
00568 XSB_Deref(val1);
00569 if (val1 == val2) return 0;
00570 switch(cell_tag(val1)) {
00571 case XSB_FREE:
00572 case XSB_REF1:
00573 if (isattv(val2))
00574 return vptr(val1) - (CPtr)dec_addr(val2);
00575 else if (isnonvar(val2)) return -1;
00576 else {
00577
00578
00579
00580 if ((top_of_localstk <= vptr(val1)) &&
00581 (vptr(val1) <= (CPtr)glstack.high-1)) {
00582 bld_free(hreg);
00583 bind_ref(vptr(val1), hreg);
00584 hreg++;
00585 val1 = follow(val1);
00586 }
00587 if ((top_of_localstk <= vptr(val2)) &&
00588 (vptr(val2) <= (CPtr)glstack.high-1)) {
00589 bld_free(hreg);
00590 bind_ref(vptr(val2), hreg);
00591 hreg++;
00592 val2 = follow(val2);
00593 }
00594 return vptr(val1) - vptr(val2);
00595 }
00596 case XSB_FLOAT:
00597 if (isref(val2) || isattv(val2)) return 1;
00598 else if (isofloat(val2))
00599 return sign(float_val(val1) - ofloat_val(val2));
00600 else return -1;
00601 case XSB_INT:
00602 if (isref(val2) || isofloat(val2) || isattv(val2)) return 1;
00603 else if (isinteger(val2))
00604 return int_val(val1) - int_val(val2);
00605 else if (isboxedinteger(val2))
00606 return int_val(val1) - boxedint_val(val2);
00607 else return -1;
00608 case XSB_STRING:
00609 if (isref(val2) || isofloat(val2) || isinteger(val2) || isattv(val2))
00610 return 1;
00611 else if (isstring(val2)) {
00612 return strcmp(string_val(val1), string_val(val2));
00613 }
00614 else return -1;
00615 case XSB_STRUCT:
00616
00617
00618
00619 if (isboxedinteger(val1)) {
00620 if (isref(val2) || isofloat(val2) || isattv(val2)) return 1;
00621 else if (isinteger(val2))
00622 return boxedint_val(val1) - int_val(val2);
00623 else if (isboxedinteger(val2))
00624 return boxedint_val(val1) - boxedint_val(val2);
00625 else return -1;
00626 } else if (isboxedfloat(val1)) {
00627 if (isref(val2) || isattv(val2)) return 1;
00628 else if (isofloat(val2))
00629 return sign(boxedfloat_val(val1) - ofloat_val(val2));
00630 else return -1;
00631 } else if (cell_tag(val2) != XSB_STRUCT && cell_tag(val2) != XSB_LIST) return 1;
00632 else {
00633 int arity1, arity2;
00634 Psc ptr1 = get_str_psc(val1);
00635 Psc ptr2 = get_str_psc(val2);
00636
00637 arity1 = get_arity(ptr1);
00638 if (islist(val2)) arity2 = 2;
00639 else arity2 = get_arity(ptr2);
00640 if (arity1 != arity2) return arity1-arity2;
00641 if (islist(val2)) comp = strcmp(get_name(ptr1), ".");
00642 else comp = strcmp(get_name(ptr1), get_name(ptr2));
00643 if (comp || (arity1 == 0)) return comp;
00644 cptr1 = clref_val(val1);
00645 cptr2 = clref_val(val2);
00646 for (arity2 = 1; arity2 <= arity1; arity2++) {
00647 if (islist(val2))
00648 comp = compare(CTXTc (void*)cell(cptr1+arity2), (void*)cell(cptr2+arity2-1));
00649 else
00650 comp = compare(CTXTc (void*)cell(cptr1+arity2), (void*)cell(cptr2+arity2));
00651 if (comp) break;
00652 }
00653 return comp;
00654 }
00655 break;
00656 case XSB_LIST:
00657 if (cell_tag(val2) != XSB_STRUCT && cell_tag(val2) != XSB_LIST) return 1;
00658 else if (isconstr(val2)) return -(compare(CTXTc (void*)val2, (void*)val1));
00659 else {
00660 cptr1 = clref_val(val1);
00661 cptr2 = clref_val(val2);
00662 comp = compare(CTXTc (void*)cell(cptr1), (void*)cell(cptr2));
00663 if (comp) return comp;
00664 return compare(CTXTc (void*)cell(cptr1+1), (void*)cell(cptr2+1));
00665 }
00666 break;
00667 case XSB_ATTV:
00668 if (isattv(val2))
00669 return (CPtr)dec_addr(val1) - (CPtr)dec_addr(val2);
00670 else if (isref(val2))
00671 return (CPtr)dec_addr(val1) - vptr(val2);
00672 else
00673 return -1;
00674 default:
00675 xsb_abort("Compare (unknown tag %ld); returning 0", cell_tag(val1));
00676 return 0;
00677 }
00678 }
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 int key_compare(CTXTdeclc const void * t1, const void * t2)
00689 {
00690 Cell term1 = (Cell) t1 ;
00691 Cell term2 = (Cell) t2 ;
00692
00693 XSB_Deref(term1);
00694 XSB_Deref(term2);
00695 return compare(CTXTc (void*)cell(clref_val(term1)+1), (void*)cell(clref_val(term2)+1));
00696 }
00697
00698
00699
00700
00701
00702
00703
00704 void print_aqatom(FILE *file, char *string) {
00705 int loc = 0;
00706
00707 fprintf(file,"'");
00708 while (string[loc] != '\0') {
00709 if (string[loc] == '\'') fprintf(file,"'");
00710 fprintf(file,"%c",string[loc++]);
00711 }
00712 fprintf(file,"'");
00713 }
00714
00715
00716
00717
00718
00719 void print_qatom(FILE *file, char *string)
00720 {
00721 if (quotes_are_needed(string)) print_aqatom(file, string);
00722 else fprintf(file, "%s", string);
00723 }
00724
00725
00726
00727
00728
00729
00730 void print_dqatom(FILE *file, char *string)
00731 {
00732 int loc = 0;
00733
00734 fprintf(file,"\"");
00735 while (string[loc] != '\0') {
00736 if (string[loc] == '"') fprintf(file,"\"");
00737 fprintf(file,"%c",string[loc++]);
00738 }
00739 fprintf(file,"\"");
00740 }
00741
00742
00743
00744
00745
00746 void print_op(FILE *file, char *string, int pos)
00747 {
00748 char *s;
00749 int need_blank = 0;
00750
00751 s = string;
00752 while (*s) {
00753 if (intype(*s) != SIGN) { need_blank = 1; break;}
00754 s++;
00755 }
00756 if (need_blank) {
00757 switch (pos) {
00758 case 1: print_qatom(file, string); putc(' ', file); break;
00759 case 2: putc(' ', file);
00760 print_qatom(file, string); putc(' ', file); break;
00761 case 3: putc(' ', file); print_qatom(file, string); break;
00762 }
00763 } else fprintf(file, "%s", string);
00764 }
00765
00766
00767
00768 void remove_incomplete_tables_reset_freezes(CTXTdecl)
00769 {
00770 remove_incomplete_tables();
00771 reset_freeze_registers;
00772 }
00773
00774
00775
00776
00777
00778 void xsb_segfault_catcher(int err)
00779 {
00780 char *tmp_message = xsb_segfault_message;
00781 #ifdef MULTI_THREAD
00782 xsb_exit(tmp_message);
00783 #else
00784 xsb_segfault_message = xsb_default_segfault_msg;
00785 printf("segfault!!\n");
00786 xsb_basic_abort(tmp_message);
00787 #endif
00788 }
00789
00790 void xsb_segfault_quitter(int err)
00791 {
00792 #ifdef MULTI_THREAD
00793 th_context *th = find_context(xsb_thread_self());
00794 #endif
00795 print_xsb_backtrace(CTXT);
00796 xsb_exit(xsb_segfault_message);
00797 }
00798
00799 #ifdef WIN_NT
00800
00801 void checkJavaInterrupt(void *info)
00802 {
00803 char ch;
00804 SOCKET intSocket = (SOCKET)info;
00805 xsb_dbgmsg((LOG_DEBUG, "Thread started on socket %ld",(int)intSocket));
00806 while(1){
00807 if (1!=recv(intSocket,&ch,1,0)) {
00808 xsb_warn("Problem handling interrupt from Java");
00809 }
00810 else
00811 xsb_mesg("--- Java interrupt detected");
00812
00813 fflush(stdout);
00814 fflush(stderr);
00815 fflush(stdmsg);
00816 fflush(stdwarn);
00817 fflush(stddbg);
00818 keyint_proc(SIGINT);
00819 }
00820 }
00821
00822 xsbBool startInterruptThread(SOCKET intSocket)
00823 {
00824 xsb_mesg("Beginning interrupt thread on socket %ld",(int)intSocket);
00825 #ifdef _MT
00826 _beginthread( checkJavaInterrupt, 0, (void*)intSocket );
00827 #endif
00828 return 1;
00829 }
00830 #endif
00831
00832
00833 extern long if_profiling;
00834 extern long prof_flag;
00835
00836 void setProfileBit(void *place_holder) {
00837 long unhandled = 0;
00838 #ifdef MULTI_THREAD
00839 th_context *th = find_context(xsb_thread_self());
00840 #endif
00841 while (TRUE) {
00842 if (if_profiling) {
00843 if (asynint_val & PROFINT_MARK) {
00844 unhandled++;
00845 if (!(unhandled % 10)) printf("Unhandled profile ints: %ld\n",unhandled);
00846 }
00847 asynint_val |= PROFINT_MARK;
00848 }
00849 #ifdef WIN_NT
00850 Sleep(10);
00851 #else
00852 sleep(0.01);
00853 #endif
00854 }
00855 }
00856
00857 xsbBool startProfileThread()
00858 {
00859 #ifdef WIN_NT
00860 HANDLE Thread;
00861 if (!if_profiling) {
00862 Thread = (HANDLE)_beginthread(setProfileBit,0,NULL);
00863 SetThreadPriority(Thread,THREAD_PRIORITY_HIGHEST);
00864 }
00865 #elif defined(SOLARIS)
00866 printf("Profiling not supported\n");
00867 #else
00868 pthread_t a_thread;
00869 struct sched_param param;
00870
00871 if (!if_profiling) {
00872 pthread_create(&a_thread, NULL, (void*)&setProfileBit, (void*)NULL);
00873 param.sched_priority = sched_get_priority_max(SCHED_OTHER);
00874 pthread_setschedparam(a_thread, SCHED_OTHER, ¶m);
00875
00876 if_profiling = 1;
00877 }
00878 #endif
00879 return TRUE;
00880 }