|
Lines 109-114
Link Here
|
| 109 |
* Initial revision |
109 |
* Initial revision |
| 110 |
* |
110 |
* |
| 111 |
*/ |
111 |
*/ |
|
|
112 |
#include <stdlib.h> |
| 113 |
#include <string.h> |
| 114 |
#include <limits.h> |
| 112 |
#include <unistd.h> |
115 |
#include <unistd.h> |
| 113 |
#include <stdio.h> |
116 |
#include <stdio.h> |
| 114 |
#include <signal.h> |
117 |
#include <signal.h> |
|
Lines 120-134
Link Here
|
| 120 |
#include <sys/shm.h> |
123 |
#include <sys/shm.h> |
| 121 |
#include <sys/sem.h> |
124 |
#include <sys/sem.h> |
| 122 |
#include <sys/wait.h> |
125 |
#include <sys/wait.h> |
|
|
126 |
#include <sys/time.h> |
| 123 |
#include "sem.h" |
127 |
#include "sem.h" |
| 124 |
|
128 |
|
| 125 |
#ifndef lint |
129 |
#ifndef lint |
| 126 |
static char *rcsid = "$Header: /a/swan/home/swan/staff/csg/lmjm/src/buffer/RCS/buffer.c,v 1.19 1995/08/24 17:46:28 lmjm Exp lmjm $"; |
130 |
static char *rcsid = "$Header: /a/swan/home/swan/staff/csg/lmjm/src/buffer/RCS/buffer.c,v 1.19 1995/08/24 17:46:28 lmjm Exp lmjm $"; |
| 127 |
#endif |
131 |
#endif |
| 128 |
|
132 |
|
| 129 |
#ifndef __alpha |
133 |
#ifndef __linux__ |
| 130 |
extern char *shmat(); |
134 |
extern char *shmat(); |
| 131 |
#endif /* __alpha */ |
135 |
#endif /* __linux__ */ |
| 132 |
|
136 |
|
| 133 |
/* General macros */ |
137 |
/* General macros */ |
| 134 |
#define TRUE 1 |
138 |
#define TRUE 1 |
|
Lines 136-141
Link Here
|
| 136 |
#define K *1024 |
140 |
#define K *1024 |
| 137 |
#define M *1024*1024 |
141 |
#define M *1024*1024 |
| 138 |
|
142 |
|
|
|
143 |
#if defined __GNUC__ || __STDC_VERSION__ >= 199901L |
| 144 |
#define NUM_K_TYPE unsigned long long |
| 145 |
#define NUM_K_FMT "llu" |
| 146 |
#else |
| 147 |
#define NUM_K_TYPE unsigned long |
| 148 |
#define NUM_K_FMT "lu" |
| 149 |
#endif |
| 150 |
|
| 139 |
/* Some forward declarations */ |
151 |
/* Some forward declarations */ |
| 140 |
void byee(); |
152 |
void byee(); |
| 141 |
void start_reader_and_writer(); |
153 |
void start_reader_and_writer(); |
|
Lines 250-256
Link Here
|
| 250 |
|
262 |
|
| 251 |
char print_total = 0; |
263 |
char print_total = 0; |
| 252 |
/* Number of K output */ |
264 |
/* Number of K output */ |
| 253 |
unsigned long outk = 0; |
265 |
NUM_K_TYPE outk = 0; |
|
|
266 |
|
| 267 |
struct timeval starttime; |
| 254 |
|
268 |
|
| 255 |
int |
269 |
int |
| 256 |
main( argc, argv ) |
270 |
main( argc, argv ) |
|
Lines 262-267
Link Here
|
| 262 |
set_handlers(); |
276 |
set_handlers(); |
| 263 |
|
277 |
|
| 264 |
buffer_allocate(); |
278 |
buffer_allocate(); |
|
|
279 |
|
| 280 |
gettimeofday(&starttime, NULL); |
| 265 |
|
281 |
|
| 266 |
start_reader_and_writer(); |
282 |
start_reader_and_writer(); |
| 267 |
|
283 |
|
|
Lines 384-391
Link Here
|
| 384 |
fprintf( stderr, "Usage: %s [-B] [-t] [-S size] [-m memsize] [-b blocks] [-p percent] [-s blocksize] [-u pause] [-i infile] [-o outfile] [-z size]\n", |
400 |
fprintf( stderr, "Usage: %s [-B] [-t] [-S size] [-m memsize] [-b blocks] [-p percent] [-s blocksize] [-u pause] [-i infile] [-o outfile] [-z size]\n", |
| 385 |
progname ); |
401 |
progname ); |
| 386 |
fprintf( stderr, "-B = blocked device - pad out last block\n" ); |
402 |
fprintf( stderr, "-B = blocked device - pad out last block\n" ); |
| 387 |
fprintf( stderr, "-t = show total amount writen at end\n" ); |
403 |
fprintf( stderr, "-t = show total amount written at end\n" ); |
| 388 |
fprintf( stderr, "-S size = show amount writen every size bytes\n" ); |
404 |
fprintf( stderr, "-S size = show amount written every size bytes\n" ); |
| 389 |
fprintf( stderr, "-m size = size of shared mem chunk to grab\n" ); |
405 |
fprintf( stderr, "-m size = size of shared mem chunk to grab\n" ); |
| 390 |
fprintf( stderr, "-b num = number of blocks in queue\n" ); |
406 |
fprintf( stderr, "-b num = number of blocks in queue\n" ); |
| 391 |
fprintf( stderr, "-p percent = don't start writing until percent blocks filled\n" ); |
407 |
fprintf( stderr, "-p percent = don't start writing until percent blocks filled\n" ); |
|
Lines 397-402
Link Here
|
| 397 |
byee( -1 ); |
413 |
byee( -1 ); |
| 398 |
} |
414 |
} |
| 399 |
} |
415 |
} |
|
|
416 |
|
| 417 |
if (argc > optind) { |
| 418 |
fprintf( stderr, "too many arguments\n" ); |
| 419 |
byee( -1 ); |
| 420 |
} |
| 400 |
|
421 |
|
| 401 |
if (zflag) showevery = blocksize; |
422 |
if (zflag) showevery = blocksize; |
| 402 |
|
423 |
|
|
Lines 507-515
Link Here
|
| 507 |
get_buffer(); |
528 |
get_buffer(); |
| 508 |
|
529 |
|
| 509 |
if( debug ) |
530 |
if( debug ) |
| 510 |
fprintf( stderr, "%s pbuffer is 0x%08x, buffer_size is %d [%d x %d]\n", |
531 |
fprintf( stderr, "%s pbuffer is 0x%08lx, buffer_size is %d [%d x %d]\n", |
| 511 |
proc_string, |
532 |
proc_string, |
| 512 |
(char *)pbuffer, buffer_size, blocks, blocksize ); |
533 |
(unsigned long)pbuffer, buffer_size, blocks, blocksize ); |
| 513 |
|
534 |
|
| 514 |
#ifdef SYS5 |
535 |
#ifdef SYS5 |
| 515 |
memset( (char *)pbuffer, '\0', buffer_size ); |
536 |
memset( (char *)pbuffer, '\0', buffer_size ); |
|
Lines 528-534
Link Here
|
| 528 |
pbuffer->blocks_free_lock = 1; |
549 |
pbuffer->blocks_free_lock = 1; |
| 529 |
/* start this off so lock() can be called on it for each block |
550 |
/* start this off so lock() can be called on it for each block |
| 530 |
* till all the blocks are used up */ |
551 |
* till all the blocks are used up */ |
|
|
552 |
/* Initializing the semaphore to "blocks - 1" causes a hang when using option |
| 553 |
* "-p 100" because it always keeps one block free, so we'll never reach 100% fill |
| 554 |
* level. However, there doesn't seem to be a good reason to keep one block free, |
| 555 |
* so we initialize the semaphore to "blocks" instead. |
| 556 |
* <mbuck@debian.org> 2004-01-11 |
| 557 |
*/ |
| 558 |
#if 0 |
| 531 |
sem_set( pbuffer->semid, pbuffer->blocks_free_lock, blocks - 1 ); |
559 |
sem_set( pbuffer->semid, pbuffer->blocks_free_lock, blocks - 1 ); |
|
|
560 |
#else |
| 561 |
sem_set( pbuffer->semid, pbuffer->blocks_free_lock, blocks ); |
| 562 |
#endif |
| 532 |
|
563 |
|
| 533 |
/* Detattach the shared memory so the fork doesnt do anything odd */ |
564 |
/* Detattach the shared memory so the fork doesnt do anything odd */ |
| 534 |
shmdt( (char *)pbuffer ); |
565 |
shmdt( (char *)pbuffer ); |
|
Lines 648-654
Link Here
|
| 648 |
int |
679 |
int |
| 649 |
fill_block() |
680 |
fill_block() |
| 650 |
{ |
681 |
{ |
| 651 |
int bytes; |
682 |
int bytes = 0; |
| 652 |
char *start; |
683 |
char *start; |
| 653 |
int toread; |
684 |
int toread; |
| 654 |
static char eof_reached = 0; |
685 |
static char eof_reached = 0; |
|
Lines 707-713
Link Here
|
| 707 |
{ |
738 |
{ |
| 708 |
int filled = 0; |
739 |
int filled = 0; |
| 709 |
int maxfilled = (blocks * percent) / 100; |
740 |
int maxfilled = (blocks * percent) / 100; |
| 710 |
int first_block; |
741 |
int first_block = 0; |
| 711 |
|
742 |
|
| 712 |
if( debug ) |
743 |
if( debug ) |
| 713 |
fprintf( stderr, "\tW: Entering writer\n blocks = %d\n maxfilled = %d\n", |
744 |
fprintf( stderr, "\tW: Entering writer\n blocks = %d\n maxfilled = %d\n", |
|
Lines 742-748
Link Here
|
| 742 |
} |
773 |
} |
| 743 |
|
774 |
|
| 744 |
if( print_total ){ |
775 |
if( print_total ){ |
| 745 |
fprintf( stderr, "Kilobytes Out %lu\n", outk ); |
776 |
fprintf( stderr, "Kilobytes Out %" NUM_K_FMT "\n", outk ); |
| 746 |
} |
777 |
} |
| 747 |
|
778 |
|
| 748 |
if( debug ) |
779 |
if( debug ) |
|
Lines 783-796
Link Here
|
| 783 |
void |
814 |
void |
| 784 |
write_block_to_stdout() |
815 |
write_block_to_stdout() |
| 785 |
{ |
816 |
{ |
| 786 |
static unsigned long out = 0; |
817 |
unsigned long out = 0; |
| 787 |
static unsigned long last_gb = 0; |
818 |
static unsigned long last_gb = 0; |
| 788 |
static unsigned long next_k = 0; |
819 |
static NUM_K_TYPE next_k = 0; |
| 789 |
int written; |
820 |
int written; |
| 790 |
|
821 |
|
| 791 |
if( next_k == 0 && showevery ){ |
822 |
if( next_k == 0 && showevery ){ |
| 792 |
if( debug > 3 ) |
823 |
if( debug > 3 ) |
| 793 |
fprintf( stderr, "W: next_k = %lu showevery = %d\n", next_k, showevery ); |
824 |
fprintf( stderr, "W: next_k = %" NUM_K_FMT " showevery = %d\n", next_k, showevery ); |
| 794 |
showevery = showevery / 1024; |
825 |
showevery = showevery / 1024; |
| 795 |
next_k = showevery; |
826 |
next_k = showevery; |
| 796 |
} |
827 |
} |
|
Lines 798-804
Link Here
|
| 798 |
if( (written = write( fdout, curr_block->data, curr_block->bytes )) != curr_block->bytes ){ |
829 |
if( (written = write( fdout, curr_block->data, curr_block->bytes )) != curr_block->bytes ){ |
| 799 |
report_proc(); |
830 |
report_proc(); |
| 800 |
perror( "write of data failed" ); |
831 |
perror( "write of data failed" ); |
| 801 |
fprintf( stderr, "bytes to write=%d, bytes written=%d, total written %10luK\n", curr_block->bytes, written, outk ); |
832 |
fprintf( stderr, "bytes to write=%d, bytes written=%d, total written %10" NUM_K_FMT "K\n", curr_block->bytes, written, outk ); |
| 802 |
byee( -1 ); |
833 |
byee( -1 ); |
| 803 |
} |
834 |
} |
| 804 |
|
835 |
|
|
Lines 825-831
Link Here
|
| 825 |
} |
856 |
} |
| 826 |
if( showevery ){ |
857 |
if( showevery ){ |
| 827 |
if( debug > 3 ) |
858 |
if( debug > 3 ) |
| 828 |
fprintf( stderr, "W: outk = %lu, next_k = %lu\n", |
859 |
fprintf( stderr, "W: outk = %" NUM_K_FMT ", next_k = %" NUM_K_FMT "\n", |
| 829 |
outk, next_k ); |
860 |
outk, next_k ); |
| 830 |
if( outk >= next_k ){ |
861 |
if( outk >= next_k ){ |
| 831 |
pr_out(); |
862 |
pr_out(); |
|
Lines 914-926
Link Here
|
| 914 |
do_size( arg ) |
945 |
do_size( arg ) |
| 915 |
char *arg; |
946 |
char *arg; |
| 916 |
{ |
947 |
{ |
| 917 |
char format[ 20 ]; |
948 |
int ret = 0; |
| 918 |
int ret; |
|
|
| 919 |
|
949 |
|
| 920 |
*format = '\0'; |
950 |
char unit = '\0'; |
| 921 |
sscanf( arg, "%d%s", &ret, format ); |
951 |
sscanf( arg, "%d%c", &ret, &unit ); |
| 922 |
|
952 |
|
| 923 |
switch( *format ){ |
953 |
switch( unit ){ |
| 924 |
case 'm': |
954 |
case 'm': |
| 925 |
case 'M': |
955 |
case 'M': |
| 926 |
ret = ret K K; |
956 |
ret = ret K K; |
|
Lines 941-947
Link Here
|
| 941 |
void |
971 |
void |
| 942 |
pr_out() |
972 |
pr_out() |
| 943 |
{ |
973 |
{ |
| 944 |
fprintf( stderr, " %10luK\r", outk ); |
974 |
struct timeval now; |
|
|
975 |
unsigned long ms_delta, k_per_s; |
| 976 |
|
| 977 |
gettimeofday(&now, NULL); |
| 978 |
ms_delta = (now.tv_sec - starttime.tv_sec) * 1000 |
| 979 |
+ (now.tv_usec - starttime.tv_usec) / 1000; |
| 980 |
if (ms_delta) { |
| 981 |
/* Use increased accuracy for small amounts of data, |
| 982 |
* decreased accuracy for *huge* throughputs > 4.1GB/s |
| 983 |
* to avoid division by 0. This will overflow if your |
| 984 |
* machine's throughput exceeds 4TB/s - you deserve to |
| 985 |
* loose if you're still using 32 bit longs on such a |
| 986 |
* beast ;-) |
| 987 |
* <mbuck@debian.org> |
| 988 |
*/ |
| 989 |
if (outk < ULONG_MAX / 1000) { |
| 990 |
k_per_s = (outk * 1000) / ms_delta; |
| 991 |
} else if (ms_delta >= 1000) { |
| 992 |
k_per_s = outk / (ms_delta / 1000); |
| 993 |
} else { |
| 994 |
k_per_s = (outk / ms_delta) * 1000; |
| 995 |
} |
| 996 |
fprintf( stderr, " %10" NUM_K_FMT "K, %10luK/s\r", outk, k_per_s ); |
| 997 |
} else { |
| 998 |
if (outk) { |
| 999 |
fprintf( stderr, " %10" NUM_K_FMT "K, ?K/s\r", outk ); |
| 1000 |
} else { |
| 1001 |
fprintf( stderr, " 0K, 0K/s\r"); |
| 1002 |
} |
| 1003 |
} |
| 945 |
} |
1004 |
} |
| 946 |
|
1005 |
|
| 947 |
#ifdef SYS5 |
1006 |
#ifdef SYS5 |