aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGene Cumm <gene.cumm@gmail.com>2011-11-30 23:15:23 -0500
committerGene Cumm <gene.cumm@gmail.com>2011-11-30 23:15:23 -0500
commit14dea45079563a7bfb533e132185ddda73c161e6 (patch)
treeec3ded28b7760f75c081e6ded5cd75513008dbc0
parentdfdfec6e416896fe2800b58ef3e14e648033c67a (diff)
downloadsyslinux-14dea45079563a7bfb533e132185ddda73c161e6.tar.gz
syslinux-14dea45079563a7bfb533e132185ddda73c161e6.tar.xz
syslinux-14dea45079563a7bfb533e132185ddda73c161e6.zip
cptime.c32: Simple module to test download rates
This uses standard file read operations to approximate the download rate from the current file system. Signed-off-by: Gene Cumm <gene.cumm@gmail.com>
-rw-r--r--com32/samples/cptime.c284
1 files changed, 284 insertions, 0 deletions
diff --git a/com32/samples/cptime.c b/com32/samples/cptime.c
new file mode 100644
index 00000000..0f5ffe61
--- /dev/null
+++ b/com32/samples/cptime.c
@@ -0,0 +1,284 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010-2011 Gene Cumm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * cptime.c Version 1.4
+ *
+ * Timed copy; read entire file then output total time, bytes transferred,
+ * and compute transfer rate.
+ *
+ * cptime [-s|-l] [-v|-q] [-b _SIZE_] [-n _LEN_] _FILE_...
+ * -s Change to simple output mode without computing transfer rate
+ * -l Change to long output mode (to allow for overriding previous -s)
+ * -v Verbose output
+ * -q Quiet output
+ * -b _SIZE_ use _SIZE_ for transfer size
+ * -n _LEN_ maximum length to fetch
+ * _FILE_... Space delimited list of files to dump
+ * Note: The last instance of -s or -l wins, along with the last use of -b and -n and the winning option will be applied to all operations
+ *
+ * Hisory:
+ * 1.4 Use fread() rather than read(); use CLK_TCK when available.
+ * 1.3 Added -v/-q; rework some argument processing.
+ * 1.2 Added -n
+ * 1.1 Added -l and -b switches; more flexible command line processing
+ * 1.0 First release
+ */
+
+/*
+ * ToDos:
+ * - Refine timing to be more precise. Low priority.
+ * - Add -o for offset. Wishlist.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/times.h>
+#include <consoles.h>
+#include <minmax.h>
+#include <limits.h>
+#include <string.h>
+#include <stdint.h>
+#include <console.h>
+
+#ifdef __COM32__
+# define BUFSZ_DEF (size_t)2048
+/* What's optimal? Under 4k?
+ * layout.inc: xfer_buf_seg equ 1000h
+ * com32.inc: push dword (1 << 16) ; 64K bounce buffer
+ */
+/* typedef size_t off_t */
+
+# define TPS_T float
+# ifdef CLK_TCK
+static inline TPS_T get_tps(void) { return CLK_TCK; }
+# else
+static inline TPS_T get_tps(void) { return 18.2; }
+# endif
+
+#else /* __COM32__ */
+
+# define BUFSZ_DEF (size_t)16384
+/* Need to check what might be a "best" buffer/fetch block size here */
+
+# define TPS_T long
+static inline TPS_T get_tps(void) { return sysconf(_SC_CLK_TCK); }
+
+#endif /* __COM32__ */
+
+#ifndef SSIZE_MAX
+# define SSIZE_MAX PTRDIFF_MAX
+#endif
+/* typedef ptrdiff_t ssize_t; */
+#define BUFSZ_MAX (size_t)SSIZE_MAX
+/* ssize_t max */
+#define BUFSZ_MIN (size_t)1
+
+
+/* Please note: I don't know the origin of these two macros nor their license */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+#define TYPE_MAX(t) \
+ ((t) (! TYPE_SIGNED (t) \
+ ? (t) -1 \
+ : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
+
+#ifndef OFF_T_MAX
+# define OFF_T_MAX TYPE_MAX(off_t)
+#endif
+/* Can't be SIZE_MAX or SSIZE_MAX as Syslinux/COM32 is unsigned while Linux
+ * is signed.
+ */
+
+#define LEN_MAX OFF_T_MAX
+/* off_t max */
+#define LEN_MIN (off_t)0
+
+void print_cp_result_tick(size_t bcnt, clock_t et, TPS_T tps, int offs)
+{
+ size_t dr;
+ /* prevent divide by 0 */
+ dr = max(bcnt, (bcnt * tps)) / max((clock_t)1, (et + offs));
+ printf(" %+d %zu B/s; %zu KiB/s; %zu MiB/s\n", offs, dr, dr/1024, dr/1048576);
+} /* void print_cp_result_tick(size_t bcnt, clock_t et, TPS_T tps, int offs) */
+
+void print_cp_result_long(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz, char do_verbose)
+{
+ TPS_T tps;
+ if (do_verbose > 2)
+ printf("Enter print_cp_result_long()\n");
+ tps = get_tps();
+ printf(" %zu B in %d ticks from '%s'\n", bcnt, (int)(ec - bc), fn);
+ printf(" ~%d ticks per second; %zu B block/transfer size\n", (int)tps, bufsz);
+ print_cp_result_tick(bcnt, (ec - bc), tps, 0);
+ print_cp_result_tick(bcnt, (ec - bc), tps, 1);
+ print_cp_result_tick(bcnt, (ec - bc), tps, -1);
+} /* void print_cp_result_long(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz) */
+
+void print_cp_result_simple(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz, char do_verbose)
+{
+ if (do_verbose) {}
+ printf(" %zuB %dt %zux '%s'\n", bcnt, (int)(ec - bc), bufsz, fn);
+} /* void print_cp_result_simple(char *fn, int bcnt, clock_t bc, clock_t ec, char do_verbose) */
+
+size_t time_copy_bufsz(size_t bufsz, size_t bcnt, off_t maxlen)
+{
+ return min(bufsz, (maxlen - bcnt));
+} /* size_t time_copy_bufsz(size_t bufsz, size_t bcnt, off_t maxlen) */
+
+int time_copy(char *fn, char do_simple, char do_verbose, size_t ibufsz, off_t maxlen)
+{
+// int fd;
+ int rv = 0;
+ int i = 0;
+ FILE *f;
+ size_t bufsz, bcnt = 0;
+ int numrd;
+ struct tms tm;
+ clock_t bc, ec;
+ char buf[ibufsz + 1];
+
+ buf[0] = 0;
+ if (do_verbose)
+ printf("Trying file '%s'\n", fn);
+ errno = 0;
+// fd = open(fn, O_RDONLY);
+ f = fopen(fn, "r");
+// if (fd == -1) {
+ if (!f) {
+ switch (errno) {
+ case ENOENT :
+ printf("File '%s' does not exist\n", fn);
+ break;
+ case EBADF:
+ printf("File '%s': Bad File Descriptor\n", fn);
+ break;
+ default :
+ printf("Error '%d' opening file '%s'\n", errno, fn);
+ }
+ rv = 1;
+ } else {
+ if (do_verbose)
+ printf("File '%s' opened\n", fn);
+ bufsz = time_copy_bufsz(ibufsz, bcnt, maxlen);
+ bc = times(&tm);
+// numrd = read(fd, buf, bufsz);
+// numrd = fread(buf, bufsz, 1, f);
+ numrd = fread(buf, 1, bufsz, f);
+ i++;
+ if (numrd > 0)
+ bcnt = numrd;
+ while ((numrd > 0) && (bufsz > 0)) {
+ bufsz = time_copy_bufsz(bufsz, bcnt, maxlen);
+// numrd = read(fd, buf, bufsz);
+// numrd = fread(buf, bufsz, 1, f);
+ numrd = fread(buf, 1, bufsz, f);
+ i++;
+ if (numrd >= 0)
+// bcnt = bcnt + numrd;
+ bcnt += numrd;
+ }
+ ec = times(&tm);
+// close(fd);
+ fclose(f);
+ if (do_verbose)
+ printf("File '%s' closed\n", fn);
+ if (numrd < 0) {
+ switch (errno) {
+ case EIO :
+ printf("IO Error at %zu B reading file '%s'\n", bcnt, fn);
+ break;
+ case EINVAL :
+ printf("Invalid Mode at %zu B reading file '%s'\n", bcnt, fn);
+ break;
+ default :
+ printf("Error '%d' at %zu B reading file '%s'\n", errno, bcnt, fn);
+ }
+ rv = 2;
+ }
+ if (bcnt > 0) {
+ if (bufsz == 0)
+ printf("maxed out on maxln\n");
+ if (do_simple)
+ print_cp_result_simple(fn, bcnt, bc, ec, ibufsz, do_verbose);
+ else
+ print_cp_result_long(fn, bcnt, bc, ec, ibufsz, do_verbose);
+ }
+ if (do_verbose)
+ printf(" numrd %d bcnt %d bufsz %d i %d\n", numrd, bcnt, bufsz, i);
+ }
+ return rv;
+} /* int time_copy(char *fn, char do_simple, int bufsz, off_t maxlen) */
+
+int main(int argc, char *argv[])
+{
+ int i;
+ char do_simple = 0, do_pbuf = 0, do_plen = 0, do_verbose = 0;
+ char *arg;
+ size_t tbufsz, bufsz = min((BUFSZ_DEF), (BUFSZ_MAX));
+ off_t tmaxlen, maxlen = LEN_MAX;
+ int numfl = 0;
+ console_ansi_std();
+// openconsole(&dev_stdcon_r, &dev_stdcon_w);
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ arg = argv[i] + 1;
+ if (strcmp(arg, "b") == 0) {
+ i++;
+ if (i < argc) {
+ tbufsz = atoi(argv[i]);
+ if (tbufsz > 0)
+ bufsz = min(max((BUFSZ_MIN), tbufsz), (BUFSZ_MAX));
+ do_pbuf = 1;
+ }
+ } else if (strcmp(arg, "n") == 0) {
+ i++;
+ if (i < argc) {
+ tmaxlen = atoi(argv[i]);
+ if (tmaxlen > 0)
+ maxlen = min(max((LEN_MIN), tmaxlen), (LEN_MAX));
+ do_plen = 1;
+ }
+ } else if (strcmp(arg, "s") == 0)
+ do_simple = 1;
+ else if (strcmp(arg, "l") == 0)
+ do_simple = 0;
+ else if (strcmp(arg, "v") == 0)
+ do_verbose = 1;
+ else if (strcmp(arg, "q") == 0)
+ do_verbose = 0;
+ }
+ }
+ if (do_pbuf || do_verbose)
+ printf("Using bufsz %zu\n", bufsz);
+ if (do_plen || do_verbose)
+ printf("Using maxlen %zu\n", maxlen);
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ arg = argv[i] + 1;
+ if ((strcmp(arg, "b") == 0) || (strcmp(arg, "n") == 0))
+ i++; /* Skip next arg */
+ else if (!((strcmp(arg, "s") == 0) || (strcmp(arg, "l") == 0) || (strcmp(arg, "v") == 0) || (strcmp(arg, "q") == 0))) {
+ time_copy(argv[i], do_simple, do_verbose, bufsz, maxlen);
+ numfl++;
+ }
+ } else {
+ time_copy(argv[i], do_simple, do_verbose, bufsz, maxlen);
+ numfl++;
+ }
+ }
+ if (numfl == 0)
+ fprintf(stderr, "%s: Please specify a file\n", argv[0]);
+ return 0;
+} /* int main(int argc, char *argv[]) */