| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | /************************************************************************
 | 
					
						
							|  |  |  | **                                                                     ** | 
					
						
							|  |  |  | **                   The YapTab/YapOr/OPTYap systems                   ** | 
					
						
							|  |  |  | **                                                                     ** | 
					
						
							|  |  |  | ** YapTab extends the Yap Prolog engine to support sequential tabling  ** | 
					
						
							|  |  |  | ** YapOr extends the Yap Prolog engine to support or-parallelism       ** | 
					
						
							|  |  |  | ** OPTYap extends the Yap Prolog engine to support or-parallel tabling ** | 
					
						
							|  |  |  | **                                                                     ** | 
					
						
							|  |  |  | **                                                                     ** | 
					
						
							|  |  |  | **      Yap Prolog was developed at University of Porto, Portugal      ** | 
					
						
							|  |  |  | **                                                                     ** | 
					
						
							|  |  |  | ************************************************************************/ | 
					
						
							| 
									
										
										
										
											2005-05-31 08:24:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | /* ------------------ **
 | 
					
						
							|  |  |  | **      Includes      ** | 
					
						
							|  |  |  | ** ------------------ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Yap.h"
 | 
					
						
							|  |  |  | #ifdef YAPOR
 | 
					
						
							|  |  |  | #include "Yatom.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-23 14:22:17 +01:00
										 |  |  | #include "YapHeap.h"
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #include "or.macros.h"
 | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  | #include "tab.macros.h"
 | 
					
						
							|  |  |  | #endif /* TABLING */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ------------------------------------- **
 | 
					
						
							|  |  |  | **      Local functions declaration      ** | 
					
						
							|  |  |  | ** ------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int move_up_one_node(or_fr_ptr nearest_livenode); | 
					
						
							|  |  |  | static int get_work_below(void); | 
					
						
							|  |  |  | static int get_work_above(void); | 
					
						
							|  |  |  | static int find_a_better_position(void); | 
					
						
							|  |  |  | static int search_for_hidden_shared_work(bitmap stable_busy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ----------------------- **
 | 
					
						
							|  |  |  | **      Local inlines      ** | 
					
						
							|  |  |  | ** ----------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-25 17:15:04 -05:00
										 |  |  | static inline void PUT_NO_WORK_IN_UPPER_NODES(void); | 
					
						
							|  |  |  | static inline void PUT_IDLE(int); | 
					
						
							|  |  |  | static inline void PUT_BUSY(int); | 
					
						
							|  |  |  | static inline void move_up_to_prune_request(void); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline | 
					
						
							|  |  |  | void PUT_NO_WORK_IN_UPPER_NODES(void) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   or_fr_ptr current_node, nearest_livenode; | 
					
						
							|  |  |  |   current_node = LOCAL_top_or_fr; | 
					
						
							|  |  |  |   while ((nearest_livenode = OrFr_nearest_livenode(current_node))) { | 
					
						
							|  |  |  |     OrFr_nearest_livenode(current_node) = NULL; | 
					
						
							|  |  |  |     current_node = nearest_livenode; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline | 
					
						
							|  |  |  | void PUT_IDLE(int worker_num) { | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   LOCK(GLOBAL_locks_bm_idle_workers); | 
					
						
							|  |  |  |   BITMAP_insert(GLOBAL_bm_idle_workers, worker_num); | 
					
						
							|  |  |  |   UNLOCK(GLOBAL_locks_bm_idle_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline | 
					
						
							|  |  |  | void PUT_BUSY(int worker_num) { | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   LOCK(GLOBAL_locks_bm_idle_workers); | 
					
						
							|  |  |  |   BITMAP_delete(GLOBAL_bm_idle_workers, worker_num); | 
					
						
							|  |  |  |   UNLOCK(GLOBAL_locks_bm_idle_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline | 
					
						
							|  |  |  | void move_up_to_prune_request(void) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2010-04-18 04:59:11 +01:00
										 |  |  |   YAPOR_ERROR_CHECKING(move_up_to_prune_request, EQUAL_OR_YOUNGER_CP(Get_LOCAL_prune_request(), Get_LOCAL_top_cp())); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     LOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  |     if (BITMAP_alone(OrFr_members(LOCAL_top_or_fr), worker_id)) { | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  |       if (OrFr_suspensions(LOCAL_top_or_fr) || OrFr_owners(LOCAL_top_or_fr) != 1) | 
					
						
							|  |  |  |         pruning_over_tabling_data_structures(); | 
					
						
							|  |  |  | #endif /* TABLING */
 | 
					
						
							|  |  |  |       CUT_free_solution_frames(OrFr_qg_solutions(LOCAL_top_or_fr)); | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |       CUT_free_tg_solution_frames(OrFr_tg_solutions(LOCAL_top_or_fr)); | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |       FREE_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       BITMAP_delete(OrFr_members(LOCAL_top_or_fr), worker_id); | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  |       OrFr_owners(LOCAL_top_or_fr)--; | 
					
						
							|  |  |  | #endif /* TABLING */
 | 
					
						
							|  |  |  |       UNLOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     SCH_update_local_or_tops(); | 
					
						
							| 
									
										
										
										
											2010-01-27 11:01:28 +00:00
										 |  |  |   } while (Get_LOCAL_top_cp() != Get_LOCAL_prune_request()); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   CUT_reset_prune_request(); | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |   Set_LOCAL_top_cp_on_stack( Get_LOCAL_top_cp()); | 
					
						
							|  |  |  |   abolish_incomplete_subgoals(Get_LOCAL_top_cp() - 1);  /* do not include LOCAL_top_cp */ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif /* TABLIG */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* -------------------------- **
 | 
					
						
							|  |  |  | **      Global functions      ** | 
					
						
							|  |  |  | ** -------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int get_work(void) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   int counter; | 
					
						
							|  |  |  |   bitmap stable_busy; | 
					
						
							|  |  |  |   yamop *alt_with_work; | 
					
						
							|  |  |  |   or_fr_ptr or_fr_with_work, or_fr_to_move_to; | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  |   choiceptr leader_node = DepFr_leader_cp(LOCAL_top_dep_fr); | 
					
						
							|  |  |  | #endif /* TABLING */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* reset local load */ | 
					
						
							|  |  |  |   LOCAL_load = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* check for prune request */ | 
					
						
							| 
									
										
										
										
											2010-01-27 11:01:28 +00:00
										 |  |  |   if (Get_LOCAL_prune_request()) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     move_up_to_prune_request(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* find nearest node with available work */ | 
					
						
							|  |  |  |   or_fr_with_work = LOCAL_top_or_fr; | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     or_fr_with_work = OrFr_nearest_livenode(or_fr_with_work); | 
					
						
							|  |  |  |     if (or_fr_with_work == NULL) | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     alt_with_work = OrFr_alternative(or_fr_with_work); | 
					
						
							|  |  |  |   } while (alt_with_work == NULL || YAMOP_SEQ(alt_with_work)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef TABLING
 | 
					
						
							|  |  |  |   /* wait for incomplete installations */ | 
					
						
							| 
									
										
										
										
											2010-01-15 12:04:01 +00:00
										 |  |  |   while (LOCAL_reply_signal != worker_ready); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif /* TABLING */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (or_fr_with_work) { | 
					
						
							|  |  |  |     /* move up to the nearest node with available work */ | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |     if (leader_node && YOUNGER_CP(leader_node, GetOrFr_node(or_fr_with_work))) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* there is a leader node before the nearest node with work */ | 
					
						
							|  |  |  |       or_fr_to_move_to = leader_node->cp_or_fr; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  | #endif /* TABLING */ 
 | 
					
						
							|  |  |  |       or_fr_to_move_to = or_fr_with_work; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       if (! move_up_one_node(or_fr_with_work)) | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } while (LOCAL_top_or_fr != or_fr_to_move_to); | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* no nodes with available work */ | 
					
						
							|  |  |  |   PUT_NO_WORK_IN_UPPER_NODES(); | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  |   if (leader_node) { | 
					
						
							|  |  |  |     /* there is a leader node */ | 
					
						
							|  |  |  |     or_fr_to_move_to = leader_node->cp_or_fr;; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       if (! move_up_one_node(NULL)) | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } while (LOCAL_top_or_fr != or_fr_to_move_to); | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* TABLING */ 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |   if (LOCAL_pruning_scope) { | 
					
						
							|  |  |  |     PUT_OUT_PRUNING(worker_id); | 
					
						
							|  |  |  |     LOCAL_pruning_scope = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |   PUT_OUT_ROOT_NODE(worker_id); | 
					
						
							|  |  |  |   LOCK_WORKER(worker_id); | 
					
						
							|  |  |  |   PUT_IDLE(worker_id); | 
					
						
							|  |  |  |   UNLOCK_WORKER(worker_id); | 
					
						
							|  |  |  |   SCH_refuse_share_request_if_any(); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   counter = 0; | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   BITMAP_difference(stable_busy, OrFr_members(LOCAL_top_or_fr), GLOBAL_bm_idle_workers); | 
					
						
							| 
									
										
										
										
											2014-02-13 10:13:45 +00:00
										 |  |  |    while (1) { | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |     while (BITMAP_subset(GLOBAL_bm_idle_workers, OrFr_members(LOCAL_top_or_fr)) && | 
					
						
							|  |  |  |            Get_LOCAL_top_cp() != Get_GLOBAL_root_cp()) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       /* no busy workers here and below */ | 
					
						
							|  |  |  |       if (! move_up_one_node(NULL)) { | 
					
						
							|  |  |  |         PUT_BUSY(worker_id); | 
					
						
							|  |  |  |         return TRUE; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |     if (Get_LOCAL_top_cp() == Get_GLOBAL_root_cp()) { | 
					
						
							|  |  |  |       if (! BITMAP_member(GLOBAL_bm_root_cp_workers, worker_id)) | 
					
						
							| 
									
										
										
										
											2014-02-13 10:13:45 +00:00
										 |  |  |         /* We need this extra bitmap because the GLOBAL_bm_idle_workers bitmap 
 | 
					
						
							|  |  |  |            is not enough to deal with sequential predicates. The condition of | 
					
						
							|  |  |  |            all workers being idle is not sufficient to ensure that there is no  | 
					
						
							|  |  |  |            available computation since a sequential predicate can still be resumed. | 
					
						
							|  |  |  |            Only when all workers are idle and in the root choicepoint it is safe to | 
					
						
							|  |  |  |            finish execution. */ | 
					
						
							| 
									
										
										
										
											2003-11-05 16:12:25 +00:00
										 |  |  |         PUT_IN_ROOT_NODE(worker_id); | 
					
						
							| 
									
										
										
										
											2014-02-13 10:13:45 +00:00
										 |  |  |       if (BITMAP_same(GLOBAL_bm_root_cp_workers, GLOBAL_bm_present_workers)) | 
					
						
							|  |  |  |         /* All workers are idle in the root choicepoint. Execution 
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |            must finish as there is no available computation. */ | 
					
						
							|  |  |  |         return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (get_work_below()) { | 
					
						
							|  |  |  |       PUT_BUSY(worker_id); | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (get_work_above()) { | 
					
						
							|  |  |  |       PUT_BUSY(worker_id); | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (find_a_better_position()) { | 
					
						
							|  |  |  |       PUT_BUSY(worker_id); | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |     if (++counter == GLOBAL_scheduler_loop) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       if (search_for_hidden_shared_work(stable_busy)) { | 
					
						
							|  |  |  |         PUT_BUSY(worker_id); | 
					
						
							|  |  |  |         return TRUE; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       counter = 0; | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |       BITMAP_difference(stable_busy, OrFr_members(LOCAL_top_or_fr), GLOBAL_bm_idle_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |       BITMAP_minus(stable_busy, GLOBAL_bm_idle_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ------------------------- **
 | 
					
						
							|  |  |  | **      Local functions      ** | 
					
						
							|  |  |  | ** ------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static | 
					
						
							|  |  |  | int move_up_one_node(or_fr_ptr nearest_livenode) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2010-04-18 04:59:11 +01:00
										 |  |  |   YAPOR_ERROR_CHECKING(move_up_one_node, Get_LOCAL_prune_request() && EQUAL_OR_YOUNGER_CP(Get_LOCAL_prune_request(), Get_LOCAL_top_cp())); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   LOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  |   /* last worker in a sequential choicepoint ? */ | 
					
						
							|  |  |  |   if (OrFr_alternative(LOCAL_top_or_fr)  | 
					
						
							|  |  |  |       && YAMOP_SEQ(OrFr_alternative(LOCAL_top_or_fr))  | 
					
						
							|  |  |  |       && BITMAP_alone(OrFr_members(LOCAL_top_or_fr), worker_id)) { | 
					
						
							|  |  |  |     UNLOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* pending prune ? */ | 
					
						
							| 
									
										
										
										
											2010-02-02 23:42:15 +00:00
										 |  |  |   if (Get_OrFr_pend_prune_cp(LOCAL_top_or_fr)  | 
					
						
							| 
									
										
										
										
											2010-01-27 11:01:28 +00:00
										 |  |  |       && ! Get_LOCAL_prune_request() | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       && CUT_last_worker_left_pending_prune(LOCAL_top_or_fr)) { | 
					
						
							| 
									
										
										
										
											2005-04-07 17:56:58 +00:00
										 |  |  | #ifdef TABLING
 | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |     choiceptr aux_cp = Get_LOCAL_top_cp(); | 
					
						
							| 
									
										
										
										
											2005-04-07 17:56:58 +00:00
										 |  |  | #endif /* TABLIG */
 | 
					
						
							| 
									
										
										
										
											2010-02-02 23:42:15 +00:00
										 |  |  |     choiceptr prune_cp = Get_OrFr_pend_prune_cp(LOCAL_top_or_fr); | 
					
						
							|  |  |  |     Set_OrFr_pend_prune_cp(LOCAL_top_or_fr, NULL); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     BRANCH(worker_id, OrFr_depth(LOCAL_top_or_fr)) = OrFr_pend_prune_ltt(LOCAL_top_or_fr); | 
					
						
							|  |  |  |     UNLOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							| 
									
										
										
										
											2012-02-27 17:18:01 +00:00
										 |  |  |     prune_shared_branch(prune_cp, &OrFr_pend_prune_ltt(LOCAL_top_or_fr)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef TABLING
 | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |     while (YOUNGER_CP(aux_cp->cp_b, Get_LOCAL_top_cp())) | 
					
						
							| 
									
										
										
										
											2005-04-07 17:56:58 +00:00
										 |  |  |       aux_cp = aux_cp->cp_b; | 
					
						
							|  |  |  |     abolish_incomplete_subgoals(aux_cp); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif /* TABLIG */
 | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-27 23:09:17 +01:00
										 |  |  |   OPTYAP_ERROR_CHECKING(move_up_one_node, B_FZ != DepFr_cons_cp(LOCAL_top_dep_fr)); | 
					
						
							|  |  |  |   OPTYAP_ERROR_CHECKING(move_up_one_node, LOCAL_top_susp_or_fr && EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp(), B_FZ) && YOUNGER_CP(GetOrFr_node(LOCAL_top_susp_or_fr), Get_LOCAL_top_cp())); | 
					
						
							|  |  |  |   OPTYAP_ERROR_CHECKING(move_up_one_node, LOCAL_top_susp_or_fr && YOUNGER_CP(B_FZ, Get_LOCAL_top_cp()) && YOUNGER_CP(GetOrFr_node(LOCAL_top_susp_or_fr), B_FZ)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  |   /* frozen stacks on branch ? */ | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |   if (YOUNGER_CP(B_FZ, Get_LOCAL_top_cp())) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (nearest_livenode) | 
					
						
							|  |  |  |       OrFr_nearest_livenode(LOCAL_top_or_fr) = nearest_livenode; | 
					
						
							|  |  |  |     BITMAP_delete(OrFr_members(LOCAL_top_or_fr), worker_id); | 
					
						
							|  |  |  |     if (BITMAP_empty(OrFr_members(LOCAL_top_or_fr))) { | 
					
						
							|  |  |  |       if (frame_with_suspensions_not_collected(LOCAL_top_or_fr)) { | 
					
						
							|  |  |  |         collect_suspension_frames(LOCAL_top_or_fr); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |       if (OrFr_tg_solutions(LOCAL_top_or_fr)) { | 
					
						
							|  |  |  |         tg_sol_fr_ptr tg_solutions; | 
					
						
							|  |  |  |         or_fr_ptr leftmost_until; | 
					
						
							|  |  |  |         tg_solutions = OrFr_tg_solutions(LOCAL_top_or_fr); | 
					
						
							|  |  |  |         leftmost_until = CUT_leftmost_until(LOCAL_top_or_fr, OrFr_depth(TgSolFr_gen_cp(tg_solutions)->cp_or_fr)); | 
					
						
							|  |  |  |         OrFr_tg_solutions(LOCAL_top_or_fr) = NULL; | 
					
						
							|  |  |  |         UNLOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  |         if (leftmost_until) { | 
					
						
							|  |  |  |           LOCK_OR_FRAME(leftmost_until); | 
					
						
							|  |  |  |           tg_solutions = CUT_store_tg_answers(leftmost_until, tg_solutions, | 
					
						
							|  |  |  |                                               BRANCH_LTT(worker_id, OrFr_depth(leftmost_until))); | 
					
						
							|  |  |  |           UNLOCK_OR_FRAME(leftmost_until); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         CUT_validate_tg_answers(tg_solutions); | 
					
						
							|  |  |  |         goto update_local_tops1; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     UNLOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |   update_local_tops1: | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |     SCH_update_local_or_tops(); | 
					
						
							| 
									
										
										
										
											2010-01-27 11:01:28 +00:00
										 |  |  |     if (Get_LOCAL_prune_request()) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       pruning_over_tabling_data_structures(); | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* suspension frames to resume ? */ | 
					
						
							|  |  |  |   if (OrFr_suspensions(LOCAL_top_or_fr)) { | 
					
						
							|  |  |  |     susp_fr_ptr resume_fr; | 
					
						
							|  |  |  | #ifdef TIMESTAMP_CHECK
 | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |     resume_fr = suspension_frame_to_resume(LOCAL_top_or_fr, ++GLOBAL_timestamp); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  |     resume_fr = suspension_frame_to_resume(LOCAL_top_or_fr); | 
					
						
							|  |  |  | #endif /* TIMESTAMP_CHECK */
 | 
					
						
							|  |  |  |     if (resume_fr) { | 
					
						
							|  |  |  |       if (LOCAL_top_susp_or_fr == LOCAL_top_or_fr && OrFr_suspensions(LOCAL_top_or_fr) == NULL) { | 
					
						
							|  |  |  |         LOCAL_top_susp_or_fr = OrFr_nearest_suspnode(LOCAL_top_or_fr); | 
					
						
							|  |  |  |         OrFr_nearest_suspnode(LOCAL_top_or_fr) = LOCAL_top_or_fr; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       UNLOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |       unbind_variables(TR, Get_LOCAL_top_cp()->cp_tr); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       resume_suspension_frame(resume_fr, LOCAL_top_or_fr); | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (LOCAL_top_susp_or_fr == LOCAL_top_or_fr) { | 
					
						
							|  |  |  |       LOCAL_top_susp_or_fr = OrFr_nearest_suspnode(LOCAL_top_or_fr); | 
					
						
							|  |  |  |       OrFr_nearest_suspnode(LOCAL_top_or_fr) = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else if (LOCAL_top_susp_or_fr == LOCAL_top_or_fr) { | 
					
						
							|  |  |  |     LOCAL_top_susp_or_fr = OrFr_nearest_suspnode(LOCAL_top_or_fr); | 
					
						
							|  |  |  |     OrFr_nearest_suspnode(LOCAL_top_or_fr) = LOCAL_top_or_fr; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /* top node frozen ? */ | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |   if (B_FZ == Get_LOCAL_top_cp()) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (nearest_livenode) | 
					
						
							|  |  |  |       OrFr_nearest_livenode(LOCAL_top_or_fr) = nearest_livenode; | 
					
						
							|  |  |  |     BITMAP_delete(OrFr_members(LOCAL_top_or_fr), worker_id); | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |     if (BITMAP_empty(OrFr_members(LOCAL_top_or_fr))) { | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |       if (OrFr_suspensions(LOCAL_top_or_fr) && OrFr_owners(LOCAL_top_or_fr) == 1) { | 
					
						
							|  |  |  |         complete_suspension_frames(LOCAL_top_or_fr); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |       if (OrFr_tg_solutions(LOCAL_top_or_fr)) { | 
					
						
							|  |  |  |         tg_sol_fr_ptr tg_solutions; | 
					
						
							|  |  |  |         or_fr_ptr leftmost_until; | 
					
						
							|  |  |  |         tg_solutions = OrFr_tg_solutions(LOCAL_top_or_fr); | 
					
						
							|  |  |  |         leftmost_until = CUT_leftmost_until(LOCAL_top_or_fr, OrFr_depth(TgSolFr_gen_cp(tg_solutions)->cp_or_fr)); | 
					
						
							|  |  |  |         OrFr_tg_solutions(LOCAL_top_or_fr) = NULL; | 
					
						
							|  |  |  |         UNLOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  |         if (leftmost_until) { | 
					
						
							|  |  |  |           LOCK_OR_FRAME(leftmost_until); | 
					
						
							|  |  |  |           tg_solutions = CUT_store_tg_answers(leftmost_until, tg_solutions, | 
					
						
							|  |  |  |                                               BRANCH_LTT(worker_id, OrFr_depth(leftmost_until))); | 
					
						
							|  |  |  |           UNLOCK_OR_FRAME(leftmost_until); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         CUT_validate_tg_answers(tg_solutions); | 
					
						
							|  |  |  |         goto update_local_tops2; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |     UNLOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |   update_local_tops2: | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |     SCH_update_local_or_tops(); | 
					
						
							| 
									
										
										
										
											2010-01-27 11:01:28 +00:00
										 |  |  |     if (Get_LOCAL_prune_request()) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       pruning_over_tabling_data_structures(); | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-27 23:09:17 +01:00
										 |  |  |   OPTYAP_ERROR_CHECKING(move_up_one_node, OrFr_alternative(LOCAL_top_or_fr) && ! YAMOP_SEQ(OrFr_alternative(LOCAL_top_or_fr))); | 
					
						
							|  |  |  |   OPTYAP_ERROR_CHECKING(move_up_one_node, Get_LOCAL_top_cp() == DepFr_cons_cp(LOCAL_top_dep_fr)); | 
					
						
							|  |  |  |   OPTYAP_ERROR_CHECKING(move_up_one_node, Get_LOCAL_top_cp() != Get_LOCAL_top_cp_on_stack()); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* no frozen nodes */ | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |   Set_LOCAL_top_cp_on_stack(GetOrFr_node(OrFr_next_on_stack(LOCAL_top_or_fr))); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* no more owners ? */ | 
					
						
							|  |  |  |   if (OrFr_owners(LOCAL_top_or_fr) == 1) { | 
					
						
							|  |  |  |     if (OrFr_suspensions(LOCAL_top_or_fr)) { | 
					
						
							|  |  |  |       complete_suspension_frames(LOCAL_top_or_fr); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |     if (LOCAL_top_sg_fr && Get_LOCAL_top_cp() == SgFr_gen_cp(LOCAL_top_sg_fr)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       mark_as_completed(LOCAL_top_sg_fr); | 
					
						
							|  |  |  |       LOCAL_top_sg_fr = SgFr_next(LOCAL_top_sg_fr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   /* last member worker in node ? */ | 
					
						
							|  |  |  |   if (BITMAP_alone(OrFr_members(LOCAL_top_or_fr), worker_id)) { | 
					
						
							|  |  |  | #endif /* TABLING */
 | 
					
						
							| 
									
										
										
										
											2010-01-27 11:01:28 +00:00
										 |  |  |     if (Get_LOCAL_prune_request()) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       CUT_free_solution_frames(OrFr_qg_solutions(LOCAL_top_or_fr)); | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |       CUT_free_tg_solution_frames(OrFr_tg_solutions(LOCAL_top_or_fr)); | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |       FREE_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  |       SCH_update_local_or_tops(); | 
					
						
							|  |  |  |       CUT_reset_prune_request(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       qg_sol_fr_ptr qg_solutions = OrFr_qg_solutions(LOCAL_top_or_fr); | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |       tg_sol_fr_ptr tg_solutions = OrFr_tg_solutions(LOCAL_top_or_fr); | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |       FREE_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  |       SCH_update_local_or_tops(); | 
					
						
							|  |  |  |       CUT_reset_prune_request(); | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |       if (qg_solutions || tg_solutions) { | 
					
						
							|  |  |  |         or_fr_ptr leftmost_or_fr; | 
					
						
							|  |  |  |         if (qg_solutions) | 
					
						
							|  |  |  |           CUT_join_answers_in_an_unique_frame(qg_solutions); | 
					
						
							|  |  |  |         leftmost_or_fr = CUT_leftmost_or_frame(); | 
					
						
							|  |  |  |         LOCK_OR_FRAME(leftmost_or_fr); | 
					
						
							|  |  |  |         if (qg_solutions) | 
					
						
							|  |  |  |           CUT_store_answers(leftmost_or_fr, qg_solutions); | 
					
						
							|  |  |  |         if (tg_solutions) | 
					
						
							|  |  |  |           tg_solutions = CUT_store_tg_answers(leftmost_or_fr, tg_solutions,  | 
					
						
							|  |  |  |                                               BRANCH_LTT(worker_id, OrFr_depth(leftmost_or_fr))); | 
					
						
							|  |  |  |         UNLOCK_OR_FRAME(leftmost_or_fr); | 
					
						
							|  |  |  |         CUT_validate_tg_answers(tg_solutions); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |       if (qg_solutions) { | 
					
						
							|  |  |  |         or_fr_ptr leftmost_or_fr; | 
					
						
							|  |  |  |         CUT_join_answers_in_an_unique_frame(qg_solutions); | 
					
						
							|  |  |  |         leftmost_or_fr = CUT_leftmost_or_frame(); | 
					
						
							|  |  |  |         LOCK_OR_FRAME(leftmost_or_fr); | 
					
						
							|  |  |  |         CUT_store_answers(leftmost_or_fr, qg_solutions); | 
					
						
							|  |  |  |         UNLOCK_OR_FRAME(leftmost_or_fr); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* more owners */ | 
					
						
							|  |  |  |   if (nearest_livenode) | 
					
						
							|  |  |  |     OrFr_nearest_livenode(LOCAL_top_or_fr) = nearest_livenode; | 
					
						
							|  |  |  |   BITMAP_delete(OrFr_members(LOCAL_top_or_fr), worker_id); | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  |   OrFr_owners(LOCAL_top_or_fr)--; | 
					
						
							|  |  |  |   if (BITMAP_empty(OrFr_members(LOCAL_top_or_fr))) { | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |     if (OrFr_tg_solutions(LOCAL_top_or_fr)) { | 
					
						
							|  |  |  |       tg_sol_fr_ptr tg_solutions; | 
					
						
							|  |  |  |       or_fr_ptr leftmost_until; | 
					
						
							|  |  |  |       tg_solutions = OrFr_tg_solutions(LOCAL_top_or_fr); | 
					
						
							|  |  |  |       leftmost_until = CUT_leftmost_until(LOCAL_top_or_fr, OrFr_depth(TgSolFr_gen_cp(tg_solutions)->cp_or_fr)); | 
					
						
							| 
									
										
										
										
											2010-01-27 11:01:28 +00:00
										 |  |  |       if (Get_LOCAL_prune_request()) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |         pruning_over_tabling_data_structures(); | 
					
						
							|  |  |  |       OrFr_tg_solutions(LOCAL_top_or_fr) = NULL; | 
					
						
							|  |  |  |       UNLOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  |       if (leftmost_until) { | 
					
						
							|  |  |  |         LOCK_OR_FRAME(leftmost_until); | 
					
						
							|  |  |  |         tg_solutions = CUT_store_tg_answers(leftmost_until, tg_solutions, | 
					
						
							|  |  |  |                                             BRANCH_LTT(worker_id, OrFr_depth(leftmost_until))); | 
					
						
							|  |  |  |         UNLOCK_OR_FRAME(leftmost_until); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       CUT_validate_tg_answers(tg_solutions); | 
					
						
							|  |  |  |       goto update_local_tops3; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							| 
									
										
										
										
											2010-01-27 11:01:28 +00:00
										 |  |  |     if (Get_LOCAL_prune_request()) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       pruning_over_tabling_data_structures(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* TABLING */
 | 
					
						
							|  |  |  |   UNLOCK_OR_FRAME(LOCAL_top_or_fr); | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |   update_local_tops3: | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |   if (LOCAL_top_sg_fr && Get_LOCAL_top_cp() == SgFr_gen_cp(LOCAL_top_sg_fr)) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     LOCAL_top_sg_fr = SgFr_next(LOCAL_top_sg_fr); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* TABLING */
 | 
					
						
							|  |  |  |   SCH_update_local_or_tops(); | 
					
						
							|  |  |  |   CUT_reset_prune_request(); | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static | 
					
						
							|  |  |  | int get_work_below(void){ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   int i, worker_p, big_load; | 
					
						
							|  |  |  |   bitmap busy_below, idle_below; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   worker_p = -1; | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   big_load = GLOBAL_delayed_release_load ; | 
					
						
							|  |  |  |   BITMAP_difference(busy_below, OrFr_members(LOCAL_top_or_fr), GLOBAL_bm_idle_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   BITMAP_difference(idle_below, OrFr_members(LOCAL_top_or_fr), busy_below); | 
					
						
							|  |  |  |   BITMAP_delete(idle_below, worker_id); | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   for (i = 0; i < GLOBAL_number_workers; i++) { | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |     if (BITMAP_member(idle_below ,i) && YOUNGER_CP(REMOTE_top_cp(i), Get_LOCAL_top_cp())) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       BITMAP_minus(busy_below, OrFr_members(REMOTE_top_or_fr(i))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (BITMAP_empty(busy_below)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   /* choose the worker with highest load */ | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   for (i = 0 ; i < GLOBAL_number_workers; i++) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (BITMAP_member(busy_below ,i) && REMOTE_load(i) > big_load) { | 
					
						
							|  |  |  |       worker_p = i; | 
					
						
							|  |  |  |       big_load = REMOTE_load(i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (worker_p == -1)  | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   return (q_share_work(worker_p)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static | 
					
						
							|  |  |  | int get_work_above(void){ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   int i, worker_p, big_load; | 
					
						
							|  |  |  |   bitmap visible_busy_above, visible_idle_above; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   worker_p = -1;  | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   big_load = GLOBAL_delayed_release_load ; | 
					
						
							|  |  |  |   BITMAP_difference(visible_busy_above, GLOBAL_bm_present_workers, OrFr_members(LOCAL_top_or_fr)); | 
					
						
							|  |  |  |   BITMAP_minus(visible_busy_above, GLOBAL_bm_invisible_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   BITMAP_copy(visible_idle_above, visible_busy_above);  | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   BITMAP_minus(visible_busy_above, GLOBAL_bm_idle_workers); | 
					
						
							|  |  |  |   BITMAP_and(visible_idle_above, GLOBAL_bm_idle_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   BITMAP_insert(visible_busy_above, worker_id); | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   for (i = 0 ; i < GLOBAL_number_workers; i++) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (BITMAP_member(visible_idle_above, i)) | 
					
						
							|  |  |  |       BITMAP_minus(visible_busy_above, OrFr_members(REMOTE_top_or_fr(i))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!BITMAP_member(visible_busy_above, worker_id) || BITMAP_alone(visible_busy_above, worker_id)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   BITMAP_delete(visible_busy_above, worker_id); | 
					
						
							|  |  |  |   /* choose the worker with higher load */ | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   for (i = 0; i < GLOBAL_number_workers; i++) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (BITMAP_member(visible_busy_above ,i) && REMOTE_load(i) > big_load) { | 
					
						
							|  |  |  |       worker_p = i; | 
					
						
							|  |  |  |       big_load = REMOTE_load(i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (worker_p == -1) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   /* put workers invisibles */ | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   LOCK(GLOBAL_locks_bm_invisible_workers); | 
					
						
							|  |  |  |   if (BITMAP_member(GLOBAL_bm_invisible_workers, worker_p)) { | 
					
						
							|  |  |  |     UNLOCK(GLOBAL_locks_bm_invisible_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   BITMAP_insert(GLOBAL_bm_invisible_workers, worker_id); | 
					
						
							|  |  |  |   BITMAP_insert(GLOBAL_bm_invisible_workers, worker_p); | 
					
						
							|  |  |  |   UNLOCK(GLOBAL_locks_bm_invisible_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   /* move up to cp with worker_p */ | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     if (! move_up_one_node(NULL)) { | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (! BITMAP_member(OrFr_members(LOCAL_top_or_fr), worker_p)); | 
					
						
							|  |  |  |   /* put workers visibles */ | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   LOCK(GLOBAL_locks_bm_invisible_workers); | 
					
						
							|  |  |  |   BITMAP_delete(GLOBAL_bm_invisible_workers, worker_id); | 
					
						
							|  |  |  |   BITMAP_delete(GLOBAL_bm_invisible_workers, worker_p); | 
					
						
							|  |  |  |   UNLOCK(GLOBAL_locks_bm_invisible_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   return (q_share_work(worker_p)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static | 
					
						
							|  |  |  | int find_a_better_position(void){ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   int i; | 
					
						
							|  |  |  |   bitmap busy_above, idle_above; | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   BITMAP_difference(busy_above, GLOBAL_bm_present_workers, OrFr_members(LOCAL_top_or_fr)); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   BITMAP_copy(idle_above, busy_above);  | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   BITMAP_minus(busy_above, GLOBAL_bm_idle_workers); | 
					
						
							|  |  |  |   BITMAP_and(idle_above, GLOBAL_bm_idle_workers); | 
					
						
							|  |  |  |   for (i = 0; i < GLOBAL_number_workers; i++) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (BITMAP_member(idle_above, i)) { | 
					
						
							|  |  |  |       if (BITMAP_empty(busy_above))  | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       if (BITMAP_member(OrFr_members(REMOTE_top_or_fr(i)), worker_id)) | 
					
						
							|  |  |  |         BITMAP_clear(busy_above); | 
					
						
							|  |  |  |       BITMAP_minus(busy_above, OrFr_members(REMOTE_top_or_fr(i))); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (BITMAP_empty(busy_above)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   /* move up to cp with all workers of bitmap busy_above */ | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     if (! move_up_one_node(NULL)) { | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (! BITMAP_subset(OrFr_members(LOCAL_top_or_fr), busy_above)); | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static | 
					
						
							|  |  |  | int search_for_hidden_shared_work(bitmap stable_busy){ | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   int i; | 
					
						
							|  |  |  |   bitmap invisible_work, idle_below; | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   BITMAP_intersection(invisible_work, stable_busy, GLOBAL_bm_requestable_workers); | 
					
						
							|  |  |  |   BITMAP_intersection(idle_below, OrFr_members(LOCAL_top_or_fr), GLOBAL_bm_idle_workers); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   BITMAP_delete(idle_below, worker_id); | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   for (i = 0; i < GLOBAL_number_workers; i++) { | 
					
						
							| 
									
										
										
										
											2010-01-14 15:58:19 +00:00
										 |  |  |     if (BITMAP_member(idle_below ,i) && YOUNGER_CP(REMOTE_top_cp(i), Get_LOCAL_top_cp())) | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       BITMAP_minus(invisible_work, OrFr_members(REMOTE_top_or_fr(i))); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (BITMAP_empty(invisible_work)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   /* choose the first available worker */ | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   for (i = 0; i < GLOBAL_number_workers; i++ ) { | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     if (BITMAP_member(invisible_work ,i)) | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return (q_share_work(i)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* YAPOR */
 |