diff options
Diffstat (limited to '')
-rw-r--r-- | main.cc | 475 |
1 files changed, 176 insertions, 299 deletions
@@ -1,6 +1,6 @@ /* Plzip - A parallel version of the lzip data compressor Copyright (C) 2009 Laszlo Ersek. - Copyright (C) 2009 Antonio Diaz Diaz. + Copyright (C) 2009, 2010 Antonio Diaz Diaz. 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 @@ -29,14 +29,14 @@ #include <cerrno> #include <climits> #include <csignal> -#include <cstdarg> /* va_list */ +#include <cstdarg> #include <cstddef> -#include <cstdio> /* flockfile() */ +#include <cstdio> #include <cstdlib> -#include <cstring> /* strerror() */ +#include <cstring> #include <string> #include <vector> -#include <fcntl.h> /* open() */ +#include <fcntl.h> #include <stdint.h> #include <pthread.h> #include <unistd.h> @@ -63,8 +63,6 @@ #endif void internal_error( const char * msg ); -int readblock( const int fd, char * buf, const int size ) throw(); -int writeblock( const int fd, const char * buf, const int size ) throw(); namespace { @@ -72,7 +70,7 @@ namespace { const char * invocation_name = 0; const char * const Program_name = "Plzip"; const char * const program_name = "plzip"; -const char * const program_year = "2009"; +const char * const program_year = "2010"; struct { const char * from; const char * to; } const known_extensions[] = { { ".lz", "" }, @@ -89,7 +87,6 @@ enum Mode { m_compress = 0, m_decompress, m_test }; std::string output_filename; int outhandle = -1; -int verbosity = 0; bool delete_output_on_interrupt = false; class Pretty_print @@ -137,13 +134,13 @@ void show_help() throw() // std::printf( " -b, --member-size=<n> set member size limit in bytes\n" ); std::printf( " -c, --stdout send output to standard output\n" ); std::printf( " -d, --decompress decompress\n" ); -// std::printf( " -f, --force overwrite existing output files\n" ); -// std::printf( " -k, --keep keep (don't delete) input files\n" ); -// std::printf( " -m, --match-length=<n> set match length limit in bytes [80]\n" ); + std::printf( " -f, --force overwrite existing output files\n" ); + std::printf( " -k, --keep keep (don't delete) input files\n" ); + std::printf( " -m, --match-length=<n> set match length limit in bytes [80]\n" ); std::printf( " -n, --threads=<n> set the number of (de)compression threads\n" ); -// std::printf( " -o, --output=<file> if reading stdin, place the output into <file>\n" ); + std::printf( " -o, --output=<file> if reading stdin, place the output into <file>\n" ); std::printf( " -q, --quiet suppress all messages\n" ); -// std::printf( " -s, --dictionary-size=<n> set dictionary size limit in bytes [8MiB]\n" ); + std::printf( " -s, --dictionary-size=<n> set dictionary size limit in bytes [8MiB]\n" ); // std::printf( " -S, --volume-size=<n> set volume size limit in bytes\n" ); std::printf( " -t, --test test compressed file integrity\n" ); std::printf( " -v, --verbose be verbose (a 2nd -v gives more)\n" ); @@ -159,7 +156,7 @@ void show_help() throw() std::printf( "Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,\n" ); std::printf( "Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...\n" ); std::printf( "\nReport bugs to lzip-bug@nongnu.org\n" ); - std::printf( "Lzip home page: http://www.nongnu.org/lzip/lzip.html\n" ); + std::printf( "Plzip home page: http://www.nongnu.org/lzip/plzip.html\n" ); } @@ -209,7 +206,7 @@ long long getnum( const char * ptr, const int bs = 0, break; case 'k': if( factor == 1000 ) exponent = 1; else bad_multiplier = true; break; - default: bad_multiplier = true; + default : bad_multiplier = true; } if( bad_multiplier ) { @@ -236,9 +233,10 @@ int get_dict_size( const char * arg ) throw() { char *tail; int bits = std::strtol( arg, &tail, 0 ); - if( bits >= min_dictionary_bits && bits <= max_dictionary_bits && *tail == 0 ) + if( bits >= LZ_min_dictionary_bits() && + bits <= LZ_max_dictionary_bits() && *tail == 0 ) return ( 1 << bits ); - return getnum( arg, 0, min_dictionary_size, max_dictionary_size ); + return getnum( arg, 0, LZ_min_dictionary_size(), LZ_max_dictionary_size() ); } @@ -380,75 +378,59 @@ void cleanup_and_fail( const int retval ) throw() // Set permissions, owner and times. -void close_and_set_permissions( const struct stat * in_statsp, int * retvalp ) +void close_and_set_permissions( const struct stat * const in_statsp ) { - int tmp = 0; + bool error = false; if( in_statsp ) { - if( fchmod( outhandle, in_statsp->st_mode ) != 0 ) tmp = 1; - if( !tmp ) (void)fchown( outhandle, in_statsp->st_uid, in_statsp->st_gid ); + if( fchmod( outhandle, in_statsp->st_mode ) != 0 ) error = true; + else (void)fchown( outhandle, in_statsp->st_uid, in_statsp->st_gid ); // fchown will in many cases return with EPERM, which can be safely ignored. } if( close( outhandle ) == 0 ) outhandle = -1; else cleanup_and_fail( 1 ); delete_output_on_interrupt = false; if( !in_statsp ) return; - if( !tmp ) + if( !error ) { struct utimbuf t; t.actime = in_statsp->st_atime; t.modtime = in_statsp->st_mtime; - if( utime( output_filename.c_str(), &t ) != 0 ) tmp = 1; + if( utime( output_filename.c_str(), &t ) != 0 ) error = true; } - if( tmp ) + if( error ) { - if( tmp > *retvalp ) *retvalp = tmp; show_error( "I can't change output file attributes." ); - cleanup_and_fail( *retvalp ); + cleanup_and_fail( 1 ); } } -int decompress( const int inhandle, const Pretty_print & pp, - const bool testing ) +int do_decompress( LZ_Decoder * const decoder, const int inhandle, + const Pretty_print & pp, const bool testing ) { - void * decoder = LZ_decompress_open(); - if( !decoder || LZ_decompress_errno( decoder ) != LZ_ok ) - { - LZ_decompress_close( decoder ); - pp( "not enough memory. Find a machine with more memory" ); - return 1; - } - if( verbosity >= 1 ) pp(); - const int in_buffer_size = 65536, out_buffer_size = 8 * in_buffer_size; uint8_t in_buffer[in_buffer_size], out_buffer[out_buffer_size]; - int in_pos = 0, in_stream_pos = 0; - bool finished = false; + + if( verbosity >= 1 ) pp(); while( true ) { - int in_size = 0; - if( !finished ) + int in_size = std::min( LZ_decompress_write_size( decoder ), in_buffer_size ); + if( in_size > 0 ) { - if( in_stream_pos == 0 ) - in_stream_pos = readblock( inhandle, (char *)in_buffer, in_buffer_size ); - if( in_pos < in_stream_pos ) - { - in_size = LZ_decompress_write( decoder, in_buffer + in_pos, in_stream_pos - in_pos ); - in_pos += in_size; - } - if( in_pos >= in_stream_pos ) - { - if( in_stream_pos < in_buffer_size ) - { finished = true; LZ_decompress_finish( decoder ); } - in_stream_pos = 0; in_pos = 0; - } + const int max_in_size = in_size; + in_size = readblock( inhandle, (char *)in_buffer, max_in_size ); + if( in_size != max_in_size && errno ) + { pp(); show_error( "read error", errno ); return 1; } + if( in_size == 0 ) LZ_decompress_finish( decoder ); + else if( in_size != LZ_decompress_write( decoder, in_buffer, in_size ) ) + internal_error( "library error (LZ_decompress_write)" ); } int out_size = LZ_decompress_read( decoder, out_buffer, out_buffer_size ); // std::fprintf( stderr, "%5d in_size, %6d out_size.\n", in_size, out_size ); if( out_size < 0 ) { - const LZ_errno lz_errno = LZ_decompress_errno( decoder ); + const LZ_Errno lz_errno = LZ_decompress_errno( decoder ); if( lz_errno == LZ_header_error ) { if( LZ_decompress_total_out_size( decoder ) > 0 ) @@ -461,15 +443,18 @@ int decompress( const int inhandle, const Pretty_print & pp, pp( "not enough memory. Find a machine with more memory" ); return 1; } + pp(); if( lz_errno == LZ_unexpected_eof ) { if( verbosity >= 0 ) - { pp(); - std::fprintf( stderr, "file ends unexpectedly at pos %lld\n", - LZ_decompress_total_in_size( decoder ) ); } + std::fprintf( stderr, "file ends unexpectedly at pos %lld\n", + LZ_decompress_total_in_size( decoder ) ); return 2; } - pp(); show_error( "read error", errno ); return 1; + if( verbosity >= 0 ) + std::fprintf( stderr, "LZ_decompress_read error: %s.\n", + LZ_strerror( LZ_decompress_errno( decoder ) ) ); + return 1; } else if( out_size > 0 && outhandle >= 0 ) { @@ -478,17 +463,33 @@ int decompress( const int inhandle, const Pretty_print & pp, { pp(); show_error( "write error", errno ); return 1; } } if( LZ_decompress_finished( decoder ) == 1 ) break; - if( finished && in_size == 0 && out_size == 0 ) + if( in_size == 0 && out_size == 0 ) internal_error( "library error (LZ_decompress_read)" ); } if( verbosity >= 1 ) { if( testing ) std::fprintf( stderr, "ok\n" ); else std::fprintf( stderr, "done\n" ); } - LZ_decompress_close( decoder ); return 0; } +int decompress( const int inhandle, const Pretty_print & pp, + const bool testing ) + { + LZ_Decoder * const decoder = LZ_decompress_open(); + int retval; + + if( !decoder || LZ_decompress_errno( decoder ) != LZ_ok ) + { + pp( "not enough memory" ); + retval = 1; + } + else retval = do_decompress( decoder, inhandle, pp, testing ); + LZ_decompress_close( decoder ); + return retval; + } + + extern "C" void signal_handler( int ) throw() { show_error( "Control-C or similar caught, quitting." ); @@ -506,6 +507,9 @@ void set_signals() throw() } // end namespace +int verbosity = 0; + + void Pretty_print::operator()( const char * const msg ) const throw() { if( verbosity >= 0 ) @@ -523,6 +527,30 @@ void Pretty_print::operator()( const char * const msg ) const throw() } +void show_error( const char * msg, const int errcode, const bool help ) throw() + { + if( verbosity >= 0 ) + { + if( msg && msg[0] != 0 ) + { + std::fprintf( stderr, "%s: %s", program_name, msg ); + if( errcode > 0 ) std::fprintf( stderr, ": %s", std::strerror( errcode ) ); + std::fprintf( stderr, "\n" ); + } + if( help && invocation_name && invocation_name[0] != 0 ) + std::fprintf( stderr, "Try `%s --help' for more information.\n", invocation_name ); + } + } + + +void internal_error( const char * msg ) + { + std::string s( "internal error: " ); s += msg; + show_error( s.c_str() ); + std::exit( 3 ); + } + + /* Private stuff needed by fatal(). */ static pthread_t main_thread; @@ -530,25 +558,21 @@ static pid_t pid; /* Public utility variables and functions. */ -void *(*mallocf)(size_t size); -void (*freef)(void *ptr); - /* This can be called from any thread, main thread or sub-threads alike, since they all call common helper functions that call fatal() in case of an error. */ -void -fatal(void) +void fatal() { if( pthread_equal(pthread_self(), main_thread) ) cleanup_and_fail( 1 ); else { - if (0 == kill(pid, SIGUSR1)) + if( 0 == kill(pid, SIGUSR1) ) pthread_exit(0); } - _exit(EXIT_FAILURE); + _exit( 1 ); } @@ -572,67 +596,51 @@ fail(const char *fmt, int err, ...) } -void * -xalloc(size_t size) -{ - void *ret = (*mallocf)(size); - - if (0 == ret) { - fail("(*mallocf)()", errno); - } - - return ret; -} - - void xinit(Cond *cond) { - int ret; pthread_mutexattr_t attr; - ret = pthread_mutexattr_init(&attr); - if (0 != ret) { + int ret = pthread_mutexattr_init(&attr); + if( ret != 0 ) { fail("pthread_mutexattr_init()", ret); } ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); - if (0 != ret) { + if( ret != 0 ) { fail("pthread_mutexattr_settype()", ret); } ret = pthread_mutex_init(&cond->lock, &attr); - if (0 != ret) { + if( ret != 0 ) { fail("pthread_mutex_init()", ret); } ret = pthread_mutexattr_destroy(&attr); - if (0 != ret) { + if( ret != 0 ) { fail("pthread_mutexattr_destroy()", ret); } ret = pthread_cond_init(&cond->cond, 0); - if (0 != ret) { + if( ret != 0 ) { fail("pthread_cond_init()", ret); } - cond->ccount = 0lu; - cond->wcount = 0lu; + cond->ccount = 0; + cond->wcount = 0; } void xdestroy(Cond *cond) { - int ret; - - ret = pthread_cond_destroy(&cond->cond); - if (0 != ret) { + int ret = pthread_cond_destroy(&cond->cond); + if( ret != 0 ) { fail("pthread_cond_destroy()", ret); } ret = pthread_mutex_destroy(&cond->lock); - if (0 != ret) { + if( ret != 0 ) { fail("pthread_mutex_destroy()", ret); } } @@ -641,10 +649,8 @@ xdestroy(Cond *cond) void xlock(Cond *cond) { - int ret; - - ret = pthread_mutex_lock(&cond->lock); - if (0 != ret) { + int ret = pthread_mutex_lock(&cond->lock); + if( ret != 0 ) { fail("pthread_mutex_lock()", ret); } } @@ -661,10 +667,8 @@ xlock_pred(Cond *cond) void xunlock(Cond *cond) { - int ret; - - ret = pthread_mutex_unlock(&cond->lock); - if (0 != ret) { + int ret = pthread_mutex_unlock(&cond->lock); + if( ret != 0 ) { fail("pthread_mutex_unlock()", ret); } } @@ -673,11 +677,9 @@ xunlock(Cond *cond) void xwait(Cond *cond) { - int ret; - ++cond->wcount; - ret = pthread_cond_wait(&cond->cond, &cond->lock); - if (0 != ret) { + int ret = pthread_cond_wait(&cond->cond, &cond->lock); + if( ret != 0 ) { fail("pthread_cond_wait()", ret); } ++cond->ccount; @@ -687,10 +689,8 @@ xwait(Cond *cond) void xsignal(Cond *cond) { - int ret; - - ret = pthread_cond_signal(&cond->cond); - if (0 != ret) { + int ret = pthread_cond_signal(&cond->cond); + if( ret != 0 ) { fail("pthread_cond_signal()", ret); } } @@ -699,10 +699,8 @@ xsignal(Cond *cond) void xbroadcast(Cond *cond) { - int ret; - - ret = pthread_cond_broadcast(&cond->cond); - if (0 != ret) { + int ret = pthread_cond_broadcast(&cond->cond); + if( ret != 0 ) { fail("pthread_cond_broadcast()", ret); } } @@ -711,10 +709,8 @@ xbroadcast(Cond *cond) void xcreate(pthread_t *thread, void *(*routine)(void *), void *arg) { - int ret; - - ret = pthread_create(thread, 0, routine, arg); - if (0 != ret) { + int ret = pthread_create(thread, 0, routine, arg); + if( ret != 0 ) { fail("pthread_create()", ret); } } @@ -723,10 +719,8 @@ xcreate(pthread_t *thread, void *(*routine)(void *), void *arg) void xjoin(pthread_t thread) { - int ret; - - ret = pthread_join(thread, 0); - if (0 != ret) { + int ret = pthread_join(thread, 0); + if( ret != 0 ) { fail("pthread_join()", ret); } } @@ -735,7 +729,7 @@ xjoin(pthread_t thread) void xraise(int sig) { - if (-1 == kill(pid, sig)) { + if( -1 == kill(pid, sig) ) { fail("kill()", errno); } } @@ -743,59 +737,11 @@ xraise(int sig) /* Private stuff part 2. */ -struct Opts -{ - unsigned num_worker; /* Start this many worker threads. */ - unsigned clidx; /* Compression level index in [0u .. 8u]. */ - int print_cctrs; /* Print condition variable counters. */ -}; - -/* Backlog factor for all workers together. */ -static const unsigned blf = 3u; - -/* Separator characters in environment variable values. No escaping. */ -static const char envsep[] = " \t"; - - -static void * -trace_malloc(size_t size) -{ - void *ret; - int save_errno = 0; - - ret = malloc(size); - if (0 == ret) { - save_errno = errno; - } - - if (0 > fprintf(stderr, "%lu: malloc(%lu) == %p\n", (long unsigned)pid, - (long unsigned)size, ret) - ) { - fatal(); - } - - if (0 == ret) { - errno = save_errno; - } - - return ret; -} - - -static void -trace_free(void *ptr) -{ - if (0 > fprintf(stderr, "%lu: free(%p)\n", (long unsigned)pid, ptr)) { - fatal(); - } - free(ptr); -} - static void xsigemptyset(sigset_t *set) { - if (-1 == sigemptyset(set)) { + if( -1 == sigemptyset(set) ) { fail("sigemptyset()", errno); } } @@ -804,7 +750,7 @@ xsigemptyset(sigset_t *set) static void xsigaddset(sigset_t *set, int signo) { - if (-1 == sigaddset(set, signo)) { + if( -1 == sigaddset(set, signo) ) { fail("sigaddset()", errno); } } @@ -813,10 +759,8 @@ xsigaddset(sigset_t *set, int signo) static void xsigmask(int how, const sigset_t *set, sigset_t *oset) { - int ret; - - ret = pthread_sigmask(how, set, oset); - if (0 != ret) { + int ret = pthread_sigmask(how, set, oset); + if( ret != 0 ) { fail("pthread_sigmask()", ret); } } @@ -831,54 +775,35 @@ xsigaction(int sig, void (*handler)(int)) xsigemptyset(&act.sa_mask); act.sa_flags = 0; - if (-1 == sigaction(sig, &act, 0)) { + if( -1 == sigaction(sig, &act, 0) ) { fail("sigaction()", errno); } } -enum caught_sig -{ - CS_INT = 1, - CS_TERM, - CS_USR1, - CS_USR2 -}; +enum Caught_sig { CS_INT = 1, CS_TERM, CS_USR1, CS_USR2 }; static volatile sig_atomic_t caught_sig; -static void -sighandler(int sig) -{ +extern "C" void sighandler( int sig ) + { /* sig_atomic_t is nowhere required to be able to hold signal values. */ - switch (sig) { - case SIGINT: - caught_sig = CS_INT; - break; - - case SIGTERM: - caught_sig = CS_TERM; - break; - - case SIGUSR1: - caught_sig = CS_USR1; - break; - - case SIGUSR2: - caught_sig = CS_USR2; - break; - - default: - assert(0); + switch( sig ) + { + case SIGINT : caught_sig = CS_INT; break; + case SIGTERM: caught_sig = CS_TERM; break; + case SIGUSR1: caught_sig = CS_USR1; break; + case SIGUSR2: caught_sig = CS_USR2; break; + default: internal_error( "caught signal not in set" ); + } } -} -static void -process( const Opts *opts, unsigned num_slot, - int infd, int outfd, const Pretty_print & pp, const sigset_t *unblocked ) -{ +static void compress( const lzma_options & encoder_options, const int num_workers, + int debug_level, int num_slots, int infd, int outfd, + const Pretty_print & pp, const sigset_t *unblocked ) + { /* We could wait for signals with either sigwait() or sigsuspend(). SUSv2 states about sigwait() that its effect on signal actions is unspecified. @@ -896,18 +821,19 @@ process( const Opts *opts, unsigned num_slot, 13-OCT-2009 lacos */ - Plzip_arg muxer_arg; - pthread_t muxer; - - if( verbosity >= 1 ) pp( "" ); + if( verbosity >= 1 ) pp(); - muxer_arg.num_worker = opts->num_worker; - muxer_arg.num_slot = num_slot; - muxer_arg.clidx = opts->clidx; - muxer_arg.print_cctrs = opts->print_cctrs; + Muxer_arg muxer_arg; + muxer_arg.dictionary_size = encoder_options.dictionary_size; + muxer_arg.match_len_limit = encoder_options.match_len_limit; + muxer_arg.num_workers = num_workers; + muxer_arg.num_slots = num_slots; + muxer_arg.debug_level = debug_level; muxer_arg.infd = infd; muxer_arg.outfd = outfd; - xcreate(&muxer, plzip_wrap, &muxer_arg); + + pthread_t muxer_thread; + xcreate(&muxer_thread, muxer, &muxer_arg); /* Unblock signals, wait for them, then block them again. */ { @@ -915,7 +841,7 @@ process( const Opts *opts, unsigned num_slot, assert(-1 == ret && EINTR == errno); } - switch (caught_sig) { + switch( caught_sig ) { case CS_INT: case CS_TERM: // FIXME remove output file { @@ -951,16 +877,16 @@ process( const Opts *opts, unsigned num_slot, assert(0); } - xjoin(muxer); -} + xjoin(muxer_thread); + } static void sigs_mod(int block_n_catch, sigset_t *oset) -{ + { void (*handler)(int); - if (block_n_catch) { + if( block_n_catch ) { sigset_t mask; xsigemptyset(&mask); @@ -981,33 +907,9 @@ sigs_mod(int block_n_catch, sigset_t *oset) xsigaction(SIGUSR1, handler); xsigaction(SIGUSR2, handler); - if (!block_n_catch) { + if( !block_n_catch ) { xsigmask(SIG_SETMASK, oset, 0); } -} - - -void show_error( const char * msg, const int errcode, const bool help ) throw() - { - if( verbosity >= 0 ) - { - if( msg && msg[0] != 0 ) - { - std::fprintf( stderr, "%s: %s", program_name, msg ); - if( errcode > 0 ) std::fprintf( stderr, ": %s", std::strerror( errcode ) ); - std::fprintf( stderr, "\n" ); - } - if( help && invocation_name && invocation_name[0] != 0 ) - std::fprintf( stderr, "Try `%s --help' for more information.\n", invocation_name ); - } - } - - -void internal_error( const char * msg ) - { - std::string s( "internal error: " ); s += msg; - show_error( s.c_str() ); - std::exit( 3 ); } @@ -1050,7 +952,6 @@ int writeblock( const int fd, const char * buf, const int size ) throw() int main( const int argc, const char * argv[] ) { - Opts opts; // Mapping from gzip/bzip2 style 1..9 compression modes // to the corresponding LZMA compression modes. const lzma_options option_mapping[] = @@ -1065,7 +966,9 @@ int main( const int argc, const char * argv[] ) { 1 << 24, 163 }, // -8 { 1 << 25, 273 } }; // -9 lzma_options encoder_options = option_mapping[5]; // default = "-6" + int debug_level = 0; int inhandle = -1; + int num_workers = 0; // Start this many worker threads Mode program_mode = m_compress; bool force = false; bool keep_input_files = false; @@ -1081,30 +984,15 @@ int main( const int argc, const char * argv[] ) main_thread = pthread_self(); pid = getpid(); - mallocf = malloc; - freef = free; - xsigaction(SIGPIPE, SIG_IGN); xsigaction(SIGXFSZ, SIG_IGN); - /* Effectuate option defaults. */ - long max_worker = sysconf(_SC_THREAD_THREADS_MAX); - if (-1L == max_worker) { - max_worker = LONG_MAX; - } - if (UINT_MAX < (long unsigned)max_worker) { - max_worker = UINT_MAX; - } - if (UINT_MAX / blf < (unsigned)max_worker) { - max_worker = UINT_MAX / blf; - } - if ((size_t)-1 / sizeof(pthread_t) < (unsigned)max_worker) { - max_worker = (size_t)-1 / sizeof(pthread_t); - } - - opts.num_worker = 0u; - opts.clidx = 5u; - opts.print_cctrs = 0; + const int slots_per_worker = 2; + long max_workers = sysconf( _SC_THREAD_THREADS_MAX ); + if( max_workers < 1 || max_workers > INT_MAX / slots_per_worker ) + max_workers = INT_MAX / slots_per_worker; + if( max_workers > INT_MAX / (int)sizeof( pthread_t ) ) + max_workers = INT_MAX / sizeof( pthread_t ); const Arg_parser::Option options[] = { @@ -1150,25 +1038,24 @@ int main( const int argc, const char * argv[] ) case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - opts.clidx = code - '1'; encoder_options = option_mapping[code-'1']; break; + case 'b': break; case 'c': to_stdout = true; break; case 'd': program_mode = m_decompress; break; - case 'D': { int debug_level = getnum( arg, 0, 0, 3 ); - if( debug_level & 1 ) opts.print_cctrs = 1; - if( debug_level & 2 ) - { mallocf = trace_malloc; freef = trace_free; } } + case 'D': debug_level = getnum( arg, 0, 0, 3 ); break; case 'f': force = true; break; case 'h': show_help(); return 0; case 'k': keep_input_files = true; break; case 'm': encoder_options.match_len_limit = - getnum( arg, 0, 5, 273 ); break; + getnum( arg, 0, LZ_min_match_len_limit(), + LZ_max_match_len_limit() ); break; case 'o': default_output_filename = arg; break; - case 'n': opts.num_worker = getnum( arg, 0, 1, max_worker ); break; + case 'n': num_workers = getnum( arg, 0, 1, max_workers ); break; case 'q': verbosity = -1; break; case 's': encoder_options.dictionary_size = get_dict_size( arg ); break; + case 'S': break; case 't': program_mode = m_test; break; case 'v': if( verbosity < 4 ) ++verbosity; break; case 'V': show_version(); return 0; @@ -1176,23 +1063,13 @@ int main( const int argc, const char * argv[] ) } } - if( opts.num_worker <= 0 ) + if( num_workers <= 0 ) { -#ifdef _SC_NPROCESSORS_ONLN long num_online = sysconf( _SC_NPROCESSORS_ONLN ); - if( num_online <= 0 ) - { - show_error( "number of online processors unavailable.", 0, true ); - fatal(); - } - opts.num_worker = std::min( num_online, max_worker ); -#else - show_error( "number of (de)compression threads not set.", 0, true ); - fatal(); -#endif + if( num_online <= 0 ) num_online = 2; + num_workers = std::min( num_online, max_workers ); } - assert(UINT_MAX / blf >= opts.num_worker); - unsigned num_slot = opts.num_worker * blf; + const int num_slots = num_workers * slots_per_worker; bool filenames_given = false; for( ; argind < parser.arguments(); ++argind ) @@ -1265,14 +1142,14 @@ int main( const int argc, const char * argv[] ) if( output_filename.size() && !to_stdout && program_mode != m_test ) delete_output_on_interrupt = true; - const struct stat * in_statsp = input_filename.size() ? &in_stats : 0; + const struct stat * const in_statsp = input_filename.size() ? &in_stats : 0; pp.set_name( input_filename ); int tmp = 0; if( program_mode == m_compress ) { sigset_t unblocked; sigs_mod(1, &unblocked); - process( &opts, num_slot, inhandle, outhandle, pp, &unblocked ); + compress( encoder_options, num_workers, debug_level, num_slots, inhandle, outhandle, pp, &unblocked ); sigs_mod(0, &unblocked); } else @@ -1281,7 +1158,7 @@ int main( const int argc, const char * argv[] ) if( tmp && program_mode != m_test ) cleanup_and_fail( retval ); if( delete_output_on_interrupt ) - close_and_set_permissions( in_statsp, &retval ); + close_and_set_permissions( in_statsp ); if( input_filename.size() ) { close( inhandle ); inhandle = -1; |