Hi, bringing this again, a couple of patches in "dirty form" to get further review.
Attached there is my new attempt as it was previously discussed, i.e. providing more data in the kernel page of mapped time. * 01_types.diff: This adds a new structure in time_value.h, making it named in a similar way of stdlib' struct timespec (with the macros of the struct time_value provided also for time_spec). I chose to provide a new one, yet basically the same as time_value, as it would be awkward to use a time_value_t to store nanoseconds in its microseconds member... * 02_clock.diff: This patch actually adds the actual new clock, taking care of adding microseconds to it, and switching the mapped time struct to the new _extended one. As usual, comments, remarks, etc are welcome. (I will provide clean git commits with proper changelog once the work i finalized.) Thanks, -- Pino Toscano
--- a/include/mach/time_value.h +++ b/include/mach/time_value.h @@ -63,6 +63,39 @@ } /* + * Extended time specification. + */ + +struct time_spec { + integer_t seconds; + integer_t nanoseconds; +}; +typedef struct time_spec time_spec_t; + +/* + * Macros to manipulate time specs. Assume that time values + * are normalized (nanoseconds <= 999999999). + */ +#define TIME_NANOS_MAX (1000000000) + +#define time_spec_add_nsec(val, nanos) { \ + if (((val)->nanoseconds += (nanos)) \ + >= TIME_NANOS_MAX) { \ + (val)->nanoseconds -= TIME_NANOS_MAX; \ + (val)->seconds++; \ + } \ +} + +#define time_spec_add(result, addend) { \ + (result)->nanoseconds += (addend)->nanoseconds; \ + (result)->seconds += (addend)->seconds; \ + if ((result)->nanoseconds >= TIME_NANOS_MAX) { \ + (result)->nanoseconds -= TIME_NANOS_MAX; \ + (result)->seconds++; \ + } \ +} + +/* * Time value available through the mapped-time interface. * Read this mapped value with * do { @@ -77,4 +110,14 @@ integer_t check_seconds; } mapped_time_value_t; +typedef struct mapped_time_value_extended { + integer_t seconds; + integer_t microseconds; + integer_t check_seconds; + integer_t version; + /* new in version >= 1 */ + time_spec_t clock_rt; /* realtime clock */ + time_spec_t clock_mt; /* monotonic clock */ +} mapped_time_value_extended_t; + #endif /* _MACH_TIME_VALUE_H_ */
--- a/kern/mach_clock.c +++ b/kern/mach_clock.c @@ -69,6 +69,7 @@ int hz = HZ; /* number of ticks per second */ int tick = (1000000 / HZ); /* number of usec per tick */ time_value_t time = { 0, 0 }; /* time since bootup (uncorrected) */ +time_value_t monotonic = { 0, 0 }; /* time since bootup (uncorrected) */ unsigned long elapsed_ticks = 0; /* ticks elapsed since bootup */ int timedelta = 0; @@ -93,9 +94,9 @@ * We have to insert write fence operations.) FIXME */ -mapped_time_value_t *mtime = 0; +mapped_time_value_extended_t *mtime = 0; -#define update_mapped_time(time) \ +#define update_mapped_time(time, monotonic) \ MACRO_BEGIN \ if (mtime != 0) { \ mtime->check_seconds = (time)->seconds; \ @@ -103,6 +104,16 @@ mtime->microseconds = (time)->microseconds; \ asm volatile("":::"memory"); \ mtime->seconds = (time)->seconds; \ + asm volatile("":::"memory"); \ + mtime->clock_rt.seconds = (time)->seconds; \ + asm volatile("":::"memory"); \ + mtime->clock_rt.nanoseconds = \ + (time)->microseconds * 1000; \ + asm volatile("":::"memory"); \ + mtime->clock_mt.seconds = (monotonic)->seconds; \ + asm volatile("":::"memory"); \ + mtime->clock_mt.nanoseconds = \ + (monotonic)->microseconds * 1000; \ } \ MACRO_END @@ -219,6 +230,7 @@ */ if (timedelta == 0) { time_value_add_usec(&time, usec); + time_value_add_usec(&monotonic, usec); } else { register int delta; @@ -232,8 +244,9 @@ timedelta -= tickdelta; } time_value_add_usec(&time, delta); + time_value_add_usec(&monotonic, delta); } - update_mapped_time(&time); + update_mapped_time(&time, &monotonic); /* * Schedule soft-interupt for timeout if needed @@ -427,7 +440,7 @@ s = splhigh(); time = new_time; - update_mapped_time(&time); + update_mapped_time(&time, &monotonic); resettodr(); splx(s); @@ -498,7 +511,8 @@ != KERN_SUCCESS) panic("mapable_time_init"); memset(mtime, 0, PAGE_SIZE); - update_mapped_time(&time); + mtime->version = 1; + update_mapped_time(&time, &monotonic); } int timeopen()
signature.asc
Description: This is a digitally signed message part.