void improve_minE(struct clock_connection *clk) { int times_local_sent[9] = {0}; int times_remote_received[9] = {0}; // Set sleep time as 1/kSleepTimeDivider of the current bounds interval, // but never less or more than k(Min/Max)SleepUs. All pretty random // numbers that could use some tuning and may behave differently on // different devices. const int kMaxSleepUs = 700; const int kMinSleepUs = 70; const int kSleepTimeDivider = 10; int minE = clk->minE; int sleep_time = (clk->maxE - minE) / kSleepTimeDivider; if(sleep_time > kMaxSleepUs) sleep_time = kMaxSleepUs; if(sleep_time < kMinSleepUs) sleep_time = kMinSleepUs; // Clear everyhing on the remote side, this doesn't zero remote clock. send_cmd(clk, CMD_RESET); flush_incoming(clk); // Send digits to remote side int i; for (i = 0; i < 9; i++) { char c = i + '1'; times_local_sent[i] = micros(clk); send_async(clk, c); microsleep(sleep_time); } // Read out receive times from the other side read_remote_timestamps(clk, times_remote_received); // Do stats for (i = 0; i < 9; i++) { int tls = times_local_sent[i]; int trr = times_remote_received[i]; int dt; // Look at outgoing digits dt = tls - trr; if (tls != 0 && trr != 0 && dt > minE) { minE = dt; } } clk->minE = minE; LOGD("E is between %d and %d us, sleep_time=%d\n", clk->minE, clk->maxE, sleep_time); }
static int send_image_block(struct ploop_copy_handle *h, __u64 size, __u64 pos, ssize_t *nread) { struct delta *idelta = &h->idelta; void *iobuf = get_free_iobuf(h); ploop_dbg(4, "READ size=%llu pos=%llu", size, pos); *nread = pread(idelta->fd, iobuf, size, pos); if (*nread == 0) return 0; if (*nread < 0) { ploop_err(errno, "Error from read"); return SYSEXIT_READ; } return send_async(h, iobuf, *nread, pos); }
void improve_maxE(struct clock_connection *clk) { int times_remote_sent[9] = {0}; int times_local_received[9] = {0}; // Tell the remote to send us digits with delays // TODO: try tuning / configuring the delay time on remote side send_async(clk, CMD_SYNC_SEND); // Read and timestamp the incoming digits, they may arrive out of order. // TODO: Try he same with USBDEVFS_REAPURB, it might be faster int i; for (i = 0; i < 9; ++i) { int retval = bulk_read(clk); // TODO: deal with retval = (bytes returned) > 1. shouldn't happen. // Can it happen on some devices? int t_local = micros(clk); int digit = atoi(clk->buffer); if (digit <=0 || digit > 9) { LOGD("Error, bad incoming digit: %s\n", clk->buffer); } times_local_received[digit-1] = t_local; } // Flush whatever came after the digits. As of this writing, it's usually // a single linefeed character. flush_incoming(clk); // Read out the remote timestamps of when the digits were sent read_remote_timestamps(clk, times_remote_sent); // Do stats int maxE = clk->maxE; for (i = 0; i < 9; i++) { int trs = times_remote_sent[i]; int tlr = times_local_received[i]; int dt = tlr - trs; if (tlr != 0 && trs != 0 && dt < maxE) { maxE = dt; } } clk->maxE = maxE; LOGD("E is between %d and %d us\n", clk->minE, clk->maxE); }
int ploop_copy_stop(struct ploop_copy_handle *h, struct ploop_copy_stat *stat) { int ret; int iter; ploop_log(3, "pcopy last"); ret = freeze(h); if (ret) goto err; iter = 1; for (;;) { ret = ploop_copy_next_iteration(h, stat); if (ret) goto err; else if (stat->xferred == 0) break; if (iter++ > 2) { ploop_err(0, "Too many iterations on frozen FS, aborting"); return SYSEXIT_LOOP; } } if (!h->raw) { /* Must clear dirty flag on ploop1 image. */ struct ploop_pvd_header *vh = get_free_iobuf(h); if (PREAD(&h->idelta, vh, 4096, 0)) { ret = SYSEXIT_READ; goto err; } vh->m_DiskInUse = 0; ploop_dbg(3, "Update header"); ret = send_buf(h, vh, 4096, 0); if (ret) goto err; ret = send_optional_header(h); if (ret) goto err; } ploop_dbg(4, "IOCTL TRACK_STOP"); ret = ioctl(h->devfd, PLOOP_IOC_TRACK_STOP, 0); if (ret) goto err; h->tracker_on = 0; ploop_dbg(3, "SEND 0 0 (close)"); send_async(h, NULL, 0, 0); pthread_join(h->send_th, NULL); h->send_th = 0; ploop_dbg(3, "pcopy stop done"); err: ploop_copy_release(h); return ret; }