void print_agent(verbosity v, struct agent *a) { printf(v, "%d", a->tid); if (a->action.handling_timer) printf(v, "t"); if (a->action.context_switch) printf(v, "c"); if (a->action.forking) printf(v, "f"); if (a->action.sleeping) printf(v, "s"); if (a->action.vanishing) printf(v, "v"); if (a->action.readlining) printf(v, "r"); if (a->action.schedule_target) printf(v, "*"); if (BLOCKED(a)) printf(v, "<?%d>", a->blocked_on_tid); }
static bool report_deadlock(struct ls_state *ls) { if (BUG_ON_THREADS_WEDGED == 0) { return false; } if (!anybody_alive(ls->cpu0, &ls->test, &ls->sched, true)) { /* No threads exist. Not a deadlock, but rather end of test. */ return false; } struct agent *a; FOR_EACH_RUNNABLE_AGENT(a, &ls->sched, if (BLOCKED(a) && a->action.disk_io) { lsprintf(CHOICE, COLOUR_BOLD COLOUR_YELLOW "Warning, " "'ad-hoc' yield blocking (mutexes?) is not " "suitable for disk I/O! (TID %d)\n", a->tid); return false; }
void SokobanState::SpawnChildrenFrom(int i, std::vector<SokobanState*> &moves_to_add) const { // Loop through all the positions around the box for (int j = 0; j < 4; ++j) { // Make sure the player can reach the box if (scribble->IsReachable(boxes[i]-forward[j]) == false) { PRINT_VERBOSE("disregards moving box %d %c because the player is unable to reach\n", i, move_name[j]); continue; } Position p = boxes[i]; for (int k=1;;++k) { // Try to push this box forward p = p + forward[j]; // The position of the box // Is there an obstacle or a dead spot here? if (BLOCKED(p)) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of blocking box or wall\n", i, move_name[j], k); break; } if (POSCOST(p) < 0) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of bad position cost\n", i, move_name[j], k); break; } Position front = p + forward[j]; Position frontf = front + forward[j]; Position side1 = p + forward[(j+1)&3]; Position side11 = side1 + forward[(j+1)&3]; Position side11f = side11 + forward[j]; Position side1f = side1 + forward[j]; Position side1ff = side1f + forward[j]; Position side1b = side1 - forward[j]; Position side2 = p + forward[(j+3)&3]; Position side22 = side2 + forward[(j+3)&3]; Position side22f = side22 + forward[j]; Position side2f = side2 + forward[j]; Position side2ff = side2f + forward[j]; Position side2b = side2 - forward[j]; // Test for tunnels (push to the end) // #### #### // ->@$ => @$ // #### #### // Not on goal and walls on the sides if (POSCOST(p) > 0 && IS_WALL(side1) && IS_WALL(side2) && IS_WALL(side1f) && IS_WALL(side2f)) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of tunnel\n", i, move_name[j], k); continue; // keep searching forwards } if (BLOCKED(front)) { // Check for box-box deadlock // Check for 4 boxes with at least one not standing on a goal // Wall or box not on goal // ** // *$ if ( BLOCKED(side1) && BLOCKED(side1f) && (POSCOST(p) > 0 || POSCOST(side1) > 0 || POSCOST(side1f) > 0 || POSCOST(front) > 0 ) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of 4box-deadlock\n", i, move_name[j], k); break; } if ( BLOCKED(side2) && BLOCKED(side2f) && (POSCOST(p) > 0 || POSCOST(side2) > 0 || POSCOST(side2f) > 0 || POSCOST(front) > 0 ) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of 4box-deadlock\n", i, move_name[j], k); break; } // Check for S-deadlock // # // @$$ // # if ( (POSCOST(p) > 0 || POSCOST(front) > 0) && ((IS_WALL(side1) && IS_WALL(side2f)) || (IS_WALL(side2) && IS_WALL(side1f))) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of S-deadlock\n", i, move_name[j], k); break; } // Check for S-deadlock // # // $$ // @# if (IS_WALL(front)) { if ( BLOCKED(side1) && IS_WALL(side1b) && (POSCOST(p) > 0 || POSCOST(side1) > 0) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of S-deadlock\n", i, move_name[j], k); break; } if ( BLOCKED(side2) && IS_WALL(side2b) && (POSCOST(p) > 0 || POSCOST(side2) > 0) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of S-deadlock\n", i, move_name[j], k); break; } } } // Check for "elliptic" deadlock // Corner deadlock is a special case of elliptic deadlock // $$ ### // $ $ # $ // $$ #$ if (BLOCKED(front)) { // Test for corner position // @$$ // $ $ // $$ if (level.ValidPosition(side1f+(side1f-p)) && !BLOCKED(side1f) && BLOCKED(side1) && BLOCKED(side1f+(side1-p)) && BLOCKED(side1f+(side1f-p)) && BLOCKED(side1f+(front-p)) && (!EllipseOK(side1f) || (POSCOST(p) != 0 && POSCOST(side1f) != 0))) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } if (level.ValidPosition(side2f+(side2f-p)) && !BLOCKED(side2f) && BLOCKED(side2) && BLOCKED(side2f+(side2-p)) && BLOCKED(side2f+(side2f-p)) && BLOCKED(side2f+(front-p)) && (!EllipseOK(side2f) || (POSCOST(side2f) != 0 && POSCOST(p) != 0))) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } // Test for // $$ // $ $ //->@$$ if (level.ValidPosition(side1+(side1f-p)) && !BLOCKED(side1) && BLOCKED(side1-(front-p)) && BLOCKED(side1f) && BLOCKED(side1+(side1-p)) && BLOCKED(side1+(side1-p)-(front-p)) && (!EllipseOK(side1) )) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } if (level.ValidPosition(side2+(side2f-p)) && !BLOCKED(side2) && BLOCKED(side2-(front-p)) && BLOCKED(side2f) && BLOCKED(side2+(side2-p)) && BLOCKED(side2+(side2-p)-(front-p)) && (!EllipseOK(side2) )) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } } // Test for center position // $$ // @$ $ // $$ if (level.ValidPosition(front+(front-p)) && !BLOCKED(front) && BLOCKED(front+(front-p)) && BLOCKED(side1f) && BLOCKED(side2f) ) { if (BLOCKED(side1) && BLOCKED(side2f+(front-p)) && !EllipseOK(front)) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } if (BLOCKED(side2) && BLOCKED(side1f+(front-p)) && !EllipseOK(front)) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } } // Check for diamond deadlock // # // #-# // -$- if (POSCOST(p) != 0 && POSCOST(front) < 0 && POSCOST(side1) < 0 && POSCOST(side2) < 0 && IS_WALL(frontf) && IS_WALL(side1f) && IS_WALL(side2f) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of diamond deadlock\n", i, move_name[j], k); break; } int new_free_goals = free_goals; if (POSCOST(p) == 0) // On goal { // If this box is immobilized over a goal // Make sure that every free box can reach a free goal // @*# // # if ( IS_WALL(front) && (IS_WALL(side1) || IS_WALL(side2))) new_free_goals &= ~(1<<level.GetGoalAt(p)); // @** // ** if ( BLOCKED(front) && POSCOST(front) <= 0 && ((BLOCKED(side1) && POSCOST(side1) <= 0 && BLOCKED(side1f) && POSCOST(side1f) <= 0) || (BLOCKED(side2) && POSCOST(side2) <= 0 && BLOCKED(side2f) && POSCOST(side2f) <= 0)) ) { new_free_goals &= ~(1<<level.GetGoalAt(p)) & ~(1<<level.GetGoalAt(front)); if (BLOCKED(side1) && POSCOST(side1) <= 0 && BLOCKED(side1f) && POSCOST(side1f) <= 0) { new_free_goals &= ~(1<<level.GetGoalAt(side1)); new_free_goals &= ~(1<<level.GetGoalAt(side1f)); if (level.ValidPosition(frontf) && BLOCKED(frontf) && POSCOST(frontf) <= 0 && level.ValidPosition(side1ff) && BLOCKED(side1ff) && POSCOST(side1ff) <= 0) new_free_goals &= ~(1<<level.GetGoalAt(frontf)) & ~(1<<level.GetGoalAt(side1ff)); if (level.ValidPosition(side11) && BLOCKED(side11) && POSCOST(side11) <= 0 && level.ValidPosition(side11f) && BLOCKED(side11f) && POSCOST(side11f) <= 0) new_free_goals &= ~(1<<level.GetGoalAt(side11)) & ~(1<<level.GetGoalAt(side11f)); } if (BLOCKED(side2) && POSCOST(side2) <= 0 && BLOCKED(side2f) && POSCOST(side2f) <= 0) { new_free_goals &= ~(1<<level.GetGoalAt(side2)); new_free_goals &= ~(1<<level.GetGoalAt(side2f)); if (level.ValidPosition(frontf) && BLOCKED(frontf) && POSCOST(frontf) <= 0 && level.ValidPosition(side2ff) && BLOCKED(side2ff) && POSCOST(side2ff) <= 0) new_free_goals &= ~(1<<level.GetGoalAt(frontf)) & ~(1<<level.GetGoalAt(side2ff)); if (level.ValidPosition(side22) && BLOCKED(side22) && POSCOST(side22) <= 0 && level.ValidPosition(side22f) && BLOCKED(side22f) && POSCOST(side22f) <= 0) new_free_goals &= ~(1<<level.GetGoalAt(side22)) & ~(1<<level.GetGoalAt(side22f)); } bool bad_move = false; for (int b=0; b < num_boxes; ++b) { if (b==i) continue; if ( POSCOST(boxes[b]) != 0 && (scribble->GoalsReachable(boxes[b]) & new_free_goals) == 0 ) { Position delta = p-boxes[i]; PRINT_VERBOSE("box %d will be unable to reach any goal if box %d is moved (%d,%d)\n", b, i, delta.x, delta.y); // this is not an ok move bad_move = true; break; } } if (bad_move) break; } } SokobanState *s = new SokobanState(*this, i, move_name[j], k, new_free_goals); if (s->Cost() == unsigned(-1)) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of negative cost of new state\n", i, move_name[j], k); delete s; s = NULL; break; } moves_to_add.push_back(s); PRINT_VERBOSE("added move of box %d %c %d steps\n", i, move_name[j], k); } } }