mirror of
https://github.com/urbit/shrub.git
synced 2024-12-20 09:21:42 +03:00
u3: coalesces memory protection when saving a snapshot
This commit is contained in:
parent
0682cc2864
commit
a04521585c
@ -507,21 +507,6 @@ _ce_patch_open(void)
|
||||
return pat_u;
|
||||
}
|
||||
|
||||
/* _ce_patch_write_page(): write a page of patch memory.
|
||||
*/
|
||||
static void
|
||||
_ce_patch_write_page(u3_ce_patch* pat_u,
|
||||
c3_w pgc_w,
|
||||
c3_w* mem_w)
|
||||
{
|
||||
size_t off_i = (size_t)pgc_w << (u3a_page + 2);
|
||||
|
||||
if ( 0 > c3_pwrite(pat_u->mem_i, mem_w, pag_siz_i, off_i) ) {
|
||||
fprintf(stderr, "loom: patch write: %s\r\n", strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* _ce_patch_count_page(): count a page, producing new counter.
|
||||
*/
|
||||
static c3_w
|
||||
@ -548,25 +533,17 @@ _ce_patch_save_page(u3_ce_patch* pat_u,
|
||||
c3_w bit_w = (pag_w & 31);
|
||||
|
||||
if ( u3P.dit_w[blk_w] & (1 << bit_w) ) {
|
||||
c3_w* mem_w = u3_Loom + (pag_w << u3a_page);
|
||||
c3_w* mem_w = u3_Loom + (pag_w << u3a_page);
|
||||
size_t off_i = (size_t)pgc_w << (u3a_page + 2);
|
||||
|
||||
pat_u->con_u->mem_u[pgc_w].pag_w = pag_w;
|
||||
pat_u->con_u->mem_u[pgc_w].mug_w = u3r_mug_words(mem_w, pag_wiz_i);
|
||||
|
||||
#if 0
|
||||
u3l_log("protect a: page %d\r\n", pag_w);
|
||||
#endif
|
||||
_ce_patch_write_page(pat_u, pgc_w, mem_w);
|
||||
|
||||
if ( -1 == mprotect(u3_Loom + (pag_w << u3a_page),
|
||||
pag_siz_i,
|
||||
PROT_READ) )
|
||||
{
|
||||
fprintf(stderr, "loom: patch mprotect: %s\r\n", strerror(errno));
|
||||
if ( 0 > c3_pwrite(pat_u->mem_i, mem_w, pag_siz_i, off_i) ) {
|
||||
fprintf(stderr, "loom: patch save: %s\r\n", strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
|
||||
u3P.dit_w[blk_w] &= ~(1 << bit_w);
|
||||
pgc_w += 1;
|
||||
}
|
||||
return pgc_w;
|
||||
@ -749,6 +726,62 @@ _ce_patch_apply(u3_ce_patch* pat_u)
|
||||
}
|
||||
}
|
||||
|
||||
/* _ce_loom_protect_north(): protect/track pages from the bottom of memory.
|
||||
*/
|
||||
static void
|
||||
_ce_loom_protect_north(c3_w pgs_w)
|
||||
{
|
||||
if ( pgs_w ) {
|
||||
if ( 0 != mprotect((void*)u3_Loom,
|
||||
(size_t)pgs_w << (u3a_page + 2),
|
||||
PROT_READ) )
|
||||
{
|
||||
fprintf(stderr, "loom: protect north (%u pages): %s\r\n",
|
||||
pgs_w, strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
c3_w blk_w = pgs_w >> 5;
|
||||
c3_w bit_w = pgs_w & 31;
|
||||
|
||||
memset((void*)u3P.dit_w, 0, blk_w << 2);
|
||||
u3P.dit_w[blk_w] &= 0xffffffff << bit_w;
|
||||
}
|
||||
}
|
||||
|
||||
/* _ce_loom_protect_south(): protect/track pages from the top of memory.
|
||||
*/
|
||||
static void
|
||||
_ce_loom_protect_south(c3_w pgs_w)
|
||||
{
|
||||
c3_w lof_w = u3P.pag_w - pgs_w;
|
||||
|
||||
if ( pgs_w ) {
|
||||
if ( 0 != mprotect((void*)(u3_Loom + (lof_w << u3a_page)),
|
||||
(size_t)pgs_w << (u3a_page + 2),
|
||||
PROT_READ) )
|
||||
{
|
||||
fprintf(stderr, "loom: protect south (%u pages): %s\r\n",
|
||||
pgs_w, strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
c3_w blk_w = pgs_w >> 5;
|
||||
c3_w bit_w = pgs_w & 31;
|
||||
c3_w bas_w = (lof_w + 31) >> 5;
|
||||
|
||||
memset((void*)(u3P.dit_w + bas_w), 0, blk_w << 2);
|
||||
|
||||
// this is safe so long as the south segment never includes all pages
|
||||
//
|
||||
u3P.dit_w[bas_w - 1] &= 0xffffffff >> bit_w;
|
||||
}
|
||||
}
|
||||
|
||||
/* _ce_loom_blit_north(): apply pages, in order, from the bottom of memory.
|
||||
*/
|
||||
static void
|
||||
@ -770,21 +803,7 @@ _ce_loom_blit_north(c3_i fid_i, c3_w pgs_w)
|
||||
}
|
||||
}
|
||||
|
||||
if ( 0 != mprotect((void*)u3_Loom,
|
||||
(size_t)pgs_w << (u3a_page + 2),
|
||||
PROT_READ) )
|
||||
{
|
||||
fprintf(stderr, "loom: protect north: %s\r\n", strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
|
||||
{
|
||||
c3_w blk_w = pgs_w >> 5;
|
||||
c3_w bit_w = pgs_w & 31;
|
||||
|
||||
memset((void*)u3P.dit_w, 0, blk_w << 2);
|
||||
u3P.dit_w[blk_w] &= 0xffffffff << bit_w;
|
||||
}
|
||||
_ce_loom_protect_north(pgs_w);
|
||||
}
|
||||
|
||||
/* _ce_loom_blit_south(): apply pages, reversed, from the top of memory.
|
||||
@ -792,15 +811,14 @@ _ce_loom_blit_north(c3_i fid_i, c3_w pgs_w)
|
||||
static void
|
||||
_ce_loom_blit_south(c3_i fid_i, c3_w pgs_w)
|
||||
{
|
||||
c3_w lof_w, i_w;
|
||||
c3_w i_w;
|
||||
c3_w* ptr_w;
|
||||
size_t off_i;
|
||||
ssize_t ret_i;
|
||||
|
||||
for ( i_w = 0; i_w < pgs_w; i_w++ ) {
|
||||
off_i = (size_t)i_w << (u3a_page + 2);
|
||||
lof_w = u3P.pag_w - (i_w + 1);
|
||||
ptr_w = u3_Loom + (lof_w << u3a_page);
|
||||
ptr_w = u3_Loom + ((u3P.pag_w - (i_w + 1)) << u3a_page);
|
||||
|
||||
if ( pag_siz_i != (ret_i = c3_pread(fid_i, ptr_w, pag_siz_i, off_i)) ) {
|
||||
if ( 0 < ret_i ) {
|
||||
@ -814,27 +832,7 @@ _ce_loom_blit_south(c3_i fid_i, c3_w pgs_w)
|
||||
}
|
||||
}
|
||||
|
||||
c3_assert ( (u3P.pag_w - pgs_w) == lof_w );
|
||||
|
||||
if ( 0 != mprotect((void*)(u3_Loom + (lof_w << u3a_page)),
|
||||
(size_t)pgs_w << (u3a_page + 2),
|
||||
PROT_READ) )
|
||||
{
|
||||
fprintf(stderr, "loom: protect south: %s\r\n", strerror(errno));
|
||||
c3_assert(0);
|
||||
}
|
||||
|
||||
{
|
||||
c3_w blk_w = pgs_w >> 5;
|
||||
c3_w bit_w = pgs_w & 31;
|
||||
c3_w bas_w = (lof_w + 31) >> 5;
|
||||
|
||||
memset((void*)(u3P.dit_w + bas_w), 0, blk_w << 2);
|
||||
|
||||
// this is safe so long as the south segment never includes all pages
|
||||
//
|
||||
u3P.dit_w[bas_w - 1] &= 0xffffffff >> bit_w;
|
||||
}
|
||||
_ce_loom_protect_south(pgs_w);
|
||||
}
|
||||
|
||||
#ifdef U3_SNAPSHOT_VALIDATION
|
||||
@ -1034,6 +1032,9 @@ u3e_save(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
_ce_loom_protect_north(u3P.nor_u.pgs_w);
|
||||
_ce_loom_protect_south(u3P.sou_u.pgs_w);
|
||||
|
||||
_ce_image_sync(&u3P.nor_u);
|
||||
_ce_image_sync(&u3P.sou_u);
|
||||
_ce_patch_free(pat_u);
|
||||
|
Loading…
Reference in New Issue
Block a user