static VariantSF bottom_leader(th_context *th, VariantSF to_sgf) { CPtr csf = subg_compl_stack_ptr(to_sgf) ; while( prev_compl_frame(csf) < COMPLSTACKBOTTOM && !is_leader(csf) ) csf = prev_compl_frame(csf) ; return compl_subgoal_ptr(csf) ; }
static void ReclaimDSandMarkReset(th_context *th, VariantSF to, int leader) { CPtr csf = openreg ; for(;;) { if( !is_completed(compl_subgoal_ptr(csf))) /* Handle early completion */ { subg_grabbed(compl_subgoal_ptr(csf)) = TRUE ; subg_tid(compl_subgoal_ptr(csf)) = leader ; subg_asf_list_ptr(compl_subgoal_ptr(csf)) = NULL; subg_compl_susp_ptr(compl_subgoal_ptr(csf)) = NULL; } if( compl_subgoal_ptr(csf) == to ) break; csf = prev_compl_frame(csf) ; } }
int count_sccs(CTXTdecl) { int ctr = 0; int last_scc = 0; CPtr csf = openreg; // printf("open %x COMPL %x\n",openreg,COMPLSTACKBOTTOM); while (csf < COMPLSTACKBOTTOM) { // printf("comp level %d\n",compl_level(csf)); if (compl_level(csf) != last_scc) { ctr++; last_scc = compl_level(csf); // printf("ctr: %d\n",ctr); } csf = prev_compl_frame(csf); } return ctr; }
static void reset_thread( th_context *th, th_context *ctxt, VariantSF sgf, VariantSF *resetsgf ) { CPtr tbreg ; /* if the subgoal is not being computed by this thread, because meanwhile it has been grabbed by another thread, nothing should be done */ if( subg_tid(sgf) != ctxt->tid ) { *resetsgf = ctxt->waiting_for_subgoal; return ; } sgf = bottom_leader(ctxt, sgf) ; *resetsgf = sgf ; #ifdef WIN_NT ReclaimDSandMarkReset(ctxt, sgf, xsb_thread_id); #else ReclaimDSandMarkReset(ctxt, sgf, (pthread_t) xsb_thread_id); #endif /* trick to use other thread's context */ th = ctxt ; /* reset the stacks by restoring the generator cp of this sg */ breg = subg_cp_ptr(sgf) ; tbreg = breg ; openreg = prev_compl_frame(subg_compl_stack_ptr(sgf)) ; switch_envs(tbreg); ptcpreg = tcp_ptcp(tbreg); delayreg = tcp_pdreg(tbreg); reclaim_stacks(tbreg) ; restore_some_wamregs(tbreg, ereg); /* restore_trail_condition_registers */ ebreg = cp_ebreg(tcp_prevbreg(tbreg)); hbreg = cp_hreg(tcp_prevbreg(tbreg)); pcreg = (byte *)tcp_reset_pcreg(tbreg) ; table_restore_registers(tbreg, pcreg[3], reg); /* delete the generator cp */ breg = tcp_prevbreg(breg) ; ctxt->reset_thread = TRUE; }