]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
Add LG_BLOCKSIZE to omit some *, % ops
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 2 Nov 2024 20:42:02 +0000 (13:42 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 2 Nov 2024 20:43:05 +0000 (13:43 -0700)
* 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.

src/buffer.c
src/create.c
src/delete.c
src/list.c
src/sparse.c
src/tar.c
src/tar.h
src/update.c

index 21a89374f752e402b210ffdc57e680b238badc0c..8b6028ce969ca92e100404edcc0382263c42f68c 100644 (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 ();
 }
 
index 028b18dc09f31d2d693acfa4463c05c7f5352db0..68995c33ff13211ee1839c53a4d5c6132ec8e716 100644 (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;
index b406aef2977facd28b2ec903fefee6e5d37b6548..78d1956e0fb27cbd65eb5930294fc71d513b6e29 100644 (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);
index 14cf64b813f29163e613c5d20cf5bdbedc147b31..6dbf486766b161c3697b38c318957b1ac5c8aec7 100644 (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);
index 9518b3ce4eb875980352979018ea34efe90721ea..c7904e54635dc55992862a33bfd9fbef565ba307 100644 (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;
 
index 66486fcf4276944dd54b1f70e4946c9fa01d647c..c6b3b007dd6e7ed946e26876317ee07ba561e1df 100644 (file)
--- 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;
 
index dbd493f9b1d060a11cd72caf04e17a9191e6d5b6..27611ecc229683b111595ad54633a8d3ef7a19c7 100644 (file)
--- 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
 {
index 7a2b293ec688a302842390dc9aff2a22217eba39..f9af55712058b985a77b34fff7995d60294a214e 100644 (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)