我是靠谱客的博主 鲤鱼钥匙,最近开发中收集的这篇文章主要介绍jiffies 的使用jiffies 的使用处理特定寄存器获取当前执行时间,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

jiffies 的使用

每一个技术点都是要靠自己对着书来一步步实践

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/uaccess.h> /* copy_*_user */
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/jiffies.h>

static void __exit  hello_exit(void)
{

        printk("%dn", jiffies);
        return;
}

static int __init  hello_init(void)
{
        dev_t dev = 0;


        return 0;

}


module_init(hello_init);
module_exit(hello_exit);

调用dmesg查看结果,注意这里获取都是32位的

[ 1724.354757] 355881
[ 1751.993783] 362791
[ 1753.189108] 363090
[ 1754.108915] 363320

下面我继续看64位的获取方法

get_jiffies_64();

输出的结果是:

[  591.756554] timer:4295039905

防止溢出的回环处理函数

#include <linux/jiffies.h>
int time_after(unsigned long a, unsigned long b);
int time_before(unsigned long a, unsigned long b);
int time_after_eq(unsigned long a, unsigned long b);
int time_before_eq(unsigned long a, unsigned long b);

jiffies 和 timeval 以及 timespace 的转化,timeval使用的是秒和毫秒,timespace使用的是秒和纳秒,内核提供了4个辅助函数

struct timespec {
        __kernel_time_t tv_sec;                 /* seconds */
        long            tv_nsec;                /* nanoseconds */
};
#endif

struct timeval {
        __kernel_time_t         tv_sec;         /* seconds */
        __kernel_suseconds_t    tv_usec;        /* microseconds */
};

书上写的 jiffiestotimeval 好像不能用了,然后我看到编译的细节是头文件的目录在/usr/src/linux-headers-5.8.0-44-generic/include/linux/time.h ,linux 内核5.8以后没有这个了,所以我看了下头文件内容

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_TIME_H
#define _LINUX_TIME_H

# include <linux/cache.h>
# include <linux/seqlock.h>
# include <linux/math64.h>
# include <linux/time64.h>

extern struct timezone sys_tz;

int get_timespec64(struct timespec64 *ts,
        const struct __kernel_timespec __user *uts);
int put_timespec64(const struct timespec64 *ts,
        struct __kernel_timespec __user *uts);
int get_itimerspec64(struct itimerspec64 *it,
            const struct __kernel_itimerspec __user *uit);
int put_itimerspec64(const struct itimerspec64 *it,
            struct __kernel_itimerspec __user *uit);

extern time64_t mktime64(const unsigned int year, const unsigned int mon,
            const unsigned int day, const unsigned int hour,
            const unsigned int min, const unsigned int sec);

/* Some architectures do not supply their own clocksource.
 * This is mainly the case in architectures that get their
 * inter-tick times by reading the counter on their interval
 * timer. Since these timers wrap every tick, they're not really
 * useful as clocksources. Wrapping them to act like one is possible
 * but not very efficient. So we provide a callout these arches
 * can implement for use with the jiffies clocksource to provide
 * finer then tick granular time.
 */
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
extern u32 (*arch_gettimeoffset)(void);
#endif

#ifdef CONFIG_POSIX_TIMERS
extern void clear_itimer(void);
#else
static inline void clear_itimer(void) {}
#endif

extern long do_utimes(int dfd, const char __user *filename, struct timespec64 *times, int flags);

/*
 * Similar to the struct tm in userspace <time.h>, but it needs to be here so
 * that the kernel source is self contained.
 */
struct tm {
    /*
     * the number of seconds after the minute, normally in the range
     * 0 to 59, but can be up to 60 to allow for leap seconds
     */
    int tm_sec;
    /* the number of minutes after the hour, in the range 0 to 59*/
    int tm_min;
    /* the number of hours past midnight, in the range 0 to 23 */
    int tm_hour;
    /* the day of the month, in the range 1 to 31 */
    int tm_mday;
    /* the number of months since January, in the range 0 to 11 */
    int tm_mon;
    /* the number of years since 1900 */
    long tm_year;
    /* the number of days since Sunday, in the range 0 to 6 */
    int tm_wday;
    /* the number of days since January 1, in the range 0 to 365 */
    int tm_yday;
};

void time64_to_tm(time64_t totalsecs, int offset, struct tm *result);

# include <linux/time32.h>

static inline bool itimerspec64_valid(const struct itimerspec64 *its)
{
    if (!timespec64_valid(&(its->it_interval)) ||
        !timespec64_valid(&(its->it_value)))
        return false;

    return true;
}

/**
 * time_after32 - compare two 32-bit relative times
 * @a:  the time which may be after @b
 * @b:  the time which may be before @a
 *
 * time_after32(a, b) returns true if the time @a is after time @b.
 * time_before32(b, a) returns true if the time @b is before time @a.
 *
 * Similar to time_after(), compare two 32-bit timestamps for relative
 * times.  This is useful for comparing 32-bit seconds values that can't
 * be converted to 64-bit values (e.g. due to disk format or wire protocol
 * issues) when it is known that the times are less than 68 years apart.
 */
#define time_after32(a, b)  ((s32)((u32)(b) - (u32)(a)) < 0)
#define time_before32(b, a) time_after32(a, b)

/**
 * time_between32 - check if a 32-bit timestamp is within a given time range
 * @t:  the time which may be within [l,h]
 * @l:  the lower bound of the range
 * @h:  the higher bound of the range
 *
 * time_before32(t, l, h) returns true if @l <= @t <= @h. All operands are
 * treated as 32-bit integers.
 *
 * Equivalent to !(time_before32(@t, @l) || time_after32(@t, @h)).
 */
#define time_between32(t, l, h) ((u32)(h) - (u32)(l) >= (u32)(t) - (u32)(l))

# include <vdso/time.h>

#endif

处理特定寄存器

很多场景我们需要很高的精度,而又忽略可移植性的不可预测。

为了解决这一个问题cpu通过计算时钟周期而度量时间差的简单可靠做法。绝大多数都包含一个随着时钟周期而不断递增的计数寄存器,这个时钟计数器是完成分辨率计时任务的唯一可靠途径。

无论这个计数寄存器是否为0我们都不应该去重置他

最有名气的寄存器是时间戳计数器(TSC)。

包含头文件

两个重要的函数

rdtsc(low32, high32)
rdtscl(low32);
rdtscll(var64);

在内核头文件中还有一个与体系结构无关的函数可以替代rdtsc 多数时候用低32就够了,但是1-GHZ的处理器,每4.2秒就会溢出,因此所有平台都平台提供了

#include <linux/timex.h>
cycles_t get_cycloes(void);


static int __init  hello_init(void)
{

        printk("timer:%lldn",get_cycles());
        return 0;

}

结果:

[  591.756554] timer:4295039905
[11211.385908] timer:26952505672285

获取当前执行时间

最后

以上就是鲤鱼钥匙为你收集整理的jiffies 的使用jiffies 的使用处理特定寄存器获取当前执行时间的全部内容,希望文章能够帮你解决jiffies 的使用jiffies 的使用处理特定寄存器获取当前执行时间所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部