static srpaf_t truf_rpaf_find(truf_sym_t sym) { size_t hx = truf_sym_hx(sym); while (1) { /* just try what we've got */ for (size_t mod = 64U; mod <= zstk; mod *= 2U) { size_t off = get_off(hx, mod); if (LIKELY(rstk[off].sym.u == sym.u)) { /* found him */ return rstk + off; } else if (rstk[off].sym.u == 0U) { /* found empty slot */ rstk[off].sym = sym; /* init the rpaf cell */ rstk[off].rpaf->refprc = NANPX; rstk[off].rpaf->cruflo = ZEROPX; nstk++; return rstk + off; } } /* quite a lot of collisions, resize then */ rstk = recalloc(rstk, zstk, 2U * zstk, sizeof(*rstk)); zstk *= 2U; } }
/* * Convert an expression of the following forms to an off_t * 1) A positive decimal number. * 2) A positive decimal number followed by a b (mult by 512). * 3) A positive decimal number followed by a k (mult by 1024). * 4) A positive decimal number followed by a m (mult by 1048576). * 5) A positive decimal number followed by a w (mult by sizeof int) * 6) Two or more positive decimal numbers (with/without k,b or w). * separated by x (also * for backwards compatibility), specifying * the product of the indicated values. */ static off_t get_off(char *val) { off_t num, t; char *expr; num = strtoq(val, &expr, 0); if (num == QUAD_MAX) /* Overflow. */ err(1, "%s", oper); if (expr == val) /* No digits. */ errx(1, "%s: illegal numeric value", oper); switch(*expr) { case 'b': t = num; num *= 512; if (t > num) goto erange; ++expr; break; case 'k': case 'K': t = num; num *= 1024; if (t > num) goto erange; ++expr; break; case 'm': case 'M': t = num; num *= 1048576; if (t > num) goto erange; ++expr; break; case 'w': t = num; num *= sizeof(int); if (t > num) goto erange; ++expr; break; } switch(*expr) { case '\0': break; case '*': /* Backward compatible. */ case 'x': t = num; num *= get_off(expr + 1); if (t > num) erange: errx(1, "%s: %s", oper, strerror(ERANGE)); break; default: errx(1, "%s: illegal numeric value", oper); } return (num); }
static void f_skip(char *arg) { in.offset = get_off(arg); }
static void f_seek(char *arg) { out.offset = get_off(arg); }
/* * Convert an expression of the following forms to an off_t * 1) A positive decimal number, optionally followed by * b - multiply by 512. * k, m or g - multiply by 1024 each. * w - multiply by sizeof int * 2) Two or more of the above, separated by x * (or * for backwards compatibility), specifying * the product of the indicated values. */ static off_t get_off(char *val) { off_t num, t; char *expr; num = strtoll(val, &expr, 0); if (num == LLONG_MAX) /* Overflow. */ err(1, "%s", oper); if (expr == val) /* No digits. */ errx(1, "%s: illegal numeric value", oper); switch(*expr) { case 'b': t = num; num *= 512; if (t > num) goto erange; ++expr; break; case 'g': case 'G': t = num; num *= 1024; if (t > num) goto erange; /* fallthrough */ case 'm': case 'M': t = num; num *= 1024; if (t > num) goto erange; /* fallthrough */ case 'k': case 'K': t = num; num *= 1024; if (t > num) goto erange; ++expr; break; case 'w': t = num; num *= sizeof(int); if (t > num) goto erange; ++expr; break; } switch(*expr) { case '\0': break; case '*': /* Backward compatible. */ case 'x': t = num; num *= get_off(expr + 1); if (t > num) goto erange; break; default: errx(1, "%s: illegal numeric value", oper); } return (num); erange: errc(1, ERANGE, "%s", oper); }
TEST_CASE("RMARecords read write scenarios", "[rmarecords]") { auto sn_pair = MakeConnectedNodes<std::unique_ptr<t4s::ScifNode>>( [](int port) {return new t4s::ScifNode(port);}, //listener [](int node, int port) {return new t4s::ScifNode(node, port);} //connecter ); t4s::RMAWindow win_send(sn_pair[0]->createRMAWindow(0x1000, SCIF_PROT_READ | SCIF_PROT_WRITE)); t4s::RMAWindow win_recv(sn_pair[1]->createRMAWindow(0x1000, SCIF_PROT_READ | SCIF_PROT_WRITE)); t4s::Record inval; inval.start = inval.end = -1; std::fill_n(static_cast<t4s::Record *>(win_recv.get_mem()), win_recv.get_len()/sizeof(t4s::Record), inval); auto mmap_wr = sn_pair[0]->createMmapmem(win_recv.get_off(), 0x1000, SCIF_PROT_READ | SCIF_PROT_WRITE); auto mmap_buf = sn_pair[1]->createMmapmem(win_send.get_off(), 0x1000, SCIF_PROT_READ | SCIF_PROT_WRITE); REQUIRE(win_send.get_off() == mmap_buf.get_off()); REQUIRE(win_recv.get_off() == mmap_wr.get_off()); off_t win_recv_off = win_recv.get_off(); off_t win_send_off = win_send.get_off(); t4s::RMARecordsWriter sender(win_send, mmap_wr); t4s::RMARecordsReader recv(mmap_buf, win_recv); SECTION("Check read and write when recv_buf is empty") { REQUIRE_FALSE(recv.canRead()); REQUIRE(sender.canWrite()); } SECTION("Simple write read") { REQUIRE(sender.canWrite());