Path: blob/main/misc/buffer/files/patch-buffer.c
16126 views
--- buffer.c.orig Sat Jan 19 20:47:17 20021+++ buffer.c Tue Dec 13 11:57:38 20052@@ -114,12 +114,17 @@3#include <signal.h>4#include <fcntl.h>5#include <errno.h>6+#include <machine/param.h>7#include <sys/types.h>8#include <sys/stat.h>9#include <sys/ipc.h>10#include <sys/shm.h>11#include <sys/sem.h>12#include <sys/wait.h>13+#include <sys/time.h>14+#include <limits.h>15+#include <stdlib.h>16+#include <strings.h>17#include "sem.h"1819#ifndef lint20@@ -127,7 +132,6 @@21#endif2223#ifndef __alpha24-extern char *shmat();25#endif /* __alpha */2627/* General macros */28@@ -252,6 +256,8 @@29/* Number of K output */30unsigned long outk = 0;3132+struct timeval starttime;33+34int35main( argc, argv )36int argc;37@@ -263,6 +269,8 @@3839buffer_allocate();4041+ gettimeofday(&starttime, NULL);42+43start_reader_and_writer();4445byee( 0 );46@@ -384,8 +392,8 @@47fprintf( stderr, "Usage: %s [-B] [-t] [-S size] [-m memsize] [-b blocks] [-p percent] [-s blocksize] [-u pause] [-i infile] [-o outfile] [-z size]\n",48progname );49fprintf( stderr, "-B = blocked device - pad out last block\n" );50- fprintf( stderr, "-t = show total amount writen at end\n" );51- fprintf( stderr, "-S size = show amount writen every size bytes\n" );52+ fprintf( stderr, "-t = show total amount written at end\n" );53+ fprintf( stderr, "-S size = show amount written every size bytes\n" );54fprintf( stderr, "-m size = size of shared mem chunk to grab\n" );55fprintf( stderr, "-b num = number of blocks in queue\n" );56fprintf( stderr, "-p percent = don't start writing until percent blocks filled\n" );57@@ -398,6 +406,11 @@58}59}6061+ if (argc > optind) {62+ fprintf( stderr, "too many arguments\n" );63+ byee( -1 );64+ }65+66if (zflag) showevery = blocksize;6768/* If -b was not given try and work out the max buffer size */69@@ -507,9 +520,9 @@70get_buffer();7172if( debug )73- fprintf( stderr, "%s pbuffer is 0x%08x, buffer_size is %d [%d x %d]\n",74+ fprintf( stderr, "%s pbuffer is 0x%08lx, buffer_size is %d [%d x %d]\n",75proc_string,76- (char *)pbuffer, buffer_size, blocks, blocksize );77+ (unsigned long)pbuffer, buffer_size, blocks, blocksize );7879#ifdef SYS580memset( (char *)pbuffer, '\0', buffer_size );81@@ -526,9 +539,11 @@82lock( pbuffer->semid, pbuffer->blocks_used_lock );8384pbuffer->blocks_free_lock = 1;85- /* start this off so lock() can be called on it for each block86- * till all the blocks are used up */87- sem_set( pbuffer->semid, pbuffer->blocks_free_lock, blocks - 1 );88+ /* Initializing the semaphore to "blocks - 1" causes a hang when using option89+ * "-p 100" because it always keeps one block free, so we'll never reach 100% fill90+ * level. However, there doesn't seem to be a good reason to keep one block free,91+ * so we initialize the semaphore to "blocks" instead. */92+ sem_set( pbuffer->semid, pbuffer->blocks_free_lock, blocks );9394/* Detattach the shared memory so the fork doesnt do anything odd */95shmdt( (char *)pbuffer );96@@ -648,7 +663,7 @@97int98fill_block()99{100- int bytes;101+ int bytes = 0;102char *start;103int toread;104static char eof_reached = 0;105@@ -707,7 +722,7 @@106{107int filled = 0;108int maxfilled = (blocks * percent) / 100;109- int first_block;110+ int first_block = 0;111112if( debug )113fprintf( stderr, "\tW: Entering writer\n blocks = %d\n maxfilled = %d\n",114@@ -914,13 +929,12 @@115do_size( arg )116char *arg;117{118- char format[ 20 ];119- int ret;120+ int ret = 0;121122- *format = '\0';123- sscanf( arg, "%d%s", &ret, format );124+ char unit = '\0';125+ sscanf( arg, "%d%c", &ret, &unit );126127- switch( *format ){128+ switch( unit ){129case 'm':130case 'M':131ret = ret K K;132@@ -941,7 +955,36 @@133void134pr_out()135{136- fprintf( stderr, " %10luK\r", outk );137+ struct timeval now;138+ unsigned long ms_delta, k_per_s;139+140+ gettimeofday(&now, NULL);141+ ms_delta = (now.tv_sec - starttime.tv_sec) * 1000142+ + (now.tv_usec - starttime.tv_usec) / 1000;143+ if (ms_delta) {144+ /* Use increased accuracy for small amounts of data,145+ * decreased accuracy for *huge* throughputs > 4.1GB/s146+ * to avoid division by 0. This will overflow if your147+ * machine's throughput exceeds 4TB/s - you deserve to148+ * loose if you're still using 32 bit longs on such a149+ * beast ;-)150+ * <[email protected]>151+ */152+ if (outk < ULONG_MAX / 1000) {153+ k_per_s = (outk * 1000) / ms_delta;154+ } else if (ms_delta >= 1000) {155+ k_per_s = outk / (ms_delta / 1000);156+ } else {157+ k_per_s = (outk / ms_delta) * 1000;158+ }159+ fprintf( stderr, " %10luK, %10luK/s\r", outk, k_per_s );160+ } else {161+ if (outk) {162+ fprintf( stderr, " %10luK, ?K/s\r", outk );163+ } else {164+ fprintf( stderr, " 0K, 0K/s\r");165+ }166+ }167}168169#ifdef SYS5170171172