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