Merge remote-tracking branch 'origin/master' into lighter-than-eyre

This commit is contained in:
Elliot Glaysher 2019-02-08 16:53:23 -08:00
commit 9c7fff3e60
36 changed files with 2027 additions and 1018 deletions

3
.gitmodules vendored
View File

@ -7,6 +7,9 @@
[submodule "subprojects/h2o"]
path = subprojects/libh2o
url = https://github.com/urbit/h2o.git
[submodule "subprojects/libent"]
path = subprojects/libent
url = https://github.com/urbit/libent.git
[submodule "subprojects/libuv"]
path = subprojects/libuv
url = https://github.com/urbit/libuv.git

View File

@ -45,13 +45,13 @@ addons:
- unzip
- gdb
# before_deploy: "make deb" # TODO
deploy:
skip_cleanup: true
provider: releases
prerelease: true # turn this off for official releases
api_key:
secure: V4E7784ECSS3MO6ZIRtang9XwibDyvDYGb0MoSaP2CTlmzIAhdokr4KJFM0qM4KRaaajCdQuqi0lojgOjwdxs7e0GkAwScb33LFxQ7Chj/QkFOY7V1AnSRLR5OsXnazB0nur5aSwvcvnggQ2XW3OeF7zIvGfs9aR97SEz/xCrVE=
file: ./build/urbit # TODO upload package from before_deploy
on:
repo: urbit/urbit
tags: true
# deploy:
# skip_cleanup: true
# provider: releases
# prerelease: true # turn this off for official releases
# api_key:
# secure: XX
# file: ./build/urbit # TODO upload package from before_deploy
# on:
# repo: urbit/urbit
# tags: true

View File

@ -1 +1 @@
d318b2cfcf33ac41aeaacb03e8b5593f8eb5e690
6d6ec85d6aa9200d366d0998326726ef1965d092

View File

