u3: refactors mmap read/write patterns in urth.c

This commit is contained in:
Joe Bryan 2020-09-01 12:07:21 -07:00
parent f0dd6dc7a6
commit 7d541b5a1f
2 changed files with 128 additions and 28 deletions

View File

@ -15,3 +15,23 @@
*/ */
c3_o c3_o
u3u_uncram(c3_c* dir_c, c3_d eve_d); u3u_uncram(c3_c* dir_c, c3_d eve_d);
/* u3u_mmap_read(): open and mmap the file at [pat_c] for reading.
*/
c3_o
u3u_mmap_read(c3_c* cap_c, c3_c* pat_c, c3_d* out_d, c3_y** out_y);
/* u3u_mmap(): open/create file-backed mmap at [pat_c] for read/write.
*/
c3_o
u3u_mmap(c3_c* cap_c, c3_c* pat_c, c3_d len_d, c3_y** out_y);
/* u3u_mmap_save(): sync file-backed mmap.
*/
c3_o
u3u_mmap_save(c3_c* cap_c, c3_c* pat_c, c3_d len_d, c3_y* byt_y);
/* u3u_munmap(): unmap the region at [byt_y].
*/
c3_o
u3u_munmap(c3_d len_d, c3_y* byt_y);

View File

@ -657,41 +657,30 @@ u3u_cram(c3_c* dir_c, c3_d eve_d)
return ret_o; return ret_o;
} }
/* _cu_rock_load(): load a rock into a byte buffer. /* u3u_mmap_read(): open and mmap the file at [pat_c] for reading.
*/ */
static c3_o c3_o
_cu_rock_load(c3_c* dir_c, c3_d eve_d, c3_d* out_d, c3_y** out_y) u3u_mmap_read(c3_c* cap_c, c3_c* pat_c, c3_d* out_d, c3_y** out_y)
{ {
c3_i fid_i; c3_i fid_i;
c3_d len_d; c3_d len_d;
// open rock file // open file
// //
{ if ( -1 == (fid_i = open(pat_c, O_RDONLY, 0644)) ) {
c3_c* nam_c; fprintf(stderr, "%s: open failed (%s): %s\r\n",
cap_c, pat_c, strerror(errno));
if ( c3n == _cu_rock_path(dir_c, eve_d, &nam_c) ) {
return c3n; return c3n;
} }
if ( -1 == (fid_i = open(nam_c, O_RDONLY, 0644)) ) { // measure file
fprintf(stderr, "rock: open failed (%s, %" PRIu64 "): %s\r\n",
dir_c, eve_d, strerror(errno));
c3_free(nam_c);
return c3n;
}
c3_free(nam_c);
}
// measure rock file
// //
{ {
struct stat buf_b; struct stat buf_b;
if ( -1 == fstat(fid_i, &buf_b) ) { if ( -1 == fstat(fid_i, &buf_b) ) {
fprintf(stderr, "rock: stat failed (%s, %" PRIu64 "): %s\r\n", fprintf(stderr, "%s: stat failed (%s): %s\r\n",
dir_c, eve_d, strerror(errno)); cap_c, pat_c, strerror(errno));
close(fid_i); close(fid_i);
return c3n; return c3n;
} }
@ -699,14 +688,14 @@ _cu_rock_load(c3_c* dir_c, c3_d eve_d, c3_d* out_d, c3_y** out_y)
len_d = buf_b.st_size; len_d = buf_b.st_size;
} }
// mmap rock file // mmap file
// //
{ {
void* ptr_v; void* ptr_v;
if ( MAP_FAILED == (ptr_v = mmap(0, len_d, PROT_READ, MAP_SHARED, fid_i, 0)) ) { if ( MAP_FAILED == (ptr_v = mmap(0, len_d, PROT_READ, MAP_SHARED, fid_i, 0)) ) {
fprintf(stderr, "rock: mmap failed (%s, %" PRIu64 "): %s\r\n", fprintf(stderr, "%s: mmap failed (%s): %s\r\n",
dir_c, eve_d, strerror(errno)); cap_c, pat_c, strerror(errno));
close(fid_i); close(fid_i);
return c3n; return c3n;
} }
@ -715,22 +704,104 @@ _cu_rock_load(c3_c* dir_c, c3_d eve_d, c3_d* out_d, c3_y** out_y)
*out_y = (c3_y*)ptr_v; *out_y = (c3_y*)ptr_v;
} }
// close file
//
close(fid_i); close(fid_i);
return c3y; return c3y;
} }
/* u3u_mmap(): open/create file-backed mmap at [pat_c] for read/write.
*/
c3_o
u3u_mmap(c3_c* cap_c, c3_c* pat_c, c3_d len_d, c3_y** out_y)
{
c3_i fid_i;
// open file
//
if ( -1 == (fid_i = open(pat_c, O_RDWR | O_CREAT | O_TRUNC, 0644)) ) {
fprintf(stderr, "%s: open failed (%s): %s\r\n",
cap_c, pat_c, strerror(errno));
return c3n;
}
// grow [fid_i] to [len_w]
//
// XX build with _FILE_OFFSET_BITS == 64 ?
//
if ( 0 != ftruncate(fid_i, len_d) ) {
fprintf(stderr, "%s: ftruncate grow %s: %s\r\n",
cap_c, pat_c, strerror(errno));
close(fid_i);
return c3n;
}
// mmap file
//
{
void* ptr_v;
if ( MAP_FAILED == (ptr_v = mmap(0, len_d, PROT_READ|PROT_WRITE, MAP_SHARED, fid_i, 0)) ) {
fprintf(stderr, "%s: mmap failed (%s): %s\r\n",
cap_c, pat_c, strerror(errno));
close(fid_i);
return c3n;
}
*out_y = (c3_y*)ptr_v;
}
// close file
//
close(fid_i);
return c3y;
}
/* u3u_mmap_save(): sync file-backed mmap.
*/
c3_o
u3u_mmap_save(c3_c* cap_c, c3_c* pat_c, c3_d len_d, c3_y* byt_y)
{
if ( 0 != msync(byt_y, len_d, MS_SYNC) ) {
fprintf(stderr, "%s: msync %s: %s\r\n", cap_c, pat_c, strerror(errno));
return c3n;
}
return c3y;
}
/* u3u_munmap(): unmap the region at [byt_y].
*/
c3_o
u3u_munmap(c3_d len_d, c3_y* byt_y)
{
if ( 0 != munmap(byt_y, len_d) ) {
return c3n;
}
return c3y;
}
/* u3u_uncram(): restore persistent state from a rock. /* u3u_uncram(): restore persistent state from a rock.
*/ */
c3_o c3_o
u3u_uncram(c3_c* dir_c, c3_d eve_d) u3u_uncram(c3_c* dir_c, c3_d eve_d)
{ {
c3_c* nam_c;
c3_d len_d; c3_d len_d;
c3_y* byt_y; c3_y* byt_y;
// load rock file into buffer // load rock file into buffer
// //
if ( c3n == _cu_rock_load(dir_c, eve_d, &len_d, &byt_y) ) { if ( c3n == _cu_rock_path(dir_c, eve_d, &nam_c) ) {
fprintf(stderr, "uncram: failed to make rock path (%s, %" PRIu64 ")\r\n",
dir_c, eve_d);
return c3n;
}
else if ( c3n == u3u_mmap_read("rock", nam_c, &len_d, &byt_y) ) {
c3_free(nam_c);
return c3n; return c3n;
} }
@ -764,6 +835,7 @@ u3u_uncram(c3_c* dir_c, c3_d eve_d)
if ( c3n == u3s_cue_xeno_unsafe(&dic_u, len_d, byt_y, &ref) ) { if ( c3n == u3s_cue_xeno_unsafe(&dic_u, len_d, byt_y, &ref) ) {
fprintf(stderr, "uncram: failed to cue rock\r\n"); fprintf(stderr, "uncram: failed to cue rock\r\n");
ur_dict_free((ur_dict_t*)&dic_u); ur_dict_free((ur_dict_t*)&dic_u);
c3_free(nam_c);
return c3n; return c3n;
} }
@ -772,6 +844,7 @@ u3u_uncram(c3_c* dir_c, c3_d eve_d)
if ( c3n == u3r_pq(ref, c3__fast, &roc, &cod) ) { if ( c3n == u3r_pq(ref, c3__fast, &roc, &cod) ) {
fprintf(stderr, "uncram: failed: invalid rock format\r\n"); fprintf(stderr, "uncram: failed: invalid rock format\r\n");
u3z(ref); u3z(ref);
c3_free(nam_c);
return c3n; return c3n;
} }
@ -781,6 +854,8 @@ u3u_uncram(c3_c* dir_c, c3_d eve_d)
u3z(ref); u3z(ref);
} }
u3u_munmap(len_d, byt_y);
// allocate new hot jet state; re-establish warm // allocate new hot jet state; re-establish warm
// //
u3j_boot(c3y); u3j_boot(c3y);
@ -796,9 +871,14 @@ u3u_uncram(c3_c* dir_c, c3_d eve_d)
// leave rocks on disk // leave rocks on disk
// //
// if ( c3n == u3m_rock_drop(dir_c, eve_d) ) { // if ( 0 != unlink(nam_c) ) {
// u3l_log("serf: warning: orphaned state file\r\n"); // fprintf(stderr, "uncram: failed to delete rock (%s, %" PRIu64 "): %s\r\n",
// dir_c, eve_d, strerror(errno));
// c3_free(nam_c);
// return c3n;
// } // }
c3_free(nam_c);
return c3y; return c3y;
} }