diff options
author | neal <neal> | 2008-06-29 11:20:57 +0000 |
---|---|---|
committer | neal <neal> | 2008-06-29 11:20:57 +0000 |
commit | 487881d4231269e7cc5482ec9197c6a831df56ad (patch) | |
tree | 67cf9ed751fd8b1723115875e562056b65e70c41 /hieronymus/hieronymus.c | |
parent | 642a3509995606cc8dab319982791eb04d376a0c (diff) |
2008-06-29 Neal H. Walfield <neal@gnu.org>
* hieronymus.c (struct module): Add field delay.
(do_gather_stats): Don't initialize EPOCH here...
(main): ... but here. After loading all the modules, free the
memory. Start the modules according to their respective delay
parameters.
* Makefile.am (modules.h): Generate the delay parameter.
(module_paths): Add benchmarks.
Diffstat (limited to 'hieronymus/hieronymus.c')
-rw-r--r-- | hieronymus/hieronymus.c | 103 |
1 files changed, 68 insertions, 35 deletions
diff --git a/hieronymus/hieronymus.c b/hieronymus/hieronymus.c index a1ecfc0..f5d3e94 100644 --- a/hieronymus/hieronymus.c +++ b/hieronymus/hieronymus.c @@ -40,6 +40,8 @@ struct module const char *name; int priority; int weight; + /* Delay in seconds. */ + unsigned int delay; const char *commandline; char *start; char *end; @@ -103,8 +105,6 @@ static struct stat *stats; static void * do_gather_stats (void *arg) { - epoch = now (); - int size = 0; int period = 0; @@ -169,6 +169,8 @@ main (int argc, char *argv[]) extern int output_debug; output_debug = 3; + epoch = now (); + module_count = sizeof (modules) / sizeof (modules[0]); addr_t a[module_count]; @@ -192,6 +194,7 @@ main (int argc, char *argv[]) bool gather_stats = false; pthread_t gather_stats_tid; + /* Parse the arguments. */ for (i = 1; i < argc; i ++) { if (strcmp (argv[i], "--stats") == 0) @@ -207,58 +210,88 @@ main (int argc, char *argv[]) } } - /* Load modules. */ + /* Load each program (but don't yet start it). */ addr_t thread[module_count]; for (i = 0; i < module_count; i ++) { - /* Delay starting each process. */ -#if 0 - error_t err; - struct activity_info info; - err = rm_activity_info (activities[i], activity_info_stats, - i * 50, &info); - assert_perror (err); - assert (info.event == activity_info_stats); - assert (info.stats.count > 0); - - const char *argv[] = { modules[i].name, modules[i].commandline, NULL }; const char *env[] = { NULL }; thread[i] = process_spawn (activities[i], modules[i].start, modules[i].end, argv, env, false); -#endif - - /* Free the memory used by the module's binary. */ - /* XXX: This doesn't free folios or note pages that may be - partially freed. The latter is important because a page may - be used by two modules and after the second module is loaded, - it could be freed. */ - int count = 0; - int j; - for (j = 0; j < __hurd_startup_data->desc_count; j ++) + } + + /* Free the memory used by the binaries. XXX: Also free the folios + that are completely unused. */ + int j; + for (j = 0; j < __hurd_startup_data->desc_count; j ++) + { + struct hurd_object_desc *desc = &__hurd_startup_data->descs[j]; + + if ((desc->type == cap_page || desc->type == cap_rpage) + && ! ADDR_IS_VOID (desc->storage) + && addr_depth (desc->object) == ADDR_BITS - PAGESIZE_LOG2) { - struct hurd_object_desc *desc = &__hurd_startup_data->descs[j]; - - if ((desc->type == cap_page || desc->type == cap_rpage) - && ! ADDR_IS_VOID (desc->storage) - && addr_depth (desc->object) == ADDR_BITS - PAGESIZE_LOG2 - && (uintptr_t) modules[i].start <= addr_prefix (desc->object) - && (addr_prefix (desc->object) + PAGESIZE - 1 - <= (uintptr_t) modules[i].end)) + int i; + for (i = 0; i < module_count; i ++) + if ((uintptr_t) modules[i].start <= addr_prefix (desc->object) + && (addr_prefix (desc->object) + PAGESIZE - 1 + <= (uintptr_t) modules[i].end)) + break; + + if (i != module_count) { debug (5, "Freeing " ADDR_FMT "(" ADDR_FMT "), a %s", ADDR_PRINTF (desc->object), ADDR_PRINTF (desc->storage), cap_type_string (desc->type)); - count ++; storage_free (desc->storage, true); } } - debug (0, "Freed %d pages", count); + } + + /* Start the modules. */ + int started = 0; + while (started < module_count) + { + l4_uint64_t start = now (); + + uint64_t deadline = -1ULL; + const char *next = NULL; + + for (i = 0; i < module_count; i ++) + { + if (modules[i].delay != -1U) + { + debug (0, "%s: %ds delayed start, starting in %d s", + modules[i].name, modules[i].delay, + modules[i].delay - (int) ((start - epoch) / 1000000ULL)); + + if (modules[i].delay * 1000000ULL < start - epoch) + { + started ++; + modules[i].delay = -1U; + + debug (0, DEBUG_BOLD ("Starting %s"), modules[i].name); + thread_start (thread[i]); + } + else if (deadline > modules[i].delay * 1000000ULL) + { + deadline = modules[i].delay * 1000000ULL; + next = modules[i].name; + } + } + } - thread_start (thread[i]); + if (started < module_count) + { + debug (0, "Waiting %llu seconds before starting %s", + (deadline - (start - epoch)) / 1000000, + next); + l4_sleep (l4_time_period (deadline - (start - epoch))); + } } + /* Wait for all activities to die. */ for (i = 0; i < module_count; i ++) { |