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.
This commit is contained in:
Paul Eggert
2024-11-02 13:42:02 -07:00
parent 568919d77b
commit a6cf78b0fa
8 changed files with 32 additions and 30 deletions

View File

@@ -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 ();
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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
{

View File

@@ -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)