diff --git a/06_timers/Makefile b/06_timers/Makefile new file mode 100644 index 00000000..f4b14761 --- /dev/null +++ b/06_timers/Makefile @@ -0,0 +1,7 @@ +CC=gcc +SOURCES=main.c +EXECUTABLE=user_abs_time + +all: $(SOURCES) + $(CC) $(SOURCES) -o $(EXECUTABLE) + diff --git a/06_timers/main.c b/06_timers/main.c new file mode 100644 index 00000000..f4a0c818 --- /dev/null +++ b/06_timers/main.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-3.0 +/**/ +#include +#include +#include +#include +#include + +int print_clock_gettime(clockid_t clock) +{ + const int bufsize = 50; + char buf[bufsize]; + struct timespec now; + struct tm ts; + + memset(buf, '\0', bufsize); + if (clock_gettime(clock, &now) == -1) { + perror("clock_gettime failure"); + exit(EXIT_FAILURE); + } + gmtime_r(&now.tv_sec, &ts); + strftime(buf, bufsize, "%Y-%m-%d Time: %H:%M:%S.", &ts); + sprintf(buf, "%s%09lu", buf, now.tv_nsec); + printf("%s\n", buf); + if (clock_getres(clock, &now) == -1) { + perror("clock_getres failure"); + exit(EXIT_FAILURE); + } + printf(" resolution: %10jd.%09ld\n\n", + (intmax_t) now.tv_sec, now.tv_nsec); + return 0; +} + +int main(void) +{ + printf("=============================\n"); + printf("CLOCK_REALTIME time: "); + print_clock_gettime(CLOCK_REALTIME); + #ifdef CLOCK_TAI + printf("=============================\n"); + printf("CLOCK_TAI time: "); + print_clock_gettime(CLOCK_TAI); + #endif + return 0; +} + diff --git a/06_timers/time_module/Makefile b/06_timers/time_module/Makefile new file mode 100644 index 00000000..78c7b7b5 --- /dev/null +++ b/06_timers/time_module/Makefile @@ -0,0 +1,7 @@ +TARGET = get_time_module +obj-m+=$(TARGET).o +default: + $(MAKE) -C $(BUILD_KERNEL) M=$(CURDIR) modules + +clean: + $(MAKE) -C $(BUILD_KERNEL) M=$(CURDIR) clean diff --git a/06_timers/time_module/get_time_module.c b/06_timers/time_module/get_time_module.c new file mode 100644 index 00000000..652607aa --- /dev/null +++ b/06_timers/time_module/get_time_module.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-3.0 +/**/ + +#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME +#include +#include +#include +#include +#include +#include + +#define LEN_STR 160 + +static char buf_str[LEN_STR + 1]; +static struct timespec64 r_last_time; +static struct timespec64 a_last_time; +static bool first_read = 1; + +struct timespec64 delta_time(struct timespec64 start, struct timespec64 stop) +{ + struct timespec64 delta; + + delta.tv_sec = stop.tv_sec-start.tv_sec; + delta.tv_nsec = stop.tv_nsec-start.tv_nsec; + if (delta.tv_nsec < 0) + delta.tv_nsec += 1000000000; + return delta; +} + +static ssize_t relation_delay_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + int ret = 0; + struct timespec64 r_new_time, delta; + + if (first_read) { + ret = scnprintf(buf, PAGE_SIZE, + "RELATION DELAY FROM LAST READING \t 0s\n"); + ktime_get_real_ts64(&a_last_time); + ktime_get_ts64(&r_new_time); + first_read = 0; + return ret; + } + ktime_get_real_ts64(&a_last_time); + ktime_get_ts64(&r_new_time); + delta = delta_time(r_last_time, r_new_time); + ret = scnprintf(buf, PAGE_SIZE, + "RELATION DELAY FROM LAST READING \t %lld.%09lds\n", + (s64)delta.tv_sec, delta.tv_nsec); + r_last_time = r_new_time; + return ret; +} + +static ssize_t absolute_delay_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + int ret = 0; + + if (first_read) { + ret = scnprintf(buf, PAGE_SIZE, + "ABSOLUTE TIME OF LAST READING \t 0s\n"); + ktime_get_real_ts64(&a_last_time); + ktime_get_ts64(&r_last_time); + first_read = 0; + return ret; + } + ktime_get_ts64(&r_last_time); + ret = scnprintf(buf, PAGE_SIZE, + "ABSOLUTE TIME OF LAST READING \t %lld.%09lds\n", + (s64)a_last_time.tv_sec, a_last_time.tv_nsec); + ktime_get_real_ts64(&a_last_time); + return ret; +} + +static struct kobj_attribute relation_delay_attribute = + __ATTR(relation_delay, 0444, relation_delay_show, NULL); + +static struct kobj_attribute absolute_delay_attribute = + __ATTR(absolute_delay, 0444, absolute_delay_show, NULL); + +static struct attribute *attrs[] = { + &relation_delay_attribute.attr, + &absolute_delay_attribute.attr, + NULL, +}; + +static struct attribute_group attr_group = { + .attrs = attrs, +}; + +static struct kobject *store_delay_kobj; + +static int __init store_delay_module_init(void) +{ + int retval; + + memset(buf_str, '\0', LEN_STR+1); + pr_debug("loading started\n"); + store_delay_kobj = kobject_create_and_add("PASSED_DELAY", kernel_kobj); + if (!store_delay_kobj) + return -ENOMEM; + retval = sysfs_create_group(store_delay_kobj, &attr_group); + if (retval) + kobject_put(store_delay_kobj); + + return retval; +} + +static void __exit store_delay_module_exit(void) +{ + kobject_put(store_delay_kobj); + pr_info("module exited\n"); +} + +module_init(store_delay_module_init); +module_exit(store_delay_module_exit); + +MODULE_AUTHOR("Malakhova.Maryna "); +MODULE_DESCRIPTION("Store time delay module"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1");