summaryrefslogtreecommitdiff
path: root/hieronymus/hieronymus.c
diff options
context:
space:
mode:
authorneal <neal>2008-06-26 08:39:13 +0000
committerneal <neal>2008-06-26 08:39:13 +0000
commit544523675f87f02fed8bdfaf197fec07a44a0f6d (patch)
tree0418e3bec758bfb9d8b7ca361b40f3b7e82312d2 /hieronymus/hieronymus.c
parentafa3cbd9c9648ca85ad1136adacbd2bb1e8d30e1 (diff)
2008-06-26 Neal H. Walfield <neal@gnu.org>
* hieronymus.c: Include <stdlib.h>. (module_count): Make a global static. (activities): Likewise. (all_done): New variable. (now): New function. (epoch): Likewise. (struct stat): New structure. (stats_count): New variable. (stats): Likewise. (do_gather_stats): New function. (main): If --stats is specified, fork a thread to gather statistics. When all processes have exited, print out the statistics. (main): Name activities according to their first argument.
Diffstat (limited to 'hieronymus/hieronymus.c')
-rw-r--r--hieronymus/hieronymus.c171
1 files changed, 155 insertions, 16 deletions
diff --git a/hieronymus/hieronymus.c b/hieronymus/hieronymus.c
index 14edfb4..4fac2d5 100644
--- a/hieronymus/hieronymus.c
+++ b/hieronymus/hieronymus.c
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#define STRINGIFY_(id) #id
#define STRINGIFY(id) STRINGIFY_(id)
@@ -46,6 +47,9 @@ struct module
#include "modules.h"
+static int module_count;
+static addr_t *activities;
+
/* Initialized by the machine-specific startup-code. */
extern struct hurd_startup_data *__hurd_startup_data;
@@ -73,44 +77,152 @@ activity_alloc (struct activity_policy policy)
return storage;
}
+static bool all_done;
+
+static inline uint64_t
+now (void)
+{
+ struct timeval t;
+ struct timezone tz;
+
+ if (gettimeofday( &t, &tz ) == -1)
+ return 0;
+ return (t.tv_sec * 1000000ULL + t.tv_usec);
+}
+static uint64_t epoch;
+
+struct stat
+{
+ int available;
+ int alloced;
+ uint64_t time;
+};
+static int stats_count;
+static struct stat *stats;
+
+static void *
+do_gather_stats (void *arg)
+{
+ epoch = now ();
+
+ int size = 0;
+
+ int period = 0;
+
+ while (! all_done)
+ {
+ int count;
+ struct activity_stats_buffer buffer;
+
+ if (size == stats_count)
+ {
+ if (stats_count == 0)
+ size = 100;
+ else
+ size *= 2;
+
+ stats = realloc (stats,
+ sizeof (struct stat) * size * module_count);
+ }
+
+ struct stat *stat = &stats[stats_count * module_count];
+ stat->time = now ();
+
+ int n = 0;
+
+ int i;
+ for (i = 0; i < module_count; i ++, stat ++)
+ {
+ error_t err;
+ err = rm_activity_stats (activities[0],
+ period, &buffer, &count);
+ if (err)
+ {
+ stat->alloced = 0;
+ stat->available = 0;
+ }
+ else
+ {
+ stat->alloced = buffer.stats[0].clean + buffer.stats[0].dirty
+ + buffer.stats[0].pending_eviction;
+ stat->available = buffer.stats[0].available;
+
+
+ if (n == 0)
+ n = buffer.stats[0].period + 1;
+ }
+ }
+
+ stats_count ++;
+ period = n;
+ }
+
+ return NULL;
+}
+
int
main (int argc, char *argv[])
{
extern int output_debug;
output_debug = 3;
- // extern int __pthread_lock_trace;
- // __pthread_lock_trace = 0;
+ module_count = sizeof (modules) / sizeof (modules[0]);
- int count = sizeof (modules) / sizeof (modules[0]);
+ addr_t a[module_count];
+ activities = &a[0];
- struct storage activities[count];
- addr_t thread[count];
-
- /* Load modules. */
+ /* Create the activities. */
int i;
- for (i = 0; i < count; i ++)
+ for (i = 0; i < module_count; i ++)
{
struct activity_memory_policy sibling_policy
= ACTIVITY_MEMORY_POLICY (modules[i].priority, modules[i].weight);
struct activity_policy policy
= ACTIVITY_POLICY (sibling_policy, ACTIVITY_MEMORY_POLICY_VOID, 0);
- activities[i] = activity_alloc (policy);
+ activities[i] = activity_alloc (policy).addr;
+
+ struct object_name name;
+ strncpy (&name.name[0], modules[i].name, sizeof (name.name));
+ rm_object_name (ADDR_VOID, activities[i], name);
+ }
+
+ bool gather_stats = false;
+ pthread_t gather_stats_tid;
+
+ for (i = 1; i < argc; i ++)
+ {
+ if (strcmp (argv[i], "--stats") == 0)
+ {
+ if (! gather_stats)
+ {
+ error_t err;
+ err = pthread_create (&gather_stats_tid, NULL,
+ do_gather_stats, NULL);
+ assert_perror (err);
+ gather_stats = true;
+ }
+ }
+ }
+
+ /* Load modules. */
+ addr_t thread[module_count];
+ for (i = 0; i < module_count; i ++)
+ {
+ int count;
+ struct activity_stats_buffer buffer;
const char *argv[] = { modules[i].name, modules[i].commandline, NULL };
const char *env[] = { NULL };
- thread[i] = process_spawn (activities[i].addr,
+ thread[i] = process_spawn (activities[i],
modules[i].start, modules[i].end,
argv, env, false);
- debug (0, "");
-
/* 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;
+ count = 0;
int j;
for (j = 0; j < __hurd_startup_data->desc_count; j ++)
{
@@ -136,14 +248,14 @@ main (int argc, char *argv[])
}
/* Wait for all activities to die. */
- for (i = 0; i < count; i ++)
+ for (i = 0; i < module_count; i ++)
{
uintptr_t rt = -1;
rm_thread_wait_object_destroyed (root_activity,
thread[i], &rt);
- addr_t folio = addr_chop (activities[i].addr, FOLIO_OBJECTS_LOG2);
- int index = addr_extract (activities[i].addr, FOLIO_OBJECTS_LOG2);
+ addr_t folio = addr_chop (activities[i], FOLIO_OBJECTS_LOG2);
+ int index = addr_extract (activities[i], FOLIO_OBJECTS_LOG2);
error_t err;
err = rm_folio_object_alloc (ADDR_VOID, folio, index,
@@ -156,5 +268,32 @@ main (int argc, char *argv[])
debug (0, "%s exited with %d", modules[i].name, (int) rt);
}
+ if (gather_stats)
+ {
+ uint64_t n = now ();
+
+ all_done = true;
+ void *status;
+ pthread_join (gather_stats_tid, &status);
+
+ printf ("Total time: %lld.%lld\n",
+ (n - epoch) / 1000000,
+ ((n - epoch) / 100000) % 10);
+
+ for (i = 0; i < stats_count; i ++)
+ {
+ int j;
+
+ struct stat *stat = &stats[i * module_count];
+ printf ("%lld.%lld",
+ stat->time / 1000000,
+ (stat->time / 100000) % 10);
+
+ for (j = 0; j < module_count; j ++, stat ++)
+ printf ("\t%d\t%d", stat->available, stat->alloced);
+ printf ("\n");
+ }
+ }
+
return 0;
}