RTAI_SYSCALL_MODE unsigned long rt_bits_signal(BITS *bits, int setfun, unsigned long masks) { unsigned long flags, schedmap; RT_TASK *task; QUEUE *q; CHECK_BITS_MAGIC(bits); schedmap = 0; q = &bits->queue; flags = rt_global_save_flags_and_cli(); exec_fun[setfun](bits, masks); masks = bits->mask; while ((q = q->next) != &bits->queue) { task = q->task; if (test_fun[TEST_FUN(task)](bits, TEST_MASK(task))) { dequeue_blocked(task); rem_timed_task(task); if (task->state != RT_SCHED_READY && (task->state &= ~(RT_SCHED_SEMAPHORE | RT_SCHED_DELAYED)) == RT_SCHED_READY) { enq_ready_task(task); #ifdef CONFIG_SMP set_bit(task->runnable_on_cpus & 0x1F, &schedmap); #endif } } } RT_SCHEDULE_MAP(schedmap); rt_global_restore_flags(flags); return masks; }
RTAI_SYSCALL_MODE int _rt_bits_wait(BITS *bits, int testfun, unsigned long testmasks, int exitfun, unsigned long exitmasks, unsigned long *resulting_mask, int space) { RT_TASK *rt_current; unsigned long flags, mask = 0; int retval; CHECK_BITS_MAGIC(bits); flags = rt_global_save_flags_and_cli(); if (!test_fun[testfun](bits, testmasks)) { void *retpnt; long bits_test[2]; rt_current = RT_CURRENT; TEST_BUF(rt_current, bits_test); TEST_FUN(rt_current) = testfun; TEST_MASK(rt_current) = testmasks; rt_current->state |= RT_SCHED_SEMAPHORE; rem_ready_current(rt_current); enqueue_blocked(rt_current, &bits->queue, 1); rt_schedule(); if (unlikely((retpnt = rt_current->blocked_on) != NULL)) { if (likely(retpnt != RTP_OBJREM)) { dequeue_blocked(rt_current); retval = RTE_UNBLKD; } else { rt_current->prio_passed_to = NULL; retval = RTE_OBJREM; } goto retmask; } } retval = 0; mask = bits->mask; exec_fun[exitfun](bits, exitmasks); retmask: rt_global_restore_flags(flags); if (resulting_mask) { if (space) { *resulting_mask = mask; } else { rt_copy_to_user(resulting_mask, &mask, sizeof(mask)); } } return retval; }
int BoardIO::readFEN(Board &board, const string &buf) { board.reset(); for (int i = 0; i < 64; i++) { board.contents[i] = EmptyPiece; } char c; string::const_iterator bp = buf.begin(); size_t first = buf.find_first_not_of(" \t"); if (first != string::npos) { bp += first; } for (int line = 0; line < 8; line++) { int sqval = 56-line*8; while ((c = *bp) != ' ' && c != '/') { Piece piece; if (isdigit(c)) { sqval += (*bp - '0'); bp++; } else if (isalnum(c)) { if (!OnBoard(sqval)) { return 0; } switch (c) { case 'p': piece = BlackPawn; break; case 'n': piece = BlackKnight; break; case 'b': piece = BlackBishop; break; case 'r': piece = BlackRook; break; case 'q': piece = BlackQueen; break; case 'k': piece = BlackKing; break; case 'P': piece = WhitePawn; break; case 'N': piece = WhiteKnight; break; case 'B': piece = WhiteBishop; break; case 'R': piece = WhiteRook; break; case 'Q': piece = WhiteQueen; break; case 'K': piece = WhiteKing; break; default: return 0; } board.contents[sqval] = piece; sqval++; bp++; } else // not a letter or a digit { return 0; } } if (c=='/') ++bp; // skip delimiter } while (bp != buf.end() && isspace(*bp)) bp++; if (bp == buf.end()) return 0; if (toupper(*bp) == 'W') board.side = White; else if (toupper(*bp) == 'B') board.side = Black; else { return 0; } bp++; while (bp != buf.end() && isspace(*bp)) bp++; if (bp == buf.end()) return 0; c = *bp; if (c == '-') { // TBD: should try to infer if castling has occurred? board.state.castleStatus[White] = board.state.castleStatus[Black] = CantCastleEitherSide; bp++; } else { int k = 0; for (; bp != buf.end() && !isspace(*bp); bp++) { if (*bp == 'K') k += 1; else if (*bp == 'Q') k += 2; else if (*bp == 'k') k += 4; else if (*bp == 'q') k += 8; else { return 0; } } static const CastleType vals[4] = { CantCastleEitherSide, CanCastleKSide, CanCastleQSide, CanCastleEitherSide}; board.state.castleStatus[White] = vals[k % 4]; board.state.castleStatus[Black] = vals[k / 4]; } board.setSecondaryVars(); while (isspace(*bp)) bp++; if (bp == buf.end()) return 0; c = *bp; if (c == '-') { board.state.enPassantSq = InvalidSquare; } else if (isalpha(c)) { char sqbuf[2]; sqbuf[0] = *bp++; if (bp == buf.end()) return 0; sqbuf[1] = *bp++; Square epsq = SquareValue(sqbuf); if (epsq == InvalidSquare) { return 0; } board.state.enPassantSq = InvalidSquare; Square ep_candidate = SquareValue(sqbuf) - (8 * Direction[board.sideToMove()]); // only actually set the e.p. square on the board if an en-passant capture // is truly possible: if (TEST_MASK(Attacks::ep_mask[File(ep_candidate)-1][(int)board.oppositeSide()], board.pawn_bits[board.sideToMove()])) { board.state.enPassantSq = ep_candidate; // re-calc hash code since ep has changed board.state.hashCode = BoardHash::hashCode(board); } } else { return 0; } board.repList[board.state.moveCount++] = board.hashCode(); return 1; }