Diff for /freem/src/global_bltin.c between versions 1.17 and 1.18

version 1.17, 2025/04/11 14:21:03 version 1.18, 2025/04/11 16:23:18
Line 24 Line 24
  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.   *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
  *   *
  *   $Log$   *   $Log$
    *   Revision 1.18  2025/04/11 16:23:18  snw
    *   Avoid re-reading the same block consecutively when possible
    *
  *   Revision 1.17  2025/04/11 14:21:03  snw   *   Revision 1.17  2025/04/11 14:21:03  snw
  *   Make all but one of the read/write calls in global_bltin use gbl_read_block or gbl_write_block   *   Make all but one of the read/write calls in global_bltin use gbl_read_block or gbl_write_block
  *   *
Line 323  int gbl_write_header(global_handle *g, g Line 326  int gbl_write_header(global_handle *g, g
         return FALSE;          return FALSE;
     }      }
   
     if (g->locked == FALSE) gbl_lock (g, 1);      gbl_lock (g, 1);
     old_position = lseek (g->fd, 0, SEEK_CUR);      old_position = lseek (g->fd, 0, SEEK_CUR);
     lseek (g->fd, 0, SEEK_SET);      lseek (g->fd, 0, SEEK_SET);
   
Line 333  int gbl_write_header(global_handle *g, g Line 336  int gbl_write_header(global_handle *g, g
     }      }
   
     lseek (g->fd, old_position, SEEK_SET);      lseek (g->fd, old_position, SEEK_SET);
     if (g->locked == TRUE) gbl_unlock (g);      gbl_unlock (g);
   
     gbl_read_header (g, &g->header);      gbl_read_header (g, &g->header);
           
