static void send(const T *data, struct sockaddr addr) { int fd; assert_((fd = ::socket(AF_INET, SOCK_STREAM, 0)) > -1, "socket"); assert_(::connect(fd, &addr, sizeof(addr)) > -1, "connect"); assert_(::send(fd, data, sizeof(T), 0) > -1, "send"); assert_(::close(fd) > -1, "close"); }
void start() { // sockaddr addr; // { // struct ifaddrs *ifs; // if (getifaddrs(&ifs) == -1) { // perror("getifaddrs"); // exit(EXIT_FAILURE); // } // /* Walk through linked list, maintaining head pointer so we // can free list later */ // for (auto ifa = ifs; ifa != NULL; ifa = ifa->ifa_next) { // if (ifa->ifa_addr == NULL) continue; // if (ifa->ifa_addr->sa_family == AF_INET) { // struct sockaddr_in *sin = (struct sockaddr_in*)ifa->ifa_addr; // printf("Interface %s, addr=%s\n", // ifa->ifa_name, inet_ntoa(sin->sin_addr)); // } // } // freeifaddrs(ifs); // } struct in_addr in; { int err; char hostname[512]; struct hostent *h; assert_(::gethostname(hostname, sizeof(hostname)) > -1, "gethostname"); assert_((h = ::gethostbyname(hostname)), "gethostbyname"); if (h->h_addrtype == AF_INET) { in = *(in_addr*)h->h_addr; // //err = inet_pton(AF_INET, h->h_addr, &in); // // if (err <= 0) perror("inet_pton"); // printf("using address %s(%i)\n", inet_ntoa(in), in.s_addr); } } struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = 0; sin.sin_addr.s_addr = in.s_addr; memset(sin.sin_zero, '\0', sizeof(sin.sin_zero)); int sock; assert_((sock = ::socket(PF_INET, SOCK_STREAM, 0)) > -1, "socket"); assert_(::bind(sock, (struct sockaddr*)&sin, sizeof(sin)) > -1, "bind"); assert_(::listen(sock, 10) > -1, "listen"); this->fd_ = sock; { Address addr = this->address(); printf("ArrayServer running on %s:%i\n", inet_ntoa(((sockaddr_in*)&addr)->sin_addr), ((sockaddr_in*)&addr)->sin_port); } }
void wait(T *data) const { struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); int fd, bytes; assert_((fd = ::accept(this->fd_, (sockaddr*)&addr, &addrlen)) > -1, "accept"); assert_((bytes = ::recv(fd, data, sizeof(T), 0)) > -1, "recv"); assert_(::close(fd) > -1, "close"); if (bytes != sizeof(T)) { throw std::runtime_error("wrong number of bytes received"); } }
/** * Wait for the singnal */ void CondVar::wait(Mutex *mutex) { #if defined(_SYS_MSVC_) || defined(_SYS_MINGW_) assert(mutex); CondVarCore* pcore = (CondVarCore*) opq_; CRITICAL_SECTION *mymutex = (CRITICAL_SECTION*) mutex->opq_; pcore->wait++; LeaveCriticalSection(mymutex); while (true) { WaitForSingleObject(pcore->sev, INFINITE); EnterCriticalSection(&pcore->mutex); if (pcore->wake > 0) { pcore->wait--; pcore->wake--; if (pcore->wake < 1) { ResetEvent(pcore->sev); SetEvent(pcore->fev); } LeaveCriticalSection(&pcore->mutex); break; } LeaveCriticalSection(&pcore->mutex); } EnterCriticalSection(mymutex); #else assert_(mutex); CondVarCore* pcore = (CondVarCore*)opq_; pthread_mutex_t* mymutex = (pthread_mutex_t*)mutex->opq_; if (pthread_cond_wait(&pcore->cond, mymutex) != 0) throw std::runtime_error("pthread_cond_wait"); #endif }
/* * Auxiliar. Calculates the square number for the given cell. Squares are * numberd from top to bottom, left to right. */ int square(int row, int col) { assert_(row >= MIN_NUM && row <= MAX_NUM && col >= MIN_NUM && col <= MAX_NUM); return (((row - 1) / SUBDIMENSION) * SUBDIMENSION) + ((col - 1) / SUBDIMENSION) + 1; }
/* * Checks if a cell value is set. Returns 1 if set, 0 otherwise. */ int is_set(struct board *b, int r, int c) { assert_(b != NULL && r >= MIN_NUM && r <= MAX_NUM && c >= MIN_NUM && c <= MAX_NUM); return (b->cells[r][c].has_value); }
TimePoint SteadyClock::now() noexcept { struct timespec tp; int err = clock_gettime(CLOCK_UPTIME_RAW, &tp); (void)err; assert_(err == 0); return TimePoint(s_to_ns(tp.tv_sec) + tp.tv_nsec); }
/* * Unsets a cell value in the given board. */ void unset_cell(struct board *b, int r, int c, int val) { assert_(b != NULL && r >= MIN_NUM && r <= MAX_NUM && c >= MIN_NUM && c <= MAX_NUM && val >= MIN_NUM && val <= MAX_NUM); assert_((*(b->cells[r][c].row_candidates))[val] && (*(b->cells[r][c].col_candidates))[val] && (*(b->cells[r][c].square_candidates))[val]); b->unset_cells += 1; b->cells[r][c].has_value = 0; b->cells[r][c].value = 0; restore_candidate(b->cells[r][c].row_candidates, val); restore_candidate(b->cells[r][c].col_candidates, val); restore_candidate(b->cells[r][c].square_candidates, val); }
/* * Sets a cell value in the given board. */ void set_cell(struct board *b, int r, int c, int val) { assert_(b != NULL && r >= MIN_NUM && r <= MAX_NUM && c >= MIN_NUM && c <= MAX_NUM && val >= MIN_NUM && val <= MAX_NUM); assert_((! (*(b->cells[r][c].row_candidates))[val]) && (! (*(b->cells[r][c].col_candidates))[val]) && (! (*(b->cells[r][c].square_candidates))[val])); b->unset_cells -= 1; b->cells[r][c].has_value = 1; b->cells[r][c].value = val; use_candidate(b->cells[r][c].row_candidates, val); use_candidate(b->cells[r][c].col_candidates, val); use_candidate(b->cells[r][c].square_candidates, val); }
/* * Finds the lowest candidate number which is free in all arrays, having a * value greater or equal to the "atleast" argument. */ int find_common_free(candidates *r, candidates *c, candidates *s, int atleast) { assert_(r != NULL && c != NULL && s != NULL); int i; for (i = atleast; i <= MAX_NUM; ++i) if ((! (*r)[i]) && (! (*c)[i]) && (! (*s)[i])) return i; return (-1); }
/* * Calculates the cell following a given one. Advances from top to bottom and * left to right. Returns 0 if there is no next cell, 1 otherwise and modifies * the arguments to point to the next cell in that case. */ int next_cell(int *r, int *c) { assert_(r != NULL && c != NULL); if ((*r) == MAX_NUM && (*c) == MAX_NUM) return 0; *c = following(*c); if ((*c) == MIN_NUM) (*r) = following(*r); return 1; }
/* * Prints the given board on screen. */ void print_board(struct board *b) { int i; int j; assert_(b != NULL); for (i = MIN_NUM; i <= MAX_NUM; ++i) { for (j = MIN_NUM; j <= MAX_NUM; ++j) printf(" %d", b->cells[i][j].value); printf("\n"); } }
const Tile* TileGrid::getTile(icoord phys) const noexcept { int x = dim.x; int y = dim.y; if (loopX) { phys.x = wrap(0, phys.x, dim.x); } if (loopY) { phys.y = wrap(0, phys.y, dim.y); } assert_(inBounds(phys)); int idx = (phys.z * y + phys.y) * x + phys.x; return &grid[idx]; }
/* * Solves a board starting with the given cell. Returns 1 if the board could be * solved, 0 if not. */ int solve_board(struct board *b, int r, int c) { int prev; int val; assert_(b != NULL && r >= MIN_NUM && r <= MAX_NUM && c >= MIN_NUM && c <= MAX_NUM); /* Base case: board solved, print it. */ if (b->unset_cells == 0) { print_board(b); return 1; } /* Find the next unset cell. */ while (is_set(b, r, c) && next_cell(&r, &c)) ; /* This should never happen. */ if (is_set(b, r, c)) return 1; /* Try every possible cell value until the board can be solved. */ prev = MIN_NUM; while (1) { val = find_common_free(b->cells[r][c].row_candidates, b->cells[r][c].col_candidates, b->cells[r][c].square_candidates, prev); if (val == -1) break; set_cell(b, r, c, val); if (solve_board(b, r, c)) return 1; unset_cell(b, r, c, val); prev = val+1; } return 0; }
/* * Reads a board from the given file. Format: a digit represents a cell value, * a dot represents an empty cell. Cells should be given from top to bottom and * left to right. All other characters are ignored. * * Example: * * 5 3 . . 7 . . . . * 6 . . 1 9 5 . . . * . 9 8 . . . . 6 . * 8 . . . 6 . . . 3 * 4 . . 8 . 3 . . 1 * 7 . . . 2 . . . 6 * . 6 . . . . 2 8 . * . . . 4 1 9 . . 5 * . . . . 8 . . 7 9 * */ void read_board(FILE *f, struct board *b) { int row; int col; int c; assert_(f != NULL && b != NULL); row = MIN_NUM; col = MIN_NUM; while (! feof(f)) { c = fgetc(f); if ((isdigit(c) && c != '0') || c == '.') { if (c != '.') set_cell(b, row, col, (c - '0')); if (! next_cell(&row, &col)) break; } } }
/* * Every board starts empty. Cell candidate pointers are established. */ void init_board(struct board *b) { int i; int j; assert_(b != NULL); b->unset_cells = TOTAL_NUMS * TOTAL_NUMS; for (i = MIN_NUM; i <= MAX_NUM; ++i) { init_candidates(b->rows + i); init_candidates(b->columns + i); init_candidates(b->squares + i); for (j = MIN_NUM; j <= MAX_NUM; ++j) { b->cells[i][j].has_value = 0; b->cells[i][j].value = 0; b->cells[i][j].row_candidates = b->rows + i; b->cells[i][j].col_candidates = b->columns + j; b->cells[i][j].square_candidates = b->squares + square(i, j); } } }
/* * Restoring a candidate means marking it as unused in the array. */ void restore_candidate(candidates *cp, int num) { assert_(cp != NULL && num >= MIN_NUM && num <= MAX_NUM); (*cp)[num] = 0; }
double TileGrid::indexDepth(int idx) const noexcept { assert_(0 <= idx && idx <= dim.z); return idx2depth[(size_t)idx]; }
Address address() const { struct sockaddr addr; socklen_t len = sizeof(addr); assert_(getsockname(this->fd_, &addr, &len) > -1, "getsockname"); return addr; }
/* * Calculates the number following a given one circularly. */ int following(int num) { assert_(num >= MIN_NUM && num <= MAX_NUM); return ((num - MIN_NUM + 1) % TOTAL_NUMS + MIN_NUM); }
UI::UI() noexcept { assert_(pool == nullptr); pool = Pool::makePool("ui", 1); }