From: Paul Eggert Date: Sat, 2 Nov 2024 20:42:02 +0000 (-0700) Subject: Add LG_BLOCKSIZE to omit some *, % ops X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a6cf78b0fa43e7c7ec27275e6ee2d3383f7f922a;p=thirdparty%2Ftar.git Add LG_BLOCKSIZE to omit some *, % ops * src/buffer.c (_flush_write, short_read, seek_archive) (_gnu_flush_write): * src/create.c (write_gnu_long_link, dump_regular_file) (dump_dir0): * src/delete.c (write_recent_bytes, flush_file) (delete_archive_members): * src/list.c (read_header): * src/sparse.c (sparse_dump_region, sparse_extract_region) (pax_dump_header_1): * src/tar.c (parse_opt): * src/update.c (append_file): Prefer shifting and masking to dividing and remaindering by BLOCKSIZE. This reclaims some compiler optimizations lost by our recent preference for signed integers. * src/tar.h (LG_BLOCKSIZE): New constant, for shifting. --- diff --git a/src/buffer.c b/src/buffer.c index 21a89374..8b6028ce 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -890,7 +890,7 @@ _flush_write (void) { idx_t delta = status - map->start * BLOCKSIZE; idx_t diff; - map->nblocks += delta / BLOCKSIZE; + map->nblocks += delta >> LG_BLOCKSIZE; if (delta > map->sizeleft) delta = map->sizeleft; map->sizeleft -= delta; @@ -970,7 +970,7 @@ short_read (idx_t status) && record_start_block == 0 && status != 0 && archive_is_dev ()) { - idx_t rsize = status / BLOCKSIZE; + idx_t rsize = status >> LG_BLOCKSIZE; paxwarn (0, ngettext ("Record size = %td block", "Record size = %td blocks", @@ -1006,8 +1006,8 @@ short_read (idx_t status) more += status; } - record_end = record_start + (record_size - left) / BLOCKSIZE; - short_read_slop = (record_size - left) % BLOCKSIZE; + record_end = record_start + ((record_size - left) >> LG_BLOCKSIZE); + short_read_slop = (record_size - left) & (BLOCKSIZE - 1); records_read++; } @@ -1116,7 +1116,7 @@ seek_archive (off_t size) paxfatal (0, _("rmtlseek not stopped at a record boundary")); /* Convert to number of records */ - offset /= BLOCKSIZE; + offset >>= LG_BLOCKSIZE; /* Compute number of skipped blocks */ nblk = offset - start; @@ -1966,13 +1966,13 @@ _gnu_flush_write (idx_t buffer_level) memcpy (header->buffer, copy_ptr, bufsize); copy_ptr += bufsize; copy_size -= bufsize; - set_next_block_after (header + (bufsize - 1) / BLOCKSIZE); + set_next_block_after (header + ((bufsize - 1) >> LG_BLOCKSIZE)); header = find_next_block (); bufsize = available_space_after (header); } memcpy (header->buffer, copy_ptr, copy_size); memset (header->buffer + copy_size, 0, bufsize - copy_size); - set_next_block_after (header + (copy_size - 1) / BLOCKSIZE); + set_next_block_after (header + ((copy_size - 1) >> LG_BLOCKSIZE)); find_next_block (); } diff --git a/src/create.c b/src/create.c index 028b18dc..68995c33 100644 --- a/src/create.c +++ b/src/create.c @@ -543,13 +543,13 @@ write_gnu_long_link (struct tar_stat_info *st, const char *p, char type) memcpy (header->buffer, p, bufsize); p += bufsize; size -= bufsize; - set_next_block_after (header + (bufsize - 1) / BLOCKSIZE); + set_next_block_after (header + ((bufsize - 1) >> LG_BLOCKSIZE)); header = find_next_block (); bufsize = available_space_after (header); } memcpy (header->buffer, p, size); memset (header->buffer + size, 0, bufsize - size); - set_next_block_after (header + (size - 1) / BLOCKSIZE); + set_next_block_after (header + ((size - 1) >> LG_BLOCKSIZE)); } static int @@ -1041,7 +1041,7 @@ dump_regular_file (int fd, struct tar_stat_info *st) { /* Last read -- zero out area beyond. */ bufsize = size_left; - idx_t beyond = bufsize % BLOCKSIZE; + idx_t beyond = bufsize & (BLOCKSIZE - 1); if (beyond) memset (blk->buffer + size_left, 0, BLOCKSIZE - beyond); } @@ -1049,7 +1049,7 @@ dump_regular_file (int fd, struct tar_stat_info *st) idx_t count = (fd <= 0 ? bufsize : blocking_read (fd, blk->buffer, bufsize)); size_left -= count; - set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE); + set_next_block_after (blk + ((bufsize - 1) >> LG_BLOCKSIZE)); if (count != bufsize) { @@ -1130,14 +1130,14 @@ dump_dir0 (struct tar_stat_info *st, char const *directory) if (size_left < bufsize) { bufsize = size_left; - idx_t count = bufsize % BLOCKSIZE; + idx_t count = bufsize & (BLOCKSIZE - 1); if (count) memset (blk->buffer + size_left, 0, BLOCKSIZE - count); } memcpy (blk->buffer, p_buffer, bufsize); size_left -= bufsize; p_buffer += bufsize; - set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE); + set_next_block_after (blk + ((bufsize - 1) >> LG_BLOCKSIZE)); } } return; diff --git a/src/delete.c b/src/delete.c index b406aef2..78d1956e 100644 --- a/src/delete.c +++ b/src/delete.c @@ -114,8 +114,8 @@ write_recent_blocks (union block *h, idx_t blocks) static void write_recent_bytes (char *data, idx_t bytes) { - idx_t blocks = bytes / BLOCKSIZE; - idx_t rest = bytes % BLOCKSIZE; + idx_t blocks = bytes >> LG_BLOCKSIZE; + idx_t rest = bytes & (BLOCKSIZE - 1); write_recent_blocks ((union block *)data, blocks); memcpy (new_record[new_blocks].buffer, data + blocks * BLOCKSIZE, rest); @@ -131,7 +131,7 @@ flush_file (void) { set_next_block_after (current_header); off_t size = current_stat_info.stat.st_size; - off_t blocks_to_skip = size / BLOCKSIZE + (size % BLOCKSIZE != 0); + off_t blocks_to_skip = (size >> LG_BLOCKSIZE) + !!(size & (BLOCKSIZE - 1)); while (record_end - current_block <= blocks_to_skip) { @@ -293,7 +293,8 @@ delete_archive_members (void) new_record[new_blocks] = *current_header; new_blocks++; blocks_to_keep - = (current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE; + = ((current_stat_info.stat.st_size >> LG_BLOCKSIZE) + + !!(current_stat_info.stat.st_size & (BLOCKSIZE - 1))); set_next_block_after (current_header); if (new_blocks == blocking_factor) write_record (true); diff --git a/src/list.c b/src/list.c index 14cf64b8..6dbf4867 100644 --- a/src/list.c +++ b/src/list.c @@ -447,7 +447,7 @@ read_header (union block **return_block, struct tar_stat_info *info, union block *header_copy; if (ckd_add (&size, info->stat.st_size, 2 * BLOCKSIZE - 1)) xalloc_die (); - size -= size % BLOCKSIZE; + size -= size & (BLOCKSIZE - 1); header_copy = xmalloc (size + 1); @@ -455,13 +455,13 @@ read_header (union block **return_block, struct tar_stat_info *info, { free (next_long_name); next_long_name = header_copy; - next_long_name_blocks = size / BLOCKSIZE; + next_long_name_blocks = size >> LG_BLOCKSIZE; } else { free (next_long_link); next_long_link = header_copy; - next_long_link_blocks = size / BLOCKSIZE; + next_long_link_blocks = size >> LG_BLOCKSIZE; } set_next_block_after (header); diff --git a/src/sparse.c b/src/sparse.c index 9518b3ce..c7904e54 100644 --- a/src/sparse.c +++ b/src/sparse.c @@ -450,7 +450,7 @@ sparse_dump_region (struct tar_sparse_file *file, idx_t i) return false; } - set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE); + set_next_block_after (blk + ((bufsize - 1) >> LG_BLOCKSIZE)); } return true; @@ -482,7 +482,7 @@ sparse_extract_region (struct tar_sparse_file *file, idx_t i) } idx_t avail = available_space_after (blk); idx_t wrbytes = min (write_size, avail); - set_next_block_after (blk + (wrbytes - 1) / BLOCKSIZE); + set_next_block_after (blk + ((wrbytes - 1) >> LG_BLOCKSIZE)); file->dumped_size += avail; idx_t count = blocking_write (file->fd, blk->buffer, wrbytes); write_size -= count; @@ -1170,7 +1170,7 @@ pax_dump_header_1 (struct tar_sparse_file *file) size += floorlog10 (map[i].offset) + 2; size += floorlog10 (map[i].numbytes) + 2; } - size = (size + BLOCKSIZE - 1) / BLOCKSIZE * BLOCKSIZE; + size = (size + BLOCKSIZE - 1) & ~(BLOCKSIZE - 1); file->stat_info->archive_file_size += size; file->dumped_size += size; diff --git a/src/tar.c b/src/tar.c index 66486fcf..c6b3b007 100644 --- a/src/tar.c +++ b/src/tar.c @@ -2065,7 +2065,7 @@ parse_opt (int key, char *arg, struct argp_state *state) paxusage ("%s: %s", quotearg_colon (arg), _("Invalid record size")); if (record_size % BLOCKSIZE != 0) paxusage (_("Record size must be a multiple of %d."), BLOCKSIZE); - blocking_factor = record_size / BLOCKSIZE; + blocking_factor = record_size >> LG_BLOCKSIZE; } break; diff --git a/src/tar.h b/src/tar.h index dbd493f9..27611ecc 100644 --- a/src/tar.h +++ b/src/tar.h @@ -261,8 +261,9 @@ struct star_ext_header /* tar Header Block, overall structure. */ -/* tar files are made in basic blocks of this size. */ -enum { BLOCKSIZE = 512 }; +/* tar files are made in basic blocks of size BLOCKSIZE. + LG_BLOCKSIZE is the log base 2 of BLOCKSIZE. */ +enum { LG_BLOCKSIZE = 9, BLOCKSIZE = 1 << LG_BLOCKSIZE }; enum archive_format { diff --git a/src/update.c b/src/update.c index 7a2b293e..f9af5571 100644 --- a/src/update.c +++ b/src/update.c @@ -62,10 +62,10 @@ append_file (char *file_name) read_fatal (file_name); if (status == 0) break; - if (status % BLOCKSIZE) - memset (start->buffer + status - status % BLOCKSIZE, 0, - BLOCKSIZE - status % BLOCKSIZE); - set_next_block_after (start + (status - 1) / BLOCKSIZE); + idx_t rem = status % BLOCKSIZE; + if (rem) + memset (start->buffer + (status - rem), 0, BLOCKSIZE - rem); + set_next_block_after (start + ((status - 1) >> LG_BLOCKSIZE)); } if (close (handle) < 0)