Line 445  short gbl_open(global_handle *g, short a Line 448  short gbl_open(global_handle *g, short a
         }          }
         else {          else {
             g->opened = TRUE;              g->opened = TRUE;
             result = gbl_read_header (g, &g->header);              result = gbl_read_header (g, &g->header);            
                           
             if (result == GBL_HDR_OK) {              if (result == GBL_HDR_OK) {
                   /* initialize last_block_accessed cache */
                   g->last_block_accessed = (char *) calloc (g->header.block_size, sizeof (char));
                   NULLPTRCHK(g->last_block_accessed,"gbl_open");
                   
                 g->opened = TRUE;                  g->opened = TRUE;
             }              }
             else {                              else {                
Line 479  short gbl_open(global_handle *g, short a Line 486  short gbl_open(global_handle *g, short a
   
 int gbl_read_block(global_handle *g, unsigned long blocknum, char *block)  int gbl_read_block(global_handle *g, unsigned long blocknum, char *block)
 {  {
       struct stat gstat;
     unsigned long hdr_offset;      unsigned long hdr_offset;
     hdr_offset = sizeof (global_header);      hdr_offset = sizeof (global_header);
           
Line 486  int gbl_read_block(global_handle *g, uns Line 494  int gbl_read_block(global_handle *g, uns
         return FALSE;          return FALSE;
     }      }
   
     gbl_lock (g, 1);  
     lseek (g->fd, hdr_offset + ((long) blocknum * (long) (g->header.block_size)), SEEK_SET);  
     read (g->fd, block, g->header.block_size);  
     g->last_block = blocknum;  
     g->use_count++;      g->use_count++;
     g->read_ops++;  
     gbl_unlock (g);      fstat (g->fd, &gstat);    
       if (!g->locked) gbl_lock (g, 1);
               
       
       if ((g->last_block == blocknum) &&
           (g->have_cached_block) &&
           (g->cached_block_num == blocknum) &&
           (gstat.st_mtime < g->last_read_time)) {        
           /* the global has not been modified since the last read; grab from memory */
           g->memory_reads++;
           g->last_read_time = time (0L);
           memcpy (block, g->last_block_accessed, g->header.block_size);      
       }
       else {
           /* have to go out to disk */ 
           lseek (g->fd, hdr_offset + ((long) blocknum * (long) (g->header.block_size)), SEEK_SET);
           read (g->fd, block, g->header.block_size);
   
           /* update cache */
           memcpy (g->last_block_accessed, block, g->header.block_size);
           g->have_cached_block = TRUE;
           g->last_read_time = time (0L);
           g->cached_block_num = blocknum;
           
           g->last_block = blocknum;
           g->use_count++;
           g->read_ops++;
       }
       
       if (g->locked) gbl_unlock (g);
   
     return TRUE;          return TRUE;    
 } /* gbl_read_block() */  } /* gbl_read_block() */
Line 507  int gbl_write_block(global_handle *g, un Line 540  int gbl_write_block(global_handle *g, un
         return FALSE;          return FALSE;
     }      }
   
     if (!g->locked) {      gbl_lock (g, 1);    
         gbl_lock (g, 1);  
     }  
   
     for (;;) {      for (;;) {
                           
Line 528  int gbl_write_block(global_handle *g, un Line 559  int gbl_write_block(global_handle *g, un
                   
     }      }
   
     gbl_update_tid (g);      gbl_update_tid (g);  
           gbl_unlock (g);
     if (g->locked) {  
         gbl_unlock (g);  
     }  
   
     return TRUE;          return TRUE;    
 }  }
Line 578  global_handle *gbl_handle(char *key) Line 606  global_handle *gbl_handle(char *key)
     g->use_count = 1;      g->use_count = 1;
     g->locked = FALSE;      g->locked = FALSE;
     g->age = time (0L);      g->age = time (0L);
       g->last_read_time = 0;
     g->last_block = 0;      g->last_block = 0;
     g->opened = FALSE;      g->opened = FALSE;
     g->fd = 0;      g->fd = 0;
Line 586  global_handle *gbl_handle(char *key) Line 615  global_handle *gbl_handle(char *key)
     g->cache_hits = 0;      g->cache_hits = 0;
     g->read_ops = 0;      g->read_ops = 0;
     g->write_ops = 0;      g->write_ops = 0;
       g->memory_reads = 0;
       g->have_cached_block = FALSE;
       g->last_block_accessed = NULL;
           
     strcpy (g->global_name, global_name);          strcpy (g->global_name, global_name);    
     gbl_path (key, g->global_path);      gbl_path (key, g->global_path);
Line 3716  void gbl_dump_stat(void) Line 3748  void gbl_dump_stat(void)
     int hit_pct;      int hit_pct;
     unsigned long access_total;         unsigned long access_total;   
     unsigned long hit_total;      unsigned long hit_total;
           unsigned long mem_reads_total;
   
       mem_reads_total = 0;
     printf ("\r\nFreeM Global Statistics [PID %d]\r\n\r\n", pid);      printf ("\r\nFreeM Global Statistics [PID %d]\r\n\r\n", pid);
   
     printf ("%-20s%-10s%-10s%-10s%-12s%-20s%-10s%s\r\n", "GLOBAL", "USECT", "READS", "WRITES", "SLOW PTHCT", "AGE", "LAST BLK", "FILE");      printf ("%-20s%-10s%-10s%-10s%-10s%-12s%-20s%-10s%s\r\n", "GLOBAL", "USECT", "READS", "WRITES", "MEMREADS", "SLOW PTHCT", "AGE", "LAST BLK", "FILE");
     printf ("%-20s%-10s%-10s%-10s%-12s%-20s%-10s%s\r\n", "======", "=====", "=====", "======", "==========", "===", "========", "====");      printf ("%-20s%-10s%-10s%-10s%-10s%-12s%-20s%-10s%s\r\n", "======", "=====", "=====", "======", "========", "==========", "===", "========", "====");
   
     access_total = 0;      access_total = 0;
     ct = 0;      ct = 0;
     for (g = global_handles_head; g != NULL; g = g->next) {      for (g = global_handles_head; g != NULL; g = g->next) {
         printf ("%-20s%-10ld%-10ld%-10ld%-12ld%-20ld%-10ld%s\r\n",          printf ("%-20s%-10ld%-10ld%-10ld%-10ld%-12ld%-20ld%-10ld%s\r\n",
                 g->global_name,                  g->global_name,
                 g->use_count,                  g->use_count,
                 g->read_ops,                  g->read_ops,
                 g->write_ops,                  g->write_ops,
                   g->memory_reads,
                 g->cache_misses,                  g->cache_misses,
                 g->age,                  g->age,
                 g->last_block,                  g->last_block,
                 g->global_path);                  g->global_path);
         ct++;          ct++;
           mem_reads_total += g->memory_reads;
         access_total += g->use_count;                access_total += g->use_count;      
     }      }
     if (!ct) printf ("<no globals opened in this pid>\r\n");      if (!ct) printf ("<no globals opened in this pid>\r\n");
Line 3745  void gbl_dump_stat(void) Line 3781  void gbl_dump_stat(void)
           
     printf ("\r\nTotal accesses:      %ld\r\n", access_total);      printf ("\r\nTotal accesses:      %ld\r\n", access_total);
     printf ("Fast path hits       %ld\t(%d%%)\r\n", hit_total, hit_pct);      printf ("Fast path hits       %ld\t(%d%%)\r\n", hit_total, hit_pct);
     printf ("Fast path misses:    %ld\t(%d%%)\r\n", gbl_cache_misses, miss_pct);          printf ("Fast path misses:    %ld\t(%d%%)\r\n", gbl_cache_misses, miss_pct);
       printf ("Disk reads avoided:  %ld\r\n", mem_reads_total);
       
 }  }

Removed from v.1.17  
changed lines
  Added in v.1.18


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>