@ -38,6 +38,13 @@ Promise.resolve(urbit)
})
.then(actions.safeBoot)
.then(actions.test)
.then(function(){
return urbit.line("|mass")
.then(function(){
return urbit.expectEcho("%ran-mass")
.then(function(){ return urbit.resetListeners(); })
})
})
.then(exit)
.catch(function(err){
// we still exit 0, Arvo errors are not our fault ...

View File

@ -168,11 +168,5 @@ eager to have outside contributions on. Check here first!
## Staying in touch
The urbit developers communicate on urbit itself. Joining the
`urbit-meta` channel on
[`:talk`](https://urbit.org/docs/learn/arvo/arvo-internals/messaging/)
is highly recommended, as is reading the forums at
[http://urbit.org/fora](http://urbit.org/fora).
Questions or other communications about contributing to Urbit can go to
[support@urbit.org](mailto:support@urbit.org).

View File

@ -74,9 +74,6 @@ If you want to specify custom `DESTDIR`, use `DESTDIR=... ninja install`.
## Contact
If you have any questions, problems, patches, or proposals for patches, please
feel free to get in touch in whatever way is most convenient:
- Post to `/urbit-meta` on Urbit [`:talk`](https://urbit.org/docs/learn/arvo/arvo-internals/messaging/).
- Post to [urbit.org/fora](https://urbit.org/fora/).
- Email us directly [questions@urbit.org](mailto:questions@urbit.org).
We are using our new UI, Landscape to run a few experimental cities.
If you have an Azimuth point, please send us your planet name at
[support@urbit.org](mailto:support@urbit.org) to request access.

View File

@ -20,6 +20,9 @@
*** C file.
**/
# if defined(U3_OS_linux)
# ifndef _XOPEN_SOURCE
# define _XOPEN_SOURCE 700
# endif
# include <inttypes.h>
# include <stdlib.h>
# include <string.h>
@ -31,7 +34,6 @@
# include <setjmp.h>
# include <stdio.h>
# include <signal.h>
# include <sys/syscall.h>
# include <sys/time.h>
# include <sys/resource.h>
# include <sys/mman.h>
@ -49,7 +51,6 @@
# include <machine/endian.h>
# include <machine/byte_order.h>
# include <stdio.h>
# include <sys/random.h>
# include <sys/time.h>
# include <sys/resource.h>
# include <sys/mman.h>
@ -183,17 +184,6 @@
# define lseek64 lseek
# else
# error "port: timeconvert"
# endif
/* Entropy.
*/
# if defined(U3_OS_linux)
# define c3_getentropy(B, L) \
((L) == syscall(SYS_getrandom, B, L, 0) ? 0 : -1)
# elif defined(U3_OS_bsd) || defined(U3_OS_osx)
# define c3_getentropy getentropy
# else
# error "port: getentropy"
# endif
/* Static assertion.

View File

@ -13,5 +13,6 @@
#mesondefine U3_MEMORY_DEBUG
#mesondefine U3_CPU_DEBUG
#mesondefine U3_EVENT_TIME_DEBUG
#mesondefine U3_MEMORY_LOG
#endif /*CONFIG_H*/

View File

@ -25,6 +25,8 @@
# define u3a_bytes (c3_w)((1 << (2 + u3a_bits)))
/* u3a_minimum: minimum number of words in a box.
**
** wiseof(u3a_cell) + wiseof(u3a_box) + 1 (trailing siz_w)
*/
#ifdef U3_MEMORY_DEBUG
# define u3a_minimum 8
@ -402,6 +404,11 @@
c3_w
u3a_mark_noun(u3_noun som);
/* u3a_mark_road(): mark ad-hoc persistent road structures.
*/
c3_w
u3a_mark_road(FILE* fil_u);
/* u3a_sweep(): sweep a fully marked road.
*/
c3_w
@ -422,10 +429,15 @@
void
u3a_lop(c3_w lab_w);
/* u3a_print_memory: print memory amount.
/* u3a_print_memory(): print memory amount.
*/
void
u3a_print_memory(c3_c* cap_c, c3_w wor_w);
u3a_print_memory(FILE* fil_u, c3_c* cap_c, c3_w wor_w);
/* u3a_maid(): maybe print memory.
*/
c3_w
u3a_maid(FILE* fil_u, c3_c* cap_c, c3_w wor_w);
/* u3a_deadbeef(): write 0xdeadbeef from hat to cap.
*/

View File

@ -260,7 +260,12 @@
/* u3j_mark(): mark jet state for gc.
*/
c3_w
u3j_mark(void);
u3j_mark(FILE* fil_u);
/* u3j_free_hank(): free an entry from the hank cache.
*/
void
u3j_free_hank(u3_noun kev);
/* u3j_free(): free jet state.
*/

View File

@ -26,10 +26,10 @@
c3_i
u3m_bail(c3_m how_m) __attribute__((noreturn));
/* u3m_init(): start the environment, with/without checkpointing.
/* u3m_init(): start the environment.
*/
void
u3m_init(c3_o chk_o);
u3m_init();
/* u3m_pave(): instantiate or activate image.
*/
@ -94,7 +94,7 @@
/* u3m_mark(): mark all nouns in the road.
*/
c3_w
u3m_mark(void);
u3m_mark(FILE* fil_u);
/* u3m_grab(): garbage-collect the world, plus extra roots.
*/
@ -125,3 +125,8 @@
*/
void
u3m_wall(u3_noun wol);
/* u3m_reclaim: clear persistent caches to reclaim memory
*/
void
u3m_reclaim(void);

View File

@ -110,7 +110,7 @@
/* u3n_mark(): mark bytecode cache.
*/
c3_w
u3n_mark(void);
u3n_mark(FILE* fil_u);
/* u3n_free(): free bytecode cache.
*/

View File

@ -86,7 +86,7 @@
/* u3t_trace_open(): opens the path for writing tracing information.
*/
void
u3t_trace_open(c3_c*);
u3t_trace_open();
/* u3t_trace_close(): closes the trace file. optional.
*/

View File

@ -147,4 +147,4 @@
/* u3v_mark(): mark arvo kernel.
*/
c3_w
u3v_mark(void);
u3v_mark(FILE* fil_u);

View File

@ -327,15 +327,6 @@
c3_l tno_l; // terminal count in host
} u3_uled;
/* u3_olar: event log trailer, old version.
*/
typedef struct {
c3_w syn_w; // must equal mug of address
c3_w ent_w; // event sequence number
c3_w len_w; // word length of this event
c3_w mug_w; // mug of entry
} u3_olar;
/* u3_ular: event log trailer.
*/
typedef struct {
@ -575,6 +566,14 @@
c3_o vog; // did they vote for us?
} u3_rnam;
/* u3_trac: tracing information.
*/
typedef struct _u3_trac {
c3_w nid_w; // nock pid
FILE* fil_u; // trace file (json)
c3_w con_w; // trace counter
} u3_trac;
/* u3_opts: command line configuration.
*/
typedef struct _u3_opts {
@ -593,7 +592,7 @@
c3_c* gen_c; // -G, czar generator
c3_o gab; // -g, test garbage collection
c3_c* dns_c; // -H, ames bootstrap domain
c3_c* json_file_c; // -j, json trace
c3_o tra; // -j, json trace
c3_w kno_w; // -K, kernel version
c3_c* key_c; // -k, private key file
c3_o net; // -L, local-only networking
@ -635,7 +634,7 @@
c3_o liv; // if u3_no, shut down
c3_i xit_i; // exit code for shutdown
void* tls_u; // server SSL_CTX*
FILE* trace_file_u; // trace file to write to
u3_trac tra_u; // tracing information
} u3_host; // host == computer == process
# define u3L u3_Host.lup_u // global event loop

File diff suppressed because it is too large Load Diff

View File

@ -236,10 +236,11 @@ endforeach
incdir = include_directories('include/')
conf_data = configuration_data()
conf_data.set('URBIT_VERSION', '"0.7.0"')
conf_data.set('URBIT_VERSION', '"0.7.2"')
conf_data.set('U3_MEMORY_DEBUG', get_option('gc'))
conf_data.set('U3_CPU_DEBUG', get_option('prof'))
conf_data.set('U3_EVENT_TIME_DEBUG', get_option('event-time'))
conf_data.set('U3_MEMORY_LOG', get_option('memory-log'))
osdet = host_machine.system()
cc = meson.get_compiler('c')
@ -320,6 +321,7 @@ endif
# For these libs we provide fallback bundle
argon2_dep = dependency('argon2', version: '>=1', fallback: ['argon2', 'argon2_dep'])
ed25519_dep = dependency('ed25519', version: '>=0.1.0', fallback: ['ed25519', 'ed25519_dep'])
libent_dep = dependency('libent', version: '>=0.2.1', fallback: ['libent', 'libent_dep'])
libh2o_dep = dependency('libh2o', version: '>=0.13.3', fallback: ['libh2o', 'libh2o_dep'])
libscrypt_dep = dependency('libscrypt', version: '>=0.1.21', fallback: ['libscrypt', 'libscrypt_dep'])
libsni_dep = dependency('libsni', version: '>=0.5.0', fallback: ['libsni', 'libsni_dep'])
@ -332,6 +334,7 @@ deps = [argon2_dep,
curl_dep,
ed25519_dep,
gmp_dep,
libent_dep,
libh2o_dep,
libscrypt_dep,
libsni_dep,

View File

@ -4,5 +4,7 @@ option('prof', type : 'boolean', value : false,
description : 'Activate profiling. Run with -P.')
option('event-time', type : 'boolean', value : false,
description : 'Print timing information per event.')
option('memory-log', type : 'boolean', value : false,
description : 'Write memory usage to a logfile.')
option('nix', type: 'boolean', value: false,
description: 'Build using nix.')

View File

@ -1616,9 +1616,9 @@ u3a_mark_noun(u3_noun som)
/* u3a_print_memory: print memory amount.
*/
void
u3a_print_memory(c3_c* cap_c, c3_w wor_w)
u3a_print_memory(FILE* fil_u, c3_c* cap_c, c3_w wor_w)
{
FILE *fil_f = u3_term_io_hija();
c3_assert( 0 != fil_u );
c3_w byt_w = (wor_w * 4);
c3_w gib_w = (byt_w / 1000000000);
@ -1628,22 +1628,153 @@ u3a_print_memory(c3_c* cap_c, c3_w wor_w)
if ( byt_w ) {
if ( gib_w ) {
fprintf(fil_f, "%s: GB/%d.%03d.%03d.%03d\r\n",
fprintf(fil_u, "%s: GB/%d.%03d.%03d.%03d\r\n",
cap_c, gib_w, mib_w, kib_w, bib_w);
}
else if ( mib_w ) {
fprintf(fil_f, "%s: MB/%d.%03d.%03d\r\n", cap_c, mib_w, kib_w, bib_w);
fprintf(fil_u, "%s: MB/%d.%03d.%03d\r\n", cap_c, mib_w, kib_w, bib_w);
}
else if ( kib_w ) {
fprintf(fil_f, "%s: KB/%d.%03d\r\n", cap_c, kib_w, bib_w);
fprintf(fil_u, "%s: KB/%d.%03d\r\n", cap_c, kib_w, bib_w);
}
else if ( bib_w ) {
fprintf(fil_f, "%s: B/%d\r\n", cap_c, bib_w);
fprintf(fil_u, "%s: B/%d\r\n", cap_c, bib_w);
}
}
u3_term_io_loja(0);
}
/* u3a_maid(): maybe print memory.
*/
c3_w
u3a_maid(FILE* fil_u, c3_c* cap_c, c3_w wor_w)
{
if ( 0 != fil_u ) {
u3a_print_memory(fil_u, cap_c, wor_w);
}
return wor_w;
}
/* u3a_mark_road(): mark ad-hoc persistent road structures.
*/
c3_w
u3a_mark_road(FILE* fil_u)
{
c3_w tot_w = 0;
tot_w += u3a_maid(fil_u, " namespace", u3a_mark_noun(u3R->ski.gul));
tot_w += u3a_maid(fil_u, " trace stack", u3a_mark_noun(u3R->bug.tax));
tot_w += u3a_maid(fil_u, " trace buffer", u3a_mark_noun(u3R->bug.mer));
tot_w += u3a_maid(fil_u, " profile batteries", u3a_mark_noun(u3R->pro.don));
tot_w += u3a_maid(fil_u, " profile doss", u3a_mark_noun(u3R->pro.day));
tot_w += u3a_maid(fil_u, " new profile trace", u3a_mark_noun(u3R->pro.trace));
tot_w += u3a_maid(fil_u, " memoization cache", u3h_mark(u3R->cax.har_p));
return u3a_maid(fil_u, "total road stuff", tot_w);
}
/* _ca_print_box(): heuristically print the contents of an allocation box.
*/
static c3_c*
_ca_print_box(u3a_box* box_u)
{
// the loom offset pointing to the contents of box_u
//
c3_w box_w = u3a_outa(u3a_boxto(box_u));
// box_u might not be a cell, we use the struct to inspect further
//
u3a_cell* cel_u = (u3a_cell*)box_u;
if ( // a cell will never be bigger than the minimum allocation size
//
(u3a_minimum < box_u->siz_w) ||
// this condition being true potentially corresponds to
// box_u containing an indirect atom of only one word.
// if the condition is false, we know box_u contains a cell.
//
( (1 == (c3_w)cel_u->hed) &&
(0x80000000 & (c3_w)cel_u->tel) ) )
{
// box_u might not be an indirect atom,
// but it's always safe to print it as if it is one
//
u3a_atom* vat_u = (u3a_atom*)box_u;
u3_atom veb = u3a_to_pug(box_w);
// skip atoms larger than 10 words
// XX print mugs or something
//
if ( 10 > vat_u->len_w ) {
#if 0
/* For those times when you've really just got to crack open
* the box and see what's inside
*/
{
int i;
for ( i = 0; i < box_u->siz_w; i++ ) {
printf("%08x ", (unsigned int)(((c3_w*)box_u)[i]));
}
printf("\r\n");
}
#endif
return 0;
}
return u3m_pretty(veb);
}
else {
// box_u is definitely a cell
//
return u3m_pretty(u3a_to_pom(box_w));
}
}
/* _ca_print_leak(): print the details of a leaked allocation box.
*/
#ifdef U3_MEMORY_DEBUG
static void
_ca_print_leak(c3_c* cap_c, u3a_box* box_u, c3_w eus_w, c3_w use_w)
{
fprintf(stderr, "%s: %p mug=%x (marked=%u swept=%u)\r\n",
cap_c,
box_u,
((u3a_noun *)(u3a_boxto(box_u)))->mug_w,
eus_w,
use_w);
if ( box_u->cod_w ) {
u3m_p(" code", box_u->cod_w);
}
u3a_print_memory(stderr, " size", box_u->siz_w);
{
c3_c* dat_c = _ca_print_box(box_u);
fprintf(stderr, " data: %s\r\n", dat_c);
free(dat_c);
}
}
#else
static void
_ca_print_leak(c3_c* cap_c, u3a_box* box_u, c3_ws use_ws)
{
fprintf(stderr, "%s: %p mug=%x swept=%d\r\n",
cap_c,
box_u,
((u3a_noun *)(u3a_boxto(box_u)))->mug_w,
use_ws);
u3a_print_memory(stderr, " size", box_u->siz_w);
{
c3_c* dat_c = _ca_print_box(box_u);
fprintf(stderr, " data: %s\r\n", dat_c);
free(dat_c);
}
}
#endif
/* u3a_sweep(): sweep a fully marked road.
*/
c3_w
@ -1700,7 +1831,7 @@ u3a_sweep(void)
/* I suspect these printfs fail hilariously in the case
* of non-direct atoms. We shouldn't unconditionally run
* u3a_to_pom(). In general, the condition
* box_u->siz_w > u3a_mimimum is sufficient, but not necessary,
* box_u->siz_w > u3a_minimum is sufficient, but not necessary,
* for the box to represent an atom. The atoms between
* 2^31 and 2^32 are the exceptions.
*
@ -1711,34 +1842,20 @@ u3a_sweep(void)
if ( box_u->use_w != box_u->eus_w ) {
if ( box_u->eus_w != 0 ) {
if ( box_u->use_w == 0 ) {
printf("dank %p (%d, %d)\r\n", box_u, box_u->use_w, box_u->eus_w);
_ca_print_leak("dank", box_u, box_u->eus_w, box_u->use_w);
}
else {
printf("weak %p %x (cell) %x (%d, %d)\r\n",
box_u,
(u3_noun)u3a_to_pom(u3a_outa(u3a_boxto(box_w))),
((u3a_noun *)(u3a_boxto(box_w)))->mug_w,
box_u->use_w, box_u->eus_w);
u3a_print_memory("weak (minimum)", box_u->siz_w);
// u3m_p("weak", u3a_to_pom(u3a_outa(u3a_boxto(box_w))));
_ca_print_leak("weak", box_u, box_u->eus_w, box_u->use_w);
}
weq_w += box_u->siz_w;
}
else {
printf("leak %p %x (cell)/%x (%d)\r\n",
box_u,
(u3_noun)u3a_to_pom(u3a_outa(u3a_boxto(box_w))),
((u3a_noun *)(u3a_boxto(box_w)))->mug_w
? ((u3a_noun *)(u3a_boxto(box_w)))->mug_w
: u3r_mug(u3a_to_pom(u3a_outa(u3a_boxto(box_w)))),
box_u->use_w);
u3a_print_memory("leak (minimum)", box_u->siz_w);
// u3m_p("leak", u3a_to_pom(u3a_outa(u3a_boxto(box_w))));
_ca_print_leak("weak", box_u, box_u->eus_w, box_u->use_w);
leq_w += box_u->siz_w;
}
if ( box_u->cod_w ) {
u3m_p(" code", box_u->cod_w);
}
box_u->use_w = box_u->eus_w;
}
else {
@ -1751,25 +1868,7 @@ u3a_sweep(void)
c3_ws use_ws = (c3_ws)box_u->use_w;
if ( use_ws > 0 ) {
printf("leak %p %x\r\n",
box_u,
((u3a_noun *)(u3a_boxto(box_w)))->mug_w
? ((u3a_noun *)(u3a_boxto(box_w)))->mug_w
: u3r_mug(u3a_to_pom(u3a_outa(u3a_boxto(box_w)))));
// u3a_print_memory("leak (minimum)", box_u->siz_w);
#if 0
/* For those times when you've really just got to crack open
* the box and see what's inside
*/
{
int i;
for ( i = 0; i < box_u->siz_w; i++ ) {
printf("%08x ", (unsigned int)(((c3_w*)box_u)[i]));
}
printf("\r\n");
}
#endif
_ca_print_leak("leak", box_u, use_ws);
leq_w += box_u->siz_w;
box_u->use_w = 0;
@ -1795,22 +1894,22 @@ u3a_sweep(void)
#ifdef U3_CPU_DEBUG
if ( (0 != u3R->par_p) && (u3R->all.max_w > 1000000) ) {
u3a_print_memory("available", (tot_w - pos_w));
u3a_print_memory("allocated", pos_w);
u3a_print_memory("volatile", caf_w);
u3a_print_memory(stderr, "available", (tot_w - pos_w));
u3a_print_memory(stderr, "allocated", pos_w);
u3a_print_memory(stderr, "volatile", caf_w);
u3a_print_memory("maximum", u3R->all.max_w);
u3a_print_memory(stderr, "maximum", u3R->all.max_w);
}
#else
#if 0
u3a_print_memory("available", (tot_w - pos_w));
u3a_print_memory("allocated", pos_w);
u3a_print_memory("volatile", caf_w);
u3a_print_memory(stderr, "available", (tot_w - pos_w));
u3a_print_memory(stderr, "allocated", pos_w);
u3a_print_memory(stderr, "volatile", caf_w);
#endif
#endif
#endif
u3a_print_memory("leaked", leq_w);
u3a_print_memory("weaked", weq_w);
u3a_print_memory(stderr, "leaked", leq_w);
u3a_print_memory(stderr, "weaked", weq_w);
c3_assert((pos_w + leq_w + weq_w) == neg_w);

View File

@ -165,9 +165,9 @@ u3e_fault(void* adr_v, c3_i ser_i)
/* _ce_image_open(): open or create image.
*/
static c3_o
_ce_image_open(u3e_image* img_u, c3_o nuu_o)
_ce_image_open(u3e_image* img_u)
{
c3_i mod_i = _(nuu_o) ? (O_RDWR | O_CREAT) : O_RDWR;
c3_i mod_i = O_RDWR | O_CREAT;
c3_c ful_c[8193];
snprintf(ful_c, 8192, "%s", u3P.dir_c);
@ -197,11 +197,7 @@ _ce_image_open(u3e_image* img_u, c3_o nuu_o)
c3_d pgs_d = (siz_d + (c3_d)((1 << (u3a_page + 2)) - 1)) >>
(c3_d)(u3a_page + 2);
if ( c3y == nuu_o ) {
if ( siz_d ) {
c3_assert(0);
return c3n;
}
if ( !siz_d ) {
return c3y;
}
else {
@ -775,7 +771,7 @@ u3e_save(void)
// Sync the patch files.
//
// u3a_print_memory("sync: save", 4096 * pat_u->con_u->pgs_w);
// u3a_print_memory(stderr, "sync: save", 4096 * pat_u->con_u->pgs_w);
_ce_patch_sync(pat_u);
// Verify the patch - because why not?
@ -817,7 +813,7 @@ u3e_save(void)
_ce_patch_free(pat_u);
}
/* u3e_live(): start the persistence system.
/* u3e_live(): start the checkpointing system.
*/
c3_o
u3e_live(c3_o nuu_o, c3_c* dir_c)
@ -832,29 +828,17 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
} else
#endif
{
/* Open and apply any patches.
*/
if ( _(nuu_o) ) {
if ( (c3n == _ce_image_open(&u3P.nor_u, c3y)) ||
(c3n == _ce_image_open(&u3P.sou_u, c3y)) )
{
printf("boot: image failed\r\n");
exit(1);
}
// Open image files.
//
if ( (c3n == _ce_image_open(&u3P.nor_u)) ||
(c3n == _ce_image_open(&u3P.sou_u)) )
{
printf("boot: image failed\r\n");
exit(1);
}
else {
u3_ce_patch* pat_u;
/* Open image files.
*/
{
if ( (c3n == _ce_image_open(&u3P.nor_u, c3n)) ||
(c3n == _ce_image_open(&u3P.sou_u, c3n)) )
{
fprintf(stderr, "boot: no image\r\n");
return u3e_live(c3y, dir_c);
}
}
/* Load any patch files; apply them to images.
*/
if ( 0 != (pat_u = _ce_patch_open()) ) {
@ -896,7 +880,7 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
nuu_o = c3y;
}
else {
u3a_print_memory("live: loaded",
u3a_print_memory(stderr, "live: loaded",
(u3P.nor_u.pgs_w + u3P.sou_u.pgs_w) << u3a_page);
}
}

View File

@ -2250,24 +2250,32 @@ _cj_mark_hank(u3_noun kev, void* dat)
/* u3j_mark(): mark jet state for gc.
*/
c3_w
u3j_mark(void)
u3j_mark(FILE* fil_u)
{
c3_w tot_w = 0;
tot_w += u3h_mark(u3R->jed.war_p);
tot_w += u3h_mark(u3R->jed.cod_p);
tot_w += u3h_mark(u3R->jed.han_p);
tot_w += u3h_mark(u3R->jed.bas_p);
u3h_walk_with(u3R->jed.han_p, _cj_mark_hank, &tot_w);
if ( u3R == &(u3H->rod_u) ) {
tot_w += u3h_mark(u3R->jed.hot_p);
tot_w += u3a_maid(fil_u, " warm jet state", u3h_mark(u3R->jed.war_p));
tot_w += u3a_maid(fil_u, " cold jet state", u3h_mark(u3R->jed.cod_p));
tot_w += u3a_maid(fil_u, " hank cache", u3h_mark(u3R->jed.han_p));
tot_w += u3a_maid(fil_u, " battery hash cache", u3h_mark(u3R->jed.bas_p));
{
c3_w han_w = 0;
u3h_walk_with(u3R->jed.han_p, _cj_mark_hank, &han_w);
tot_w += u3a_maid(fil_u, " call site cache", han_w);
}
return tot_w;
if ( u3R == &(u3H->rod_u) ) {
tot_w += u3a_maid(fil_u, " hot jet state", u3h_mark(u3R->jed.hot_p));
}
return u3a_maid(fil_u, "total jet stuff", tot_w);
}
/* _cj_free_hank(): free hank cache.
/* u3j_free_hank(): free an entry from the hank cache.
*/
static void
_cj_free_hank(u3_noun kev)
void
u3j_free_hank(u3_noun kev)
{
_cj_hank* han_u = u3to(_cj_hank, u3t(kev));
if ( u3_none != han_u->hax ) {
@ -2282,7 +2290,7 @@ _cj_free_hank(u3_noun kev)
void
u3j_free(void)
{
u3h_walk(u3R->jed.han_p, _cj_free_hank);
u3h_walk(u3R->jed.han_p, u3j_free_hank);
u3h_free(u3R->jed.war_p);
u3h_free(u3R->jed.cod_p);
u3h_free(u3R->jed.han_p);

View File

@ -491,18 +491,13 @@ _pave_parts(void)
/* u3m_mark(): mark all nouns in the road.
*/
c3_w
u3m_mark(void)
u3m_mark(FILE* fil_u)
{
c3_w tot_w = 0;
tot_w += u3j_mark();
tot_w += u3n_mark();
tot_w += u3a_mark_noun(u3R->ski.gul);
tot_w += u3a_mark_noun(u3R->bug.tax);
tot_w += u3a_mark_noun(u3R->bug.mer);
tot_w += u3a_mark_noun(u3R->pro.don);
tot_w += u3a_mark_noun(u3R->pro.trace);
tot_w += u3a_mark_noun(u3R->pro.day);
tot_w += u3h_mark(u3R->cax.har_p);
tot_w += u3v_mark(fil_u);
tot_w += u3j_mark(fil_u);
tot_w += u3n_mark(fil_u);
tot_w += u3a_mark_road(fil_u);
return tot_w;
}
@ -932,7 +927,7 @@ u3m_soft_top(c3_w sec_w, // timer seconds
if ( u3C.wag_w & u3o_debug_ram ) {
#ifdef U3_CPU_DEBUG
if ( u3R->all.max_w > 1000000 ) {
u3a_print_memory("execute: top", u3R->all.max_w);
u3a_print_memory(stderr, "execute: top", u3R->all.max_w);
}
#endif
u3m_grab(pro, u3_none);
@ -1029,7 +1024,7 @@ u3m_soft_run(u3_noun gul,
#ifdef U3_CPU_DEBUG
if ( u3R->all.max_w > 1000000 ) {
u3a_print_memory("execute: run", u3R->all.max_w);
u3a_print_memory(stderr, "execute: run", u3R->all.max_w);
}
#endif
/* Produce success, on the old road.
@ -1151,8 +1146,7 @@ u3m_grab(u3_noun som, ...) // terminate with u3_none
// u3h_free(u3R->cax.har_p);
// u3R->cax.har_p = u3h_new();
u3v_mark();
u3m_mark();
u3m_mark(0);
{
va_list vap;
u3_noun tur;
@ -1186,28 +1180,43 @@ u3m_soft(c3_w sec_w,
if ( 0 == u3h(why) ) {
return why;
} else {
u3_noun tax, cod, pro, mok;
}
else {
// don't use .^ at the top level!
//
c3_assert(1 != u3h(why));
c3_assert(1 != u3h(why)); // don't use .^ at the top level!
if ( 2 == u3h(why) ) {
cod = c3__exit;
tax = u3k(u3t(why));
}
else {
c3_assert(3 == u3h(why));
cod = u3k(u3h(u3t(why)));
tax = u3k(u3t(u3t(why)));
// don't call +mook if we have no kernel
//
// This is required to soft the boot sequence.
// XX produce specific error motes instead of %2?
//
if ( 0 == u3A->roc ) {
u3z(why);
return u3nc(2, u3_nul);
}
mok = u3dc("mook", 2, tax);
pro = u3nc(cod, u3k(u3t(mok)));
else {
u3_noun tax, cod, pro, mok;
u3z(mok);
u3z(why);
if ( 2 == u3h(why) ) {
cod = c3__exit;
tax = u3k(u3t(why));
}
else {
c3_assert(3 == u3h(why));
return pro;
cod = u3k(u3h(u3t(why)));
tax = u3k(u3t(u3t(why)));
}
mok = u3dc("mook", 2, tax);
pro = u3nc(cod, u3k(u3t(mok)));
u3z(mok);
u3z(why);
return pro;
}
}
}
@ -1486,10 +1495,10 @@ _cm_signals(void)
}
}
/* u3m_init(): start the environment, with/without checkpointing.
/* u3m_init(): start the environment.
*/
void
u3m_init(c3_o chk_o)
u3m_init(void)
{
_cm_limits();
_cm_signals();
@ -1506,7 +1515,7 @@ u3m_init(c3_o chk_o)
map_v = mmap((void *)u3_Loom,
len_w,
_(chk_o) ? PROT_READ : (PROT_READ | PROT_WRITE),
(PROT_READ | PROT_WRITE),
(MAP_ANON | MAP_FIXED | MAP_PRIVATE),
-1, 0);
@ -1518,7 +1527,7 @@ u3m_init(c3_o chk_o)
-1, 0);
fprintf(stderr, "boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024)));
fprintf(stderr, "see urbit.org/docs/using/install for adding swap space\r\n");
fprintf(stderr, "see urbit.org/docs/getting-started#swap for adding swap space\r\n");
if ( -1 != (c3_ps)map_v ) {
fprintf(stderr,
"if porting to a new platform, try U3_OS_LoomBase %p\r\n",
@ -1685,7 +1694,7 @@ u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c,
{
/* Activate the loom.
*/
u3m_init(nuu_o);
u3m_init();
/* Activate the storage system.
*/
@ -1714,13 +1723,32 @@ u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c,
printf("boot: loading %s\r\n", ful_c);
{
u3_noun sys = u3ke_cue(u3m_file(ful_c));
u3_noun bot;
u3_noun pil = u3m_file(ful_c);
u3_noun sys, bot;
{
u3_noun pro = u3m_soft(0, u3ke_cue, u3k(pil));
if ( 0 != u3h(pro) ) {
fprintf(stderr, "boot: failed: unable to parse pill\r\n");
exit(1);
}
sys = u3k(u3t(pro));
u3z(pro);
}
// XX confirm trel of lists?
//
if ( c3n == u3r_trel(sys, &bot, 0, 0) ) {
fprintf(stderr, "boot: failed: obsolete pill structure\r\n");
exit(1);
}
u3x_trel(sys, &bot, 0, 0);
u3v_boot(u3k(bot));
u3z(sys);
u3z(pil);
}
}
else {
@ -1729,3 +1757,44 @@ u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c,
u3n_ream();
}
}
/* u3m_reclaim: clear persistent caches to reclaim memory
*/
void
u3m_reclaim(void)
{
// clear the u3v_wish cache
//
u3z(u3A->yot);
u3A->yot = u3_nul;
// clear the memoization cache
//
u3h_free(u3R->cax.har_p);
u3R->cax.har_p = u3h_new();
// clear the jet battery hash cache
//
u3h_free(u3R->jed.bas_p);
u3R->jed.bas_p = u3h_new();
// XX we can't clear the warm jet state
// -- _cj_nail expects it to be present ...
//
// u3h_free(u3R->jed.war_p);
// u3R->jed.war_p = u3h_new();
// clear the jet hank cache
//
u3h_walk(u3R->jed.han_p, u3j_free_hank);
u3h_free(u3R->jed.han_p);
u3R->jed.han_p = u3h_new();
// clear the bytecode cache
//
// We can't just u3h_free() -- the value is a post to a u3n_prog.
// Note that this requires that the hank cache also be freed.
//
u3n_free();
u3R->byc.har_p = u3h_new();
}

View File

@ -2556,15 +2556,18 @@ _n_bam(u3_noun kev, void* dat)
/* u3n_mark(): mark the bytecode cache for gc.
*/
c3_w
u3n_mark()
u3n_mark(FILE* fil_u)
{
c3_w bam_w = 0;
c3_w bam_w = 0, har_w = 0;
u3p(u3h_root) har_p = u3R->byc.har_p;
u3h_walk_with(har_p, _n_bam, &bam_w);
return bam_w + u3h_mark(har_p);
bam_w = u3a_maid(fil_u, " bytecode programs", bam_w);
har_w = u3a_maid(fil_u, " bytecode cache", u3h_mark(har_p));
return u3a_maid(fil_u, "total nock stuff", bam_w + har_w);
}
/* _n_feb(): u3h_walk helper for u3n_bree
/* _n_feb(): u3h_walk helper for u3n_free
*/
static void
_n_feb(u3_noun kev)

View File

@ -3,7 +3,10 @@
** This file is in the public domain.
*/
#include "all.h"
#include "vere/vere.h"
#include <pthread.h>
#include <time.h>
#include <sys/stat.h>
static c3_o _ct_lop_o;
@ -298,43 +301,54 @@ u3t_flee(void)
u3z(don);
}
static FILE* trace_file_u = NULL;
static int nock_pid_i = 0;
/* u3t_trace_open(): opens a trace file and writes the preamble.
*/
void
u3t_trace_open(c3_c* trace_file_name)
u3t_trace_open()
{
printf("trace: tracing to %s\n", trace_file_name);
trace_file_u = fopen(trace_file_name, "w");
nock_pid_i = (int)getpid();
fprintf(trace_file_u, "[ ");
c3_c fil_c[2048];
snprintf(fil_c, 2048, "%s/.urb/put/trace", u3_Host.dir_c);
struct stat st;
if ( -1 == stat(fil_c, &st) ) {
mkdir(fil_c, 0700);
}
c3_c * wen_c = u3r_string(u3A->wen);
c3_c lif_c[2048];
snprintf(lif_c, 2048, "%s/%s.json", fil_c, wen_c);
free(wen_c);
u3_Host.tra_u.fil_u = fopen(lif_c, "w");
u3_Host.tra_u.nid_w = (int)getpid();
fprintf(u3_Host.tra_u.fil_u, "[ ");
// We have two "threads", the event processing and the nock stuff.
// tid 1 = event processing
// tid 2 = nock processing
fprintf(
trace_file_u,
fprintf(u3_Host.tra_u.fil_u,
"{\"name\": \"process_name\", \"ph\": \"M\", \"pid\": %d, \"args\": "
"{\"name\": \"urbit\"}},\n",
nock_pid_i);
fprintf(trace_file_u,
u3_Host.tra_u.nid_w);
fprintf(u3_Host.tra_u.fil_u,
"{\"name\": \"thread_name\", \"ph\": \"M\", \"pid\": %d, \"tid\": 1, "
"\"args\": {\"name\": \"Event Processing\"}},\n",
nock_pid_i);
fprintf(trace_file_u,
u3_Host.tra_u.nid_w);
fprintf(u3_Host.tra_u.fil_u,
"{\"name\": \"thread_sort_index\", \"ph\": \"M\", \"pid\": %d, "
"\"tid\": 1, \"args\": {\"sort_index\": 1}},\n",
nock_pid_i);
fprintf(trace_file_u,
u3_Host.tra_u.nid_w);
fprintf(u3_Host.tra_u.fil_u,
"{\"name\": \"thread_name\", \"ph\": \"M\", \"pid\": %d, \"tid\": 2, "
"\"args\": {\"name\": \"Nock\"}},\n",
nock_pid_i);
fprintf(trace_file_u,
u3_Host.tra_u.nid_w);
fprintf(u3_Host.tra_u.fil_u,
"{\"name\": \"thread_sort_index\", \"ph\": \"M\", \"pid\": %d, "
"\"tid\": 2, \"args\": {\"sort_index\": 2}},\n",
nock_pid_i);
u3_Host.tra_u.nid_w);
u3_Host.tra_u.con_w = 5;
}
/* u3t_trace_close(): closes a trace file. optional.
@ -342,11 +356,12 @@ u3t_trace_open(c3_c* trace_file_name)
void
u3t_trace_close()
{
if (!trace_file_u)
if (!u3_Host.tra_u.fil_u)
return;
// We don't terminate the JSON because of the file format.
fclose(trace_file_u);
fclose(u3_Host.tra_u.fil_u);
u3_Host.tra_u.con_w = 0;
}
/* u3t_trace_time(): microsecond clock
@ -365,7 +380,7 @@ c3_d u3t_trace_time()
c3_o
u3t_nock_trace_push(u3_noun lab)
{
if (!trace_file_u)
if (!u3_Host.tra_u.fil_u)
return c3n;
if ( (u3_nul == u3R->pro.trace) ||
@ -437,7 +452,7 @@ trace_pretty(u3_noun som)
void
u3t_nock_trace_pop()
{
if (!trace_file_u)
if (!u3_Host.tra_u.fil_u)
return;
u3_noun trace = u3R->pro.trace;
@ -452,16 +467,17 @@ u3t_nock_trace_pop()
if (duration > 33) {
c3_c* name = trace_pretty(lab);
fprintf(trace_file_u,
fprintf(u3_Host.tra_u.fil_u,
"{\"cat\": \"nock\", \"name\": \"%s\", \"ph\":\"%c\", \"pid\": %d, "
"\"tid\": 2, \"ts\": %" PRIu64 ", \"dur\": %" PRIu64 "}, \n",
name,
'X',
nock_pid_i,
u3_Host.tra_u.nid_w,
start_time,
duration);
free(name);
u3_Host.tra_u.con_w++;
}
u3z(trace);
@ -472,16 +488,17 @@ u3t_nock_trace_pop()
void
u3t_event_trace(const c3_c* name, c3_c type)
{
if (!trace_file_u)
if (!u3_Host.tra_u.fil_u)
return;
fprintf(trace_file_u,
fprintf(u3_Host.tra_u.fil_u,
"{\"cat\": \"event\", \"name\": \"%s\", \"ph\":\"%c\", \"pid\": %d, "
"\"tid\": 1, \"ts\": %" PRIu64 ", \"id\": \"0x100\"}, \n",
name,
type,
nock_pid_i,
u3_Host.tra_u.nid_w,
u3t_trace_time());
u3_Host.tra_u.con_w++;
}
extern FILE*
@ -578,6 +595,12 @@ u3t_boot(void)
if ( u3C.wag_w & u3o_debug_cpu ) {
_ct_lop_o = c3n;
#if defined(U3_OS_osx) || defined(U3_OS_linux)
// skip profiling if we don't yet have an arvo kernel
//
if ( 0 == u3A->roc ) {
return;
}
// Register _ct_sigaction to be called on `SIGPROF`.
{
struct sigaction sig_s = {{0}};

View File

@ -29,16 +29,35 @@ _cv_nock_wish(u3_noun txt)
void
u3v_boot(u3_noun eve)
{
u3_noun cor;
// ensure zero-initialized kernel
//
// So that u3t_slog won't try to print tanks.
//
u3A->roc = 0;
// lifecycle formula
//
u3_noun lyf = u3nt(2, u3nc(0, 3), u3nc(0, 2));
u3_noun cor = u3n_nock_on(eve, lyf);
{
// default namespace function: |=(a/{* *} ~)
//
u3_noun gul = u3nt(u3nt(1, 0, 0), 0, 0);
// lifecycle formula
//
u3_noun lyf = u3nt(2, u3nc(0, 3), u3nc(0, 2));
// evalute lifecycle formula against the boot sequence
// in a virtualization context
//
u3_noun pro = u3m_soft_run(gul, u3n_nock_on, eve, lyf);
if ( 0 != u3h(pro) ) {
fprintf(stderr, "boot: failed: invalid boot sequence (from pill)\r\n");
u3z(pro);
return;
}
cor = u3k(u3t(pro));
u3z(pro);
}
// save the Arvo core (at +7 of the Arvo gate)
//
@ -83,6 +102,9 @@ u3v_start(u3_noun now)
printf("arvo: time: %s\n", wen_c);
free(wen_c);
}
if ( u3C.wag_w & u3o_trace )
u3t_trace_open();
}
/* u3v_wish(): text expression with cache.
@ -405,24 +427,19 @@ _cv_mark_ova(u3p(u3v_cart) egg_p)
/* u3v_mark(): mark arvo kernel.
*/
c3_w
u3v_mark(void)
u3v_mark(FILE* fil_u)
{
u3v_arvo* arv_u = &(u3H->arv_u);
c3_w tot_w = 0;
u3v_arvo* arv_u = &(u3H->arv_u);
tot_w += u3a_mark_noun(arv_u->yot);
tot_w += u3a_mark_noun(arv_u->now);
tot_w += u3a_mark_noun(arv_u->wen);
tot_w += u3a_mark_noun(arv_u->sen);
tot_w += u3a_mark_noun(arv_u->own);
tot_w += u3a_mark_noun(arv_u->roe);
tot_w += u3a_mark_noun(arv_u->key);
tot_w += u3a_mark_noun(arv_u->roc);
tot_w += _cv_mark_ova(arv_u->ova.egg_p);
return tot_w;
tot_w += u3a_maid(fil_u, " wish cache", u3a_mark_noun(arv_u->yot));
tot_w += u3a_maid(fil_u, " date", u3a_mark_noun(arv_u->now));
tot_w += u3a_maid(fil_u, " formatted date", u3a_mark_noun(arv_u->wen));
tot_w += u3a_maid(fil_u, " instance string", u3a_mark_noun(arv_u->sen));
tot_w += u3a_maid(fil_u, " identity", u3a_mark_noun(arv_u->own));
tot_w += u3a_maid(fil_u, " pending events", u3a_mark_noun(arv_u->roe));
tot_w += u3a_maid(fil_u, " event-log key", u3a_mark_noun(arv_u->key));
tot_w += u3a_maid(fil_u, " kernel", u3a_mark_noun(arv_u->roc));
tot_w += u3a_maid(fil_u, " egg basket", _cv_mark_ova(arv_u->ova.egg_p));
return u3a_maid(fil_u, "total arvo stuff", tot_w);
}

1
subprojects/libent Submodule

@ -0,0 +1 @@
Subproject commit fe9f8a8aad6c4a6915ff8844850e64be4b4831a2

View File

@ -5,7 +5,7 @@
static void
_setup(void)
{
u3m_init(c3y);
u3m_init();
u3m_pave(c3y, c3n);
}

View File

@ -26,7 +26,7 @@ main(int argc, char* argv[])
static void
_setup(void)
{
u3m_init(c3y);
u3m_init();
u3m_pave(c3y, c3n);
}

View File

@ -254,7 +254,7 @@ main(int argc, char *argv[])
printf("hello, world: len %dMB\n", (1 << U3_OS_LoomBits) >> 18);
// _test_words();
u3m_init(c3n);
u3m_init();
u3m_pave(c3y, c3n);
// u3j_boot();

View File

@ -194,7 +194,17 @@ _ames_czar(u3_pact* pac_u, c3_c* bos_c)
return;
}
c3_assert( 0 != bos_c );
// if we don't have a galaxy domain, no-op
//
if ( 0 == bos_c ) {
u3_noun nam = u3dc("scot", 'p', pac_u->imp_y);
c3_c* nam_c = u3r_string(nam);
fprintf(stderr, "ames: no galaxy domain for %s, no-op\r\n", nam_c);
free(nam_c);
u3z(nam);
return;
}
time_t now = time(0);

View File

@ -380,12 +380,6 @@ _lo_time(void)
void
u3_lo_open(void)
{
if ( u3C.wag_w & (u3o_debug_ram | u3o_check_corrupt) ) {
//
// Assumption: there are no noun roots outside u3A.
//
u3m_grab(u3_none);
}
#if 0
if ( u3C.wag_w & u3o_debug_cpu ) {
struct itimerval itm_u;
@ -398,6 +392,7 @@ u3_lo_open(void)
itm_u.it_interval.tv_usec);
}
#endif
_lo_time();
}
@ -406,20 +401,14 @@ u3_lo_open(void)
void
u3_lo_shut(c3_o inn)
{
// u3m_grab(u3_none);
// process actions
//
u3_raft_work();
// u3_lo_grab("lo_shut b", u3_none);
// update time
//
_lo_time();
// u3_lo_grab("lo_shut c", u3_none);
// for input operations, poll fs (XX not permanent)
// XX remove raty_lead guard
//
@ -429,15 +418,12 @@ u3_lo_shut(c3_o inn)
_lo_time();
}
// u3_lo_grab("lo_shut d", u3_none);
// clean shutdown
//
if ( c3n == u3_Host.liv ) {
// direct save and die
//
u3_raft_play();
// u3_lo_grab("lo_exit", u3_none);
// u3_loom_save(u3A->ent_d);
// u3_loom_exit();
u3t_damp();
@ -663,129 +649,3 @@ u3_lo_lead(void)
_lo_slow();
#endif
}
#if 0
/* _lo_mark_reck(): mark a reck.
*/
static c3_w
_lo_mark_reck(u3_reck* rec_u)
{
c3_w siz_w = 0;
c3_w egg_w;
siz_w += u3m_mark_noun(rec_u->ken);
siz_w += u3m_mark_noun(rec_u->roc);
siz_w += u3m_mark_noun(rec_u->yot);
siz_w += u3m_mark_noun(rec_u->now);
siz_w += u3m_mark_noun(rec_u->wen);
siz_w += u3m_mark_noun(rec_u->sen);
siz_w += u3m_mark_noun(rec_u->own);
siz_w += u3m_mark_noun(rec_u->roe);
siz_w += u3m_mark_noun(rec_u->key);
{
u3_cart* egg_u;
egg_w = 0;
for ( egg_u = rec_u->ova.egg_u; egg_u; egg_u = egg_u->nex_u ) {
egg_w += u3m_mark_noun(egg_u->vir);
}
siz_w += egg_w;
}
#if 0
fprintf(stderr, "ken %d, roc %d, yot %d, roe %d, egg %d\r\n",
ken_w, roc_w, yot_w, roe_w, egg_w);
#endif
return siz_w;
}
/* _lo_mark(): mark the whole vere system.
*/
static c3_w
_lo_mark()
{
c3_w siz_w;
siz_w = u3m_mark_internal();
siz_w += _lo_mark_reck(u3_Host.arv_u);
return siz_w;
}
#endif
#if 0
/* _lo_word(): print a word to the passed stream.
*/
static void
_lo_word(FILE* fil_u, c3_w wod_w)
{
u3_noun top = c3y;
if ( wod_w / (1000 * 1000 * 1000) ) {
fprintf(fil_u, "%u.", wod_w / (1000 * 1000 * 1000));
wod_w %= (1000 * 1000 * 1000);
top = c3n;
}
if ( wod_w / (1000 * 1000) ) {
fprintf(fil_u, ((top == c3y) ? "%u." : "%03u."),
wod_w / (1000 * 1000));
wod_w %= (1000 * 1000);
top = c3n;
}
if ( wod_w / 1000 ) {
fprintf(fil_u, ((top == c3y) ? "%u." : "%03u."), wod_w / 1000);
wod_w %= 1000;
top = c3n;
}
fprintf(fil_u, ((top == c3y) ? "%u" : "%03u"), wod_w);
}
/* u3_lo_grab(): garbage-collect the world, plus roots.
*/
void
u3_lo_grab(c3_c* cap_c, u3_noun som, ...)
{
c3_w siz_w, lec_w;
siz_w = _lo_mark();
{
va_list vap;
u3_noun tur;
va_start(vap, som);
if ( som != u3_none ) {
siz_w += u3m_mark_noun(som);
while ( u3_none != (tur = va_arg(vap, u3_noun)) ) {
siz_w += u3m_mark_noun(tur);
}
}
va_end(vap);
}
lec_w = u3m_sweep(siz_w);
// if ( lec_w || (c3y == u3_Flag_Verbose) )
if ( lec_w || !strcmp("init", cap_c) ) {
FILE* fil_u = uH;
fprintf(fil_u, "%s: gc: ", cap_c);
if ( lec_w ) {
_lo_word(fil_u, 4 * lec_w);
fprintf(fil_u, " bytes shed; ");
}
_lo_word(fil_u, 4 * siz_w);
uL(fprintf(fil_u, " bytes live\n"));
#if 0
if ( lec_w ) {
uL(fprintf(uH, "zero garbage tolerance!\n"));
u3_lo_exit();
c3_assert(0);
exit(1);
}
#endif
}
u3_wire_lan(u3_Wire) = c3y;
}
#endif

View File

@ -83,6 +83,7 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.qui = c3n;
u3_Host.ops_u.rep = c3n;
u3_Host.ops_u.tex = c3n;
u3_Host.ops_u.tra = c3n;
u3_Host.ops_u.veb = c3n;
u3_Host.ops_u.kno_w = DefaultKernel;
@ -91,7 +92,7 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.nam_c = 0;
while ( -1 != (ch_i=getopt(argc, argv,
"G:B:K:A:H:w:u:j:e:E:f:F:k:m:p:LabcCdgqstvxPDRS")) ) {
"G:B:K:A:H:w:u:e:E:f:F:k:m:p:LjabcCdgqstvxPDRS")) ) {
switch ( ch_i ) {
case 'B': {
@ -131,10 +132,6 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.url_c = strdup(optarg);
break;
}
case 'j': {
u3_Host.ops_u.json_file_c = strdup(optarg);
break;
}
case 'x': {
u3_Host.ops_u.tex = c3y;
break;
@ -170,6 +167,7 @@ _main_getopt(c3_i argc, c3_c** argv)
return c3y;
}
case 'L': { u3_Host.ops_u.net = c3n; break; }
case 'j': { u3_Host.ops_u.tra = c3y; break; }
case 'a': { u3_Host.ops_u.abo = c3y; break; }
case 'b': { u3_Host.ops_u.bat = c3y; break; }
case 'c': { u3_Host.ops_u.nuu = c3y; break; }
@ -656,9 +654,11 @@ main(c3_i argc,
/* Set tracing flag
*/
if ( u3_Host.ops_u.json_file_c ) {
if ( _(u3_Host.ops_u.tra) ) {
u3C.wag_w |= u3o_trace;
u3t_trace_open(u3_Host.ops_u.json_file_c);
u3_Host.tra_u.nid_w = 0;
u3_Host.tra_u.fil_u = NULL;
u3_Host.tra_u.con_w = 0;
}
}
u3m_boot(u3_Host.ops_u.nuu,

View File

@ -2,6 +2,7 @@
**
*/
#include <uv.h>
#include <sys/stat.h>
#include "all.h"
#include "vere/vere.h"
@ -1480,74 +1481,84 @@ _raft_sure(u3_noun ovo, u3_noun vir, u3_noun cor)
static u3_weak
_raft_lame(u3_noun ovo, u3_noun why, u3_noun tan)
{
u3_noun bov, gon;
u3_noun ret;
u3_noun bov, gon, ret;
u3_noun wir, tag, cad;
u3x_trel(ovo, &wir, &tag, &cad);
#if 0
{
c3_c* oik_c = u3r_string(u3h(u3t(ovo)));
// uL(fprintf(uH, "lame: %s\n", oik_c));
free(oik_c);
c3_c* tag_c = u3r_string(tag);
uL(fprintf(uH, "lame: %s\n", tag_c));
u3_lo_show("data", u3k(u3t(u3t(ovo))));
free(tag_c);
}
#endif
// Formal error in a network packet generates a hole card.
// Formal error in a network packet generates a %hole card.
//
// There should be a separate path for crypto failures,
// to prevent timing attacks, but isn't right now. To deal
// with a crypto failure, just drop the packet.
// There should be a separate path for crypto failures,
// to prevent timing attacks, but isn't right now. To deal
// with a crypto failure, just drop the packet.
//
if ( (c3__exit == why) && (c3__hear == u3h(u3t(ovo))) ) {
u3_lo_punt(2, u3kb_flop(u3k(tan)));
bov = u3nc(u3k(u3h(ovo)), u3nc(c3__hole, u3k(u3t(u3t(ovo)))));
u3z(why);
if ( (c3__exit == why) && (c3__hear == tag) ) {
bov = u3nt(u3k(wir), c3__hole, u3k(cad));
}
// All other errors are replaced with [%crud why trace]
//
else {
bov = u3nc(u3k(u3h(ovo)), u3nt(c3__crud, why, u3k(tan)));
bov = u3nq(u3k(wir), c3__crud, u3k(why), u3k(tan));
}
// u3_lo_show("data", u3k(u3t(u3t(ovo))));
u3z(ovo);
// poke with replacement event, on the same wire
//
gon = u3m_soft(0, u3v_poke, u3k(bov));
if ( u3_blip == u3h(gon) ) {
ret = _raft_sure(bov, u3k(u3h(u3t(gon))), u3k(u3t(u3t(gon))));
u3_noun hed, tal;
u3x_trel(gon, 0, &hed, &tal);
u3z(tan);
u3z(gon);
return ret;
ret = _raft_sure(u3k(bov), u3k(hed), u3k(tal));
}
else {
u3z(gon);
{
u3_noun vab = u3nc(u3k(u3h(bov)),
u3nc(c3__warn, u3i_tape("crude crash!")));
u3_noun nog = u3m_soft(0, u3v_poke, u3k(vab));
// XX this will always fail, nothing in arvo handles %warn
//
#if 0
u3_noun vab = u3nt(u3k(u3h(bov)), c3__warn,
u3i_tape("crude crash!"));
u3_noun nog = u3m_soft(0, u3v_poke, u3k(vab));
if ( u3_blip == u3h(nog) ) {
ret = _raft_sure(vab, u3k(u3h(u3t(nog))), u3k(u3t(u3t(nog))));
u3z(tan);
u3z(nog);
return ret;
}
else {
u3z(nog);
u3z(vab);
uL(fprintf(uH, "crude: all delivery failed!\n"));
u3_lo_punt(2, u3kb_flop(u3k(tan)));
uL(fprintf(uH, "crude: punted\n"));
// c3_assert(!"crud");
return u3_none;
}
if ( u3_blip == u3h(nog) ) {
ret = _raft_sure(u3k(vab), u3k(u3h(u3t(nog))), u3k(u3t(u3t(nog))));
}
else {
#endif
ret = u3_none;
uL(fprintf(uH, "crude: all delivery failed!\n"));
{
c3_c* tag_c = u3r_string(tag);
uL(fprintf(uH, "event: %s\n", tag_c));
u3_lo_punt(2, u3kb_flop(u3k(tan)));
free(tag_c);
}
uL(fprintf(uH, "crude: punted\n"));
// c3_assert(!"crud");
#if 0
}
u3z(vab); u3z(nog);
#endif
}
u3z(ovo); u3z(why); u3z(tan);
u3z(bov); u3z(gon);
return ret;
}
/* _raft_punk(): insert and apply an input ovum (unprotected).
@ -1674,16 +1685,18 @@ _raft_kick(u3_noun vir)
/* _raft_spac(): print n spaces.
*/
void _raft_spac(c3_w n)
void _raft_spac(FILE* fil_u, c3_w n)
{
for (; n > 0; n--)
(fprintf(stderr," "));
(fprintf(fil_u," "));
}
/* _raft_print_memory: print memory amount. cf u3a_print_memory().
/* _raft_print_memory: print memory amount.
**
** Helper for _raft_prof(), just an un-captioned u3a_print_memory().
*/
void
_raft_print_memory(c3_w wor_w)
_raft_print_memory(FILE* fil_u, c3_w wor_w)
{
c3_w byt_w = (wor_w * 4);
c3_w gib_w = (byt_w / 1000000000);
@ -1692,17 +1705,17 @@ _raft_print_memory(c3_w wor_w)
c3_w bib_w = (byt_w % 1000);
if ( gib_w ) {
(fprintf(stderr, "GB/%d.%03d.%03d.%03d\r\n",
(fprintf(fil_u, "GB/%d.%03d.%03d.%03d\r\n",
gib_w, mib_w, kib_w, bib_w));
}
else if ( mib_w ) {
(fprintf(stderr, "MB/%d.%03d.%03d\r\n", mib_w, kib_w, bib_w));
(fprintf(fil_u, "MB/%d.%03d.%03d\r\n", mib_w, kib_w, bib_w));
}
else if ( kib_w ) {
(fprintf(stderr, "KB/%d.%03d\r\n", kib_w, bib_w));
(fprintf(fil_u, "KB/%d.%03d\r\n", kib_w, bib_w));
}
else {
(fprintf(stderr, "B/%d\r\n", bib_w));
(fprintf(fil_u, "B/%d\r\n", bib_w));
}
}
@ -1745,38 +1758,44 @@ _raft_prof_noun(u3p(u3h_root) hax, u3_noun non, c3_t dud)
/* _raft_prof(): print memory profile. RETAIN.
*/
c3_w
_raft_prof(u3p(u3h_root) hax, c3_w den, u3_noun mas)
_raft_prof(FILE* fil_u, c3_w den, u3_noun mas)
{
c3_w tot_w = 0;
u3_noun h_mas, t_mas;
if ( c3n == u3r_cell(mas, &h_mas, &t_mas) ) {
_raft_spac(den);
(fprintf(stderr, "mistyped mass\r\n"));
_raft_spac(fil_u, den);
fprintf(fil_u, "mistyped mass\r\n");
return tot_w;
}
else if ( _(u3du(h_mas)) ) {
_raft_spac(den);
(fprintf(stderr, "mistyped mass head\r\n"));
u3m_p("h_mas", h_mas);
_raft_spac(fil_u, den);
fprintf(fil_u, "mistyped mass head\r\n");
{
c3_c* lab_c = u3m_pretty(h_mas);
fprintf(fil_u, "h_mas: %s", lab_c);
free(lab_c);
}
return tot_w;
}
else {
_raft_spac(den);
_raft_spac(fil_u, den);
c3_c* lab_c = u3m_pretty(h_mas);
(fprintf(stderr, "%s: ", lab_c));
free(lab_c);
{
c3_c* lab_c = u3m_pretty(h_mas);
fprintf(fil_u, "%s: ", lab_c);
free(lab_c);
}
u3_noun it_mas, tt_mas;
if ( c3n == u3r_cell(t_mas, &it_mas, &tt_mas) ) {
(fprintf(stderr, "mistyped mass tail\r\n"));
fprintf(fil_u, "mistyped mass tail\r\n");
return tot_w;
}
else if ( c3y == it_mas ) {
tot_w += u3a_mark_noun(tt_mas);
_raft_print_memory(tot_w);
_raft_print_memory(fil_u, tot_w);
#if 1
/* The basic issue here is that tt_mas is included in
@ -1808,23 +1827,23 @@ _raft_prof(u3p(u3h_root) hax, c3_w den, u3_noun mas)
return tot_w;
}
else if ( c3n == it_mas ) {
(fprintf(stderr, "\r\n"));
fprintf(fil_u, "\r\n");
while ( _(u3du(tt_mas)) ) {
tot_w += _raft_prof(hax, den+2, u3h(tt_mas));
tot_w += _raft_prof(fil_u, den+2, u3h(tt_mas));
tt_mas = u3t(tt_mas);
}
_raft_spac(den);
(fprintf(stderr, "--"));
_raft_print_memory(tot_w);
_raft_spac(fil_u, den);
fprintf(fil_u, "--");
_raft_print_memory(fil_u, tot_w);
return tot_w;
}
else {
_raft_spac(den);
(fprintf(stderr, "mistyped (strange) mass tail\r\n"));
_raft_spac(fil_u, den);
fprintf(fil_u, "mistyped (strange) mass tail\r\n");
return tot_w;
}
}
@ -1833,85 +1852,80 @@ _raft_prof(u3p(u3h_root) hax, c3_w den, u3_noun mas)
/* _raft_grab(): garbage collect, checking for profiling. RETAIN.
*/
static void
_raft_grab(u3_noun ova)
_raft_grab(u3_noun rus)
{
if ( u3_nul != u3A->sac ) {
c3_w usr_w = 0, ova_w = 0, sac_w = 0, utv_w = 0, utm_w = 0, wep_w = 0,
har_w = 0, das_w = 0, gul_w = 0, tax_w = 0, mer_w = 0, don_w = 0,
day_w = 0, car_w = 0;
if ( u3_nul == u3A->sac) {
if ( u3C.wag_w & (u3o_debug_ram | u3o_check_corrupt) ) {
u3m_grab(rus, u3_none);
}
}
else {
c3_w usr_w = 0, man_w = 0, ova_w = 0, sac_w = 0;
FILE* fil_u;
#ifdef U3_MEMORY_LOG
{
c3_c* wen_c = u3r_string(u3A->wen);
c3_c nam_c[2048];
snprintf(nam_c, 2048, "%s/.urb/put/mass", u3_Host.dir_c);
struct stat st;
if ( -1 == stat(nam_c, &st) ) {
mkdir(nam_c, 0700);
}
c3_c man_c[2048];
snprintf(man_c, 2048, "%s/%s.txt", nam_c, wen_c);
fil_u = fopen(man_c, "w");
fprintf(fil_u, "%s\r\n", wen_c);
free(wen_c);
}
#else
{
fil_u = stderr;
}
#endif
c3_assert( u3R == &(u3H->rod_u) );
fprintf(stderr, "\r\n");
usr_w = _raft_prof(u3_nul, 0, u3A->sac);
fprintf(stderr, "total userspace: ");
_raft_print_memory(usr_w);
fprintf(fil_u, "\r\n");
usr_w = _raft_prof(fil_u, 0, u3A->sac);
u3a_print_memory(fil_u, "total userspace", usr_w);
ova_w = u3a_mark_noun(ova);
fprintf(stderr, "effects list: ");
_raft_print_memory(ova_w);
man_w = u3m_mark(fil_u);
ova_w = u3a_mark_noun(rus);
u3a_print_memory(fil_u, "event & effects", ova_w);
sac_w = u3a_mark_noun(u3A->sac);
fprintf(stderr, "space profile: ");
_raft_print_memory(sac_w);
u3a_print_memory(fil_u, "space profile", sac_w);
utv_w = u3v_mark();
fprintf(stderr, "arvo stuff: ");
_raft_print_memory(utv_w);
u3a_print_memory(fil_u, "total marked", usr_w + man_w + ova_w + sac_w);
har_w = u3h_mark(u3R->jed.war_p);
fprintf(stderr, " warm jet state: ");
_raft_print_memory(har_w);
u3a_print_memory(fil_u, "sweep", u3a_sweep());
das_w = u3h_mark(u3R->jed.cod_p);
fprintf(stderr, " cold jet state: ");
_raft_print_memory(das_w);
#ifdef U3_MEMORY_LOG
{
fclose(fil_u);
}
#endif
gul_w = u3a_mark_noun(u3R->ski.gul);
fprintf(stderr, " namespace: ");
_raft_print_memory(gul_w);
tax_w = u3a_mark_noun(u3R->bug.tax);
fprintf(stderr, " trace stack list: ");
_raft_print_memory(tax_w);
mer_w = u3a_mark_noun(u3R->bug.mer);
fprintf(stderr, " trace stack buffer: ");
_raft_print_memory(mer_w);
don_w = u3a_mark_noun(u3R->pro.don);
fprintf(stderr, " profile battery list: ");
_raft_print_memory(don_w);
day_w = u3a_mark_noun(u3R->pro.day);
fprintf(stderr, " profile doss: ");
_raft_print_memory(day_w);
car_w = u3h_mark(u3R->cax.har_p);
fprintf(stderr, " memoization: ");
_raft_print_memory(car_w);
utm_w = har_w + das_w + gul_w + tax_w + mer_w + don_w + day_w + car_w;
fprintf(stderr, "total road stuff: ");
_raft_print_memory(utm_w);
fprintf(stderr, "total marked: ");
_raft_print_memory(usr_w + ova_w + sac_w + utv_w + utm_w);
wep_w = u3a_sweep();
fprintf(stderr, "sweep: ");
_raft_print_memory(wep_w);
u3h_free(u3R->cax.har_p);
u3R->cax.har_p = u3h_new();
// u3h_free(u3R->cax.har_p);
// u3R->cax.har_p = u3h_new();
u3z(u3A->sac);
u3A->sac = u3_nul;
// restore prompt
//
uL(fprintf(uH, "\n"));
}
}
int FOO;
/* _raft_crop(): Delete finished events.
*/
static void
@ -2039,6 +2053,11 @@ _raft_pump(u3_noun ovo)
void
u3_raft_chip(void)
{
if ( (u3C.wag_w & u3o_trace) && (u3_Host.tra_u.con_w >= 100000) ) {
u3t_trace_close();
u3t_trace_open();
}
u3_weak rus = _raft_poke();
_raft_crop();
@ -2052,10 +2071,14 @@ u3_raft_chip(void)
}
_raft_kick(u3k(vir));
_raft_grab(vir);
_raft_grab(rus);
u3z(rus);
}
if ( 0 == (u3A->ent_d % 1000ULL) ) {
u3m_reclaim();
}
}
/* u3_raft_play(): synchronously process events.

View File

@ -357,7 +357,9 @@ _reck_kick_norm(u3_noun pox, u3_noun fav)
uL(fprintf(uH, "<<<reset>>>\n"));
u3z(pox); u3z(fav);
// u3_ds_wipe(u3_Wire); // doesn't work
// reclaim memory from persistent caches
//
u3m_reclaim();
return c3y;
}

View File

@ -1,6 +1,7 @@
/* vere/sist.c
**
*/
#include <ent.h>
#include <errno.h>
#include <fcntl.h>
#include <uv.h>
@ -14,10 +15,14 @@ c3_d
u3_sist_pack(c3_w tem_w, c3_w typ_w, c3_w* bob_w, c3_w len_w)
{
u3_ulog* lug_u = &u3Z->lug_u;
c3_d hed_d;
c3_d ven_d;
c3_d tar_d;
u3_ular lar_u;
tar_d = lug_u->len_d + len_w;
hed_d = lug_u->len_d;
ven_d = hed_d + c3_wiseof(c3_w);
tar_d = ven_d + (c3_d)len_w;
lar_u.tem_w = tem_w;
lar_u.typ_w = typ_w;
@ -29,6 +34,8 @@ u3_sist_pack(c3_w tem_w, c3_w typ_w, c3_w* bob_w, c3_w len_w)
u3A->ent_d++;
lar_u.len_w = len_w;
// write trailer
//
if ( -1 == lseek64(lug_u->fid_i, 4ULL * tar_d, SEEK_SET) ) {
uL(fprintf(uH, "sist: seek failed, lseek: %s\n", strerror(errno)));
c3_assert(0);
@ -37,7 +44,19 @@ u3_sist_pack(c3_w tem_w, c3_w typ_w, c3_w* bob_w, c3_w len_w)
uL(fprintf(uH, "sist: write failed, write: %s\n", strerror(errno)));
c3_assert(0);
}
if ( -1 == lseek64(lug_u->fid_i, 4ULL * lug_u->len_d, SEEK_SET) ) {
// write header (just a size)
//
if ( -1 == lseek64(lug_u->fid_i, 4ULL * hed_d, SEEK_SET) ) {
uL(fprintf(uH, "sist: seek failed, lseek: %s\n", strerror(errno)));
c3_assert(0);
}
if ( sizeof(c3_w) != write(lug_u->fid_i, &len_w, sizeof(c3_w)) ) {
uL(fprintf(uH, "sist: write failed, write: %s\n", strerror(errno)));
c3_assert(0);
}
// write the event in between the header and trailer
//
if ( -1 == lseek64(lug_u->fid_i, 4ULL * ven_d, SEEK_SET) ) {
uL(fprintf(uH, "sist: seek failed, lseek: %s\n", strerror(errno)));
c3_assert(0);
}
@ -53,7 +72,7 @@ u3_sist_pack(c3_w tem_w, c3_w typ_w, c3_w* bob_w, c3_w len_w)
uL(fprintf(uH, "sist: write failed, write: %s\n", strerror(errno)));
c3_assert(0);
}
lug_u->len_d += (c3_d)(lar_u.len_w + c3_wiseof(lar_u));
lug_u->len_d += (c3_d)(lar_u.len_w + c3_wiseof(lar_u) + c3_wiseof(c3_w));
free(bob_w);
// Sync. Or, what goes by sync.
@ -189,40 +208,68 @@ u3_sist_nil(const c3_c* key_c)
/* _sist_suck(): past failure.
*/
static void
_sist_suck(u3_noun ovo, u3_noun gon)
_sist_suck(c3_d evt_d, u3_noun ovo, u3_noun gon)
{
uL(fprintf(uH, "sing: ovum failed!\n"));
fprintf(stderr, "sing: ovum failed!\r\n");
{
c3_c* hed_c = u3r_string(u3h(u3t(ovo)));
uL(fprintf(uH, "fail %s\n", hed_c));
fprintf(stderr, "sing: fail: %s event %lld mug %u\r\n",
hed_c, evt_d, u3r_mug(ovo));
free(hed_c);
}
u3_lo_punt(2, u3kb_flop(u3k(u3t(gon))));
// u3_loom_exit();
#if 1
u3_lo_exit();
{
u3_noun why;
u3x_cell(gon, &why, 0);
u3m_p("sist: why", why);
}
exit(1);
#else
u3z(ovo); u3z(gon);
u3_lo_punt(2, u3kb_flop(u3k(u3t(gon))));
#if 1
{
c3_c fil_c[2048];
snprintf(fil_c, 2048, "%s/.urb/put/failed-%lld.jam", u3_Host.dir_c, evt_d);
u3_noun pat = u3qe_jam(ovo);
fprintf(stderr, "sing: saving failed event\r\n");
u3_walk_save(fil_c, u3_nul, pat, 0, u3_nul);
}
#endif
#if 1
{
fprintf(stderr, "sing: saving checkpoint\r\n");
c3_d old_d = u3A->ent_d;
u3A->ent_d = evt_d - 1ULL;
u3e_save();
u3A->ent_d = old_d;
}
#endif
#if 1
u3_lo_bail();
#endif
}
/* _sist_sing(): replay ovum from the past, time already set.
*/
static void
_sist_sing(u3_noun ovo)
_sist_sing(c3_d evt_d, u3_noun ovo)
{
u3t_event_trace("Running", 'b');
u3_noun gon = u3m_soft(0, u3v_poke, u3k(ovo));
u3t_event_trace("Running", 'e');
{
u3_noun hed, tal;
u3x_cell(gon, &hed, &tal);
if ( u3_blip != hed ) {
_sist_suck(ovo, gon);
_sist_suck(evt_d, ovo, gon);
}
else {
u3_noun vir, cor;
@ -241,7 +288,7 @@ _sist_sing(u3_noun ovo)
if ( c3__init == u3h(fav) ) {
u3A->own = u3k(u3t(fav));
u3A->fak = ( c3__fake == u3h(tag) ) ? c3y : c3n;
u3A->fak = ( c3__fake == u3h(dat) ) ? c3y : c3n;
}
vir = u3t(vir);
@ -406,7 +453,7 @@ _sist_bask(c3_c* pop_c, u3_noun may)
void
c3_rand(c3_w* rad_w)
{
if ( 0 != c3_getentropy(rad_w, 64) ) {
if ( 0 != ent_getentropy(rad_w, 64) ) {
uL(fprintf(uH, "c3_rand getentropy: %s\n", strerror(errno)));
u3_lo_bail();
}
@ -553,7 +600,7 @@ _sist_zest()
{
u3_uled led_u;
led_u.mag_l = u3r_mug('g');
led_u.mag_l = u3r_mug('h');
led_u.kno_w = 163;
if ( 0 == u3A->key ) {
@ -586,7 +633,6 @@ static void
_sist_rest_nuu(u3_ulog* lug_u, u3_uled led_u, c3_c* old_c)
{
c3_c nuu_c[2048];
u3_noun roe = u3_nul;
c3_i fid_i = lug_u->fid_i;
c3_i fud_i;
c3_i ret_i;
@ -594,26 +640,40 @@ _sist_rest_nuu(u3_ulog* lug_u, u3_uled led_u, c3_c* old_c)
uL(fprintf(uH, "rest: converting log from prior format\n"));
c3_assert(led_u.mag_l == u3r_mug('f'));
c3_assert(led_u.mag_l == u3r_mug('g'));
if ( -1 == lseek64(fid_i, 4ULL * end_d, SEEK_SET) ) {
uL(fprintf(uH, "rest: rest_nuu failed (a), lseek64: %s\n", strerror(errno)));
ret_i = snprintf(nuu_c, 2048, "%s/.urb/ham.hope", u3_Host.dir_c);
c3_assert(ret_i < 2048);
if ( (fud_i = open(nuu_c, O_CREAT | O_TRUNC | O_RDWR, 0600)) < 0 ) {
uL(fprintf(uH, "rest: can't open record (%s), open: %s\n", nuu_c,
strerror(errno)));
u3_lo_bail();
}
led_u.mag_l = u3r_mug('h');
if ( (sizeof(led_u) != write(fud_i, &led_u, sizeof(led_u))) ) {
uL(fprintf(uH, "rest: can't write header, write: %s\n", strerror(errno)));
u3_lo_bail();
}
c3_o fir_o = c3y;
c3_d pos_d, new_d;
while ( end_d != c3_wiseof(u3_uled) ) {
c3_d tar_d;
u3_olar lar_u;
u3_ular lar_u;
c3_w* img_w;
u3_noun ron;
tar_d = (end_d - (c3_d)c3_wiseof(u3_olar));
// read trailer
//
tar_d = (end_d - (c3_d)c3_wiseof(u3_ular));
if ( -1 == lseek64(fid_i, 4ULL * tar_d, SEEK_SET) ) {
uL(fprintf(uH, "rest_nuu failed (b), lseek64: %s\n", strerror(errno)));
u3_lo_bail();
}
if ( sizeof(u3_olar) != read(fid_i, &lar_u, sizeof(u3_olar)) ) {
if ( sizeof(u3_ular) != read(fid_i, &lar_u, sizeof(u3_ular)) ) {
uL(fprintf(uH, "rest_nuu failed (c), read: %s\n", strerror(errno)));
u3_lo_bail();
}
@ -623,6 +683,16 @@ _sist_rest_nuu(u3_ulog* lug_u, u3_uled led_u, c3_c* old_c)
u3_lo_bail();
}
// calculate new log size
//
if ( c3y == fir_o ) {
pos_d = (end_d + lar_u.ent_d + 1);
new_d = pos_d;
fir_o = c3n;
}
// read event
//
img_w = c3_malloc(4 * lar_u.len_w);
end_d = (tar_d - (c3_d)lar_u.len_w);
@ -635,15 +705,50 @@ _sist_rest_nuu(u3_ulog* lug_u, u3_uled led_u, c3_c* old_c)
u3_lo_bail();
}
ron = u3i_words(lar_u.len_w, img_w);
free(img_w);
// write event trailer
//
pos_d -= (c3_d)c3_wiseof(lar_u);
if ( lar_u.mug_w != u3r_mug(ron) ) {
uL(fprintf(uH, "rest_nuu failed (g)\n"));
lar_u.syn_w = u3r_mug_chub(pos_d);
if ( -1 == lseek64(fud_i, (4ULL * pos_d), SEEK_SET) ) {
uL(fprintf(uH, "rest_nuu failed (g), lseek64: %s\n", strerror(errno)));
u3_lo_bail();
}
roe = u3nc(ron, roe);
if ( sizeof(u3_ular) != write(fud_i, &lar_u, sizeof(u3_ular)) ) {
uL(fprintf(uH, "rest_nuu failed (h), read: %s\n", strerror(errno)));
u3_lo_bail();
}
// write event
//
pos_d -= (c3_d)lar_u.len_w;
if ( -1 == lseek64(fud_i, (4ULL * pos_d), SEEK_SET) ) {
uL(fprintf(uH, "rest_nuu failed (i), lseek64: %s\n", strerror(errno)));
u3_lo_bail();
}
if ( (4 * lar_u.len_w) != write(fud_i, img_w, (4 * lar_u.len_w)) ) {
uL(fprintf(uH, "rest_nuu failed (j), read: %s\n", strerror(errno)));
u3_lo_bail();
}
// write event header
//
pos_d -= c3_wiseof(c3_w);
if ( -1 == lseek64(fud_i, (4ULL * pos_d), SEEK_SET) ) {
uL(fprintf(uH, "rest_nuu failed (k), lseek64: %s\n", strerror(errno)));
u3_lo_bail();
}
if ( 4ULL != write(fud_i, &lar_u.len_w, 4ULL) ) {
uL(fprintf(uH, "rest_nuu failed (l), read: %s\n", strerror(errno)));
u3_lo_bail();
}
free(img_w);
}
if ( 0 != close(fid_i) ) {
@ -651,61 +756,6 @@ _sist_rest_nuu(u3_ulog* lug_u, u3_uled led_u, c3_c* old_c)
u3_lo_bail();
}
ret_i = snprintf(nuu_c, 2048, "%s/.urb/ham.hope", u3_Host.dir_c);
c3_assert(ret_i < 2048);
if ( (fud_i = open(nuu_c, O_CREAT | O_TRUNC | O_RDWR, 0600)) < 0 ) {
uL(fprintf(uH, "rest: can't open record (%s), open: %s\n", nuu_c,
strerror(errno)));
u3_lo_bail();
}
led_u.mag_l = u3r_mug('g');
if ( (sizeof(led_u) != write(fud_i, &led_u, sizeof(led_u))) ) {
uL(fprintf(uH, "rest: can't write header, write: %s\n", strerror(errno)));
u3_lo_bail();
}
{
c3_d ent_d = 1;
c3_assert(end_d == c3_wiseof(u3_uled));
while ( u3_nul != roe ) {
u3_noun ovo = u3k(u3h(roe));
u3_noun nex = u3k(u3t(roe));
u3_ular lar_u;
c3_w* img_w;
c3_d tar_d;
lar_u.len_w = u3r_met(5, ovo);
tar_d = end_d + lar_u.len_w;
lar_u.syn_w = u3r_mug(tar_d);
lar_u.ent_d = ent_d;
lar_u.tem_w = 0;
lar_u.typ_w = c3__ov;
u3_noun moo = u3nt(u3k(ovo), u3_nul, c3__ov);
lar_u.mug_w = u3r_mug(moo);
u3z(moo);
img_w = c3_malloc(lar_u.len_w << 2);
u3r_words(0, lar_u.len_w, img_w, ovo);
u3z(ovo);
if ( (lar_u.len_w << 2) != write(fud_i, img_w, lar_u.len_w << 2) ) {
uL(fprintf(uH, "rest_nuu failed (h), write: %s\n", strerror(errno)));
u3_lo_bail();
}
if ( sizeof(u3_ular) != write(fud_i, &lar_u, sizeof(u3_ular)) ) {
uL(fprintf(uH, "rest_nuu failed (i), write: %s\n", strerror(errno)));
u3_lo_bail();
}
ent_d++;
end_d = tar_d + c3_wiseof(u3_ular);
u3z(roe); roe = nex;
}
}
if ( 0 != rename(nuu_c, old_c) ) {
uL(fprintf(uH, "rest_nuu failed (k), rename: %s\n", strerror(errno)));
u3_lo_bail();
@ -715,7 +765,23 @@ _sist_rest_nuu(u3_ulog* lug_u, u3_uled led_u, c3_c* old_c)
u3_lo_bail();
}
lug_u->fid_i = fud_i;
lug_u->len_d = end_d;
lug_u->len_d = new_d;
}
/* _sist_slog(): stringify an integer using a hoon atom aura
*/
static c3_c*
_sist_scot(u3_noun aura, c3_d num_d)
{
u3_noun num;
c3_c* num_c;
num = u3i_chubs(1, &num_d);
num = u3dc("scot", aura, num);
num_c = u3r_string(num);
u3z(num);
return num_c;
}
/* _sist_rest(): restore from record, or exit.
@ -726,22 +792,17 @@ _sist_rest()
struct stat buf_b;
c3_i fid_i;
c3_c ful_c[2048];
c3_d cur_d;
c3_d old_d = u3A->ent_d;
c3_d las_d = 0;
u3_noun roe = u3_nul;
u3_noun sev_l, key_l, sal_l;
u3_noun ohh = c3n;
u3_ular lar_u;
if ( 0 != u3A->ent_d ) {
u3_noun ent;
c3_c* ent_c;
ent = u3i_chubs(1, &u3A->ent_d);
ent = u3dc("scot", c3__ud, ent);
ent_c = u3r_string(ent);
uL(fprintf(uH, "rest: checkpoint to event %s\n", ent_c));
c3_c* ent_c = _sist_scot(c3__ud, u3A->ent_d - 1);
uL(fprintf(uH, "rest: checkpoint at event %s\n", ent_c));
free(ent_c);
u3z(ent);
}
// Open the fscking file. Does it even exist?
@ -778,11 +839,11 @@ _sist_rest()
u3_lo_bail();
}
if ( u3r_mug('f') == led_u.mag_l ) {
if ( u3r_mug('g') == led_u.mag_l ) {
_sist_rest_nuu(&u3Z->lug_u, led_u, ful_c);
fid_i = u3Z->lug_u.fid_i;
}
else if (u3r_mug('g') != led_u.mag_l ) {
else if (u3r_mug('h') != led_u.mag_l ) {
uL(fprintf(uH, "record (%s) is obsolete (or corrupt)\n", ful_c));
u3_lo_bail();
}
@ -840,26 +901,22 @@ _sist_rest()
// Read in the fscking events. These are probably corrupt as well.
{
c3_d ent_d;
c3_d end_d;
u3_noun rup = c3n;
end_d = u3Z->lug_u.len_d;
cur_d = u3Z->lug_u.len_d;
ent_d = 0;
if ( -1 == lseek64(fid_i, 4ULL * end_d, SEEK_SET) ) {
uL(fprintf(uH, "end_d %" PRIu64 ", lseek64: %s\n", end_d,
if ( -1 == lseek64(fid_i, 4ULL * cur_d, SEEK_SET) ) {
uL(fprintf(uH, "cur_d %" PRIu64 ", lseek64: %s\n", cur_d,
strerror(errno)));
uL(fprintf(uH, "rest: record (%s) is corrupt (c)\n", ful_c));
u3_lo_bail();
}
while ( end_d != c3_wiseof(u3_uled) ) {
c3_d tar_d = (end_d - (c3_d)c3_wiseof(u3_ular));
u3_ular lar_u;
c3_w* img_w;
u3_noun ron;
while ( cur_d != (c3_d)c3_wiseof(u3_uled) ) {
c3_d tar_d = (cur_d - (c3_d)c3_wiseof(u3_ular));
// uL(fprintf(uH, "rest: reading event at %" PRIx64 "\n", end_d));
// uL(fprintf(uH, "rest: reading event at %" PRIx64 "\n", cur_d));
if ( -1 == lseek64(fid_i, 4ULL * tar_d, SEEK_SET) ) {
uL(fprintf(uH, "rest: record (%s) is corrupt (d)\n", ful_c));
@ -876,7 +933,7 @@ _sist_rest()
rup = c3y;
}
uL(fprintf(uH, "lar:%x mug:%x\n", lar_u.syn_w, u3r_mug_chub(tar_d)));
end_d--; u3Z->lug_u.len_d--;
cur_d--; u3Z->lug_u.len_d--;
continue;
}
else if ( c3y == rup ) {
@ -896,7 +953,7 @@ _sist_rest()
lar_u.len_w,
lar_u.mug_w));
#endif
if ( end_d == u3Z->lug_u.len_d ) {
if ( cur_d == u3Z->lug_u.len_d ) {
ent_d = las_d = lar_u.ent_d;
}
else {
@ -907,27 +964,13 @@ _sist_rest()
}
ent_d -= 1ULL;
}
end_d = (tar_d - (c3_d)lar_u.len_w);
cur_d = tar_d - (c3_d)(lar_u.len_w + c3_wiseof(c3_w));
if ( ent_d < old_d ) {
/* change to continue to check all events */
break;
}
img_w = c3_malloc(4 * lar_u.len_w);
if ( -1 == lseek64(fid_i, 4ULL * end_d, SEEK_SET) ) {
uL(fprintf(uH, "rest: record (%s) is corrupt (h)\n", ful_c));
u3_lo_bail();
}
if ( (4 * lar_u.len_w) != read(fid_i, img_w, (4 * lar_u.len_w)) ) {
uL(fprintf(uH, "rest: record (%s) is corrupt (i)\n", ful_c));
u3_lo_bail();
}
ron = u3i_words(lar_u.len_w, img_w);
free(img_w);
// this validation is disabled, as it broke when mug
// was switched from FNV to Murmur3
// event-log encryption is enabled, so any actual corruption
@ -943,35 +986,18 @@ _sist_rest()
u3_lo_bail();
}
#endif
if ( c3__ov != lar_u.typ_w ) {
u3z(ron);
continue;
}
if ( u3A->key ) {
u3_noun dep;
dep = u3dc("de:crub:crypto", u3k(u3A->key), ron);
if ( c3n == u3du(dep) ) {
uL(fprintf(uH, "record (%s) is corrupt (k)\n", ful_c));
u3_lo_bail();
}
else {
ron = u3k(u3t(dep));
u3z(dep);
}
}
roe = u3nc(u3ke_cue(ron), roe);
}
u3A->ent_d = c3_max(las_d + 1ULL, old_d);
}
if ( u3_nul == roe ) {
fprintf(uH, "---------------- playback starting----------------\n");
if ( u3A->ent_d == old_d ) {
// Nothing in the log that was not also in the checkpoint.
//
c3_assert(u3A->ent_d == old_d);
// XX: reinstate this assertion
//
//c3_assert ( cur_d == u3Z->lug_u.len_d );
if ( las_d + 1 != old_d ) {
uL(fprintf(uH, "checkpoint and log disagree! las:%" PRIu64 " old:%" PRIu64 "\n",
las_d + 1, old_d));
@ -980,24 +1006,96 @@ _sist_rest()
"and do not delete your pier!\n"));
u3_lo_bail();
}
uL(fprintf(uH, "rest: checkpoint is up-to-date\n"));
}
else {
u3_noun rou = roe;
c3_w xno_w;
// Execute the fscking things. This is pretty much certain to crash.
// Execute the fscking things. This is pretty much certain to crash.
//
uL(fprintf(uH, "rest: replaying through event %" PRIu64 "\n", las_d));
fprintf(uH, "---------------- playback starting----------------\n");
{
c3_c* old_c = _sist_scot(c3__ud, old_d);
c3_c* las_c = _sist_scot(c3__ud, las_d);
uL(fprintf(uH, "rest: replaying events %s through %s\n", old_c, las_c));
free(old_c);
free(las_c);
}
xno_w = 0;
while ( u3_nul != roe ) {
u3_noun i_roe = u3h(roe);
u3_noun t_roe = u3t(roe);
u3_noun now = u3h(i_roe);
u3_noun ovo = u3t(i_roe);
c3_w xno_w = 0;
while ( cur_d != u3Z->lug_u.len_d ) {
u3_noun ven;
u3_noun now, ovo;
c3_d tar_d;
c3_w* img_w;
c3_w len_w;
// read the size
//
if ( -1 == lseek64(fid_i, 4ULL * cur_d, SEEK_SET) ) {
uL(fprintf(uH, "rest: record (%s) is corrupt (d)\n", ful_c));
u3_lo_bail();
}
if ( sizeof(len_w) != read(fid_i, &len_w, sizeof(len_w)) ) {
uL(fprintf(uH, "rest: record (%s) is corrupt (e)\n", ful_c));
u3_lo_bail();
}
tar_d = cur_d + c3_wiseof(len_w) + len_w;
// read the trailer
//
if ( -1 == lseek64(fid_i, 4ULL * tar_d, SEEK_SET) ) {
uL(fprintf(uH, "rest: record (%s) is corrupt (d)\n", ful_c));
u3_lo_bail();
}
if ( sizeof(u3_ular) != read(fid_i, &lar_u, sizeof(u3_ular)) ) {
uL(fprintf(uH, "rest: record (%s) is corrupt (e)\n", ful_c));
u3_lo_bail();
}
img_w = c3_malloc(4 * lar_u.len_w);
// read the event
//
if ( -1 == lseek64(fid_i, 4ULL * (cur_d + c3_wiseof(c3_w)), SEEK_SET) ) {
uL(fprintf(uH, "rest: record (%s) is corrupt (h)\n", ful_c));
u3_lo_bail();
}
if ( (4 * lar_u.len_w) != read(fid_i, img_w, (4 * lar_u.len_w)) ) {
uL(fprintf(uH, "rest: record (%s) is corrupt (i)\n", ful_c));
u3_lo_bail();
}
ven = u3i_words(lar_u.len_w, img_w);
free(img_w);
if ( c3__ov != lar_u.typ_w ) {
u3z(ven);
continue;
}
// decrypt the event
//
if ( u3A->key ) {
u3_noun dep;
dep = u3dc("de:crub:crypto", u3k(u3A->key), ven);
if ( c3n == u3du(dep) ) {
uL(fprintf(uH, "record (%s) is corrupt (k)\n", ful_c));
u3_lo_bail();
}
else {
ven = u3k(u3t(dep));
u3z(dep);
}
}
// run the event
//
ven = u3ke_cue(ven);
now = u3h(ven);
ovo = u3t(ven);
u3v_time(u3k(now));
if ( (c3y == u3_Host.ops_u.vno) &&
( (c3__veer == u3h(u3t(ovo)) ||
(c3__vega == u3h(u3t(ovo)))) ) )
@ -1005,23 +1103,41 @@ _sist_rest()
fprintf(stderr, "replay: skipped veer\n");
}
else {
_sist_sing(u3k(ovo));
_sist_sing(lar_u.ent_d, u3k(ovo));
fputc('.', stderr);
}
// fprintf(stderr, "playback: sing: %d\n", xno_w));
roe = t_roe;
xno_w++;
#if 1
// save a checkpoint every 100K events
//
if ( 0 == (xno_w % 100000) ) {
c3_d old_d = u3A->ent_d;
u3A->ent_d = lar_u.ent_d;
u3e_save();
u3A->ent_d = old_d;
}
#endif
if ( 0 == (xno_w % 1000) ) {
uL(fprintf(uH, "{%d}\n", xno_w));
// u3_lo_grab("rest", rou, u3_none);
}
u3z(ven);
cur_d += c3_wiseof(len_w) + len_w + c3_wiseof(lar_u);
if ( 0 == (xno_w % 1000) ) {
u3m_reclaim();
}
}
u3z(rou);
fputc('\r', stderr);
fputc('\n', stderr);
}
uL(fprintf(stderr, "\n---------------- playback complete----------------\r\n"));
uL(fprintf(stderr, "---------------- playback complete----------------\r\n"));
#if 0
// If you see this error, your record is totally fscking broken!
@ -1061,13 +1177,13 @@ _sist_rest()
if ( c3y == ohh ) {
uL(fprintf(uH, "rest: bumping ent_d\n"));
u3_ular lar_u;
c3_d end_d;
c3_d cur_d;
c3_d tar_d;
u3A->ent_d++;
end_d = u3Z->lug_u.len_d;
while ( end_d != c3_wiseof(u3_uled) ) {
tar_d = end_d - c3_wiseof(u3_ular);
cur_d = u3Z->lug_u.len_d;
while ( cur_d != c3_wiseof(u3_uled) ) {
tar_d = cur_d - c3_wiseof(u3_ular);
if ( -1 == lseek64(fid_i, 4ULL * tar_d, SEEK_SET) ) {
uL(fprintf(uH, "bumping sequence numbers failed (a)\n"));
u3_lo_bail();
@ -1085,7 +1201,7 @@ _sist_rest()
uL(fprintf(uH, "bumping sequence numbers failed (d)\n"));
u3_lo_bail();
}
end_d = tar_d - lar_u.len_w;
cur_d = tar_d - (c3_d)(lar_u.len_w + c3_wiseof(c3_w));
}
}
@ -1093,11 +1209,11 @@ _sist_rest()
{
u3_uled led_u;
led_u.mag_l = u3r_mug('g');
led_u.mag_l = u3r_mug('h');
led_u.sal_l = sal_l;
led_u.sev_l = u3A->sev_l;
led_u.key_l = u3A->key ? u3r_mug(u3A->key) : 0;
led_u.kno_w = 163; // may need actual translation!
led_u.kno_w = 163; // XX very wrong
led_u.tno_l = 1;
if ( (-1 == lseek64(fid_i, 0, SEEK_SET)) ||
@ -1183,6 +1299,12 @@ u3_sist_boot(void)
}
if ( c3n == u3_Host.ops_u.nuu ) {
// reclaim memory from persistent caches
//
u3m_reclaim();
// restore from event log, replaying if necessary
//
_sist_rest();
if ( c3y == u3A->fak ) {

View File

@ -1,6 +1,7 @@
/* vere/unix.c
**
*/
#include "all.h"
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
@ -12,7 +13,6 @@
#include <libgen.h>
#include <ftw.h>
#include "all.h"
#include "vere/vere.h"
/* _unix_down(): descend path.