自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(60)
  • 资源 (3)
  • 收藏
  • 关注

原创 内核同步机制API之write_seqcount_begin

write_seqcount_begin 和 write_seqcount_end 一起配合作为写顺序锁其使用的例程如下:static void cpuset_change_task_nodemask(struct task_struct *tsk, nodemask_t *newmems){ task_lock(tsk); local_irq_disable(); wri

2018-02-28 08:21:19 1170

原创 内核同步机制API之read_seqbegin

seqlock所示一种写优先的锁。其分为读顺序锁和写顺序锁。但是写优先。其读顺序锁的例程如下:static inline int grow_chain32(struct ufs_inode_info *ufsi, struct buffer_head *bh, __fs32 *v, Indirect *from, Indirect *to){ Ind

2018-02-28 08:19:33 1519

原创 内核同步机制API之up

void up(struct semaphore *sem)函数用于释放一个信号量,一般和down系列函数搭配使用其源码分析如下:void up(struct semaphore *sem){ unsigned long flags; #这里可以明显看到semaphore 实现中有调用spinlock来保护 raw_spin_lock_irqsave(&sem->lock...

2018-02-27 09:16:06 389

原创 内核同步机制API之__down_common

__down_common这个函数主要处理上一节博客中讲述的API中对sem->count 小于零的case的处理.可以看到下面这些函数都调用了__down_common,只是第二个和第三个形参有所不同static noinline void __sched __down(struct semaphore *sem){ __down_common(sem, TASK_UNINTERRUPT

2018-02-27 08:16:27 679

原创 内核同步机制API之down_xx

void down(struct semaphore *sem)函数的功能是获取信号量,获取成功后会将信号量减一,获取不到时会一直等待.其源码分析如下:void down(struct semaphore *sem){ unsigned long flags; #可以看到在对信号量count减一操作时用spin lock 锁保护起来。 #这里用likely修饰说明sem->count

2018-02-27 08:15:31 444

原创 rank和ip 地址的关系

在monitor 选举leader和peon的时候,rank这个值很关键,之前讲过这个值和ip地址有关,这个值和ip地址的关系如下在monitor.cc 中的bootstrap这个函数中可以看到void Monitor::bootstrap(){ // note my rank #可以看到是通过get_rank 这个函数得到rank的,这个函数的形参就是ip地址 int newr

2018-02-26 19:57:11 807

原创 内核定时机制API之usleep_range

usleep_range 用于非原子环境的睡眠,目前内核建议用这个函数替换之前udelay。其源码分析如下:void __sched usleep_range(unsigned long min, unsigned long max){ #得到最早wakeup的时间 ktime_t exp = ktime_add_us(ktime_get(), min); #计算必须要在max-min

2018-02-26 08:18:58 15788

原创 内核定时机制API之msleep 和 msleep_interruptible

void msleep(unsigned int msecs) 用于睡眠一段时间。不能用于原子环境其源码分析如下:void msleep(unsigned int msecs){ #可见timeout的时间是在形参的基础上再加一个jiffies,这也说明msleep 睡眠的后wakeup #的时间不是很准确,一般会在时间到期后的下一个jiffies再wakeup unsigned lo

2018-02-26 08:16:49 5638

原创 ceph monitor 选举leader和peon的过程

ceph中monitor 可以分为leader节点和peon节点,leader节点是分解rank值来决定,rank值又和ip地址有关。在ceph/mon/elector.cc 这个文件中实现的Elector 类用于选举monitor中的leader节点.leader节点的选举从start 这个成员函数开始void Elector::start(){ leader_acked = -

2018-02-24 19:13:43 2532

原创 内核定时机制API之add_timer_on

add_timer_on 用于在形参指定的cpu上开始一个定时器.其源码分析如下:从这个函数可以知道每个cpu上都有timer的list.如果调用add_timer的时候没有指定cpu其实就是运行在当前的cpu上。void add_timer_on(struct timer_list *timer, int cpu){ struct timer_base *new_base, *bas

2018-02-24 08:14:34 2227 1

原创 内核定时机制API之timespec64_compare

static inline int timespec64_compare(const struct timespec64 *lhs, const struct timespec64 *rhs) 用于比较两个形参timespec64 时间的大小其源码分析如下:static inline int timespec64_compare(const struct timespec64 *lhs, c

2018-02-24 08:13:54 1804

原创 内核定时机制API之timespec64_add

static inline struct timespec64 timespec64_add(struct timespec64 lhs,struct timespec64 rhs)用于将两个形参的timespec64相加的值返回。从这个函数知道两个timespec64的结构体不能直接相加,只要涉及到nsec的值的调整要调用kernel提供的这个api来进行.其源码分析如下:static i

2018-02-23 08:21:03 2300

原创 内核定时机制API之set_normalized_timespec64

void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec) 用于将形参的sec和nsec分别赋值给timespec64的成员变量,这里第三个形参nsec的范围应该在0 <= tv_nsec < NSEC_PER_SEC之内其源码分析如下:void set_normalized_timespec6

2018-02-23 08:20:08 794 2

原创 redis的main函数

redis的入口函数在redis.c 中的main函数中int main(int argc, char **argv) { // 初始化服务器配置,主要用于给struct redisServer server; 赋值,并实现一些基本的命令。,并监听clint的连接信息。 initServerConfig(); // 从这里可以看到可以通过-v 或者 --versio

2018-02-22 20:12:01 2601

原创 内核定时机制API之ns_to_timespec64 和 ns_to_timeval

struct timespec64 ns_to_timespec64(const s64 nsec)用于将纳秒转成timespec64格式返回给用户其源码分析如下:struct timespec64 ns_to_timespec64(const s64 nsec){ struct timespec64 ts; s32 rem; #如果形参nsec为null,则让timespec64的两

2018-02-22 08:17:12 2018

原创 内核定时机制API之mktime

static inline unsigned long mktime(const unsigned int year, const unsigned int mon, const unsigned int day, const unsigned int hour, const unsigned int min, const unsigned int sec)这个函数用于返回形参

2018-02-22 08:15:55 478

原创 redis中的事件处理

redis中的事件分为文件事件和时间事件。redis中用aeEventLoop 来记录事件的状态typedef struct aeEventLoop { // 文件事件 aeFileEvent *events; /* Registered events */ // 时间事件 aeTimeEvent *timeEventHead;} aeEventLoop;

2018-02-14 08:25:18 486

原创 内核定时机制API之timer_setup

timer_setup(timer, callback, flags) 用于为第一次使用timer做好准备,一般和add_timer 配合使用其使用的例程如下:static void prb_setup_retire_blk_timer(struct packet_sock *po){ struct tpacket_kbdq_core *pkc; pkc = GET_PBDQC_FRO

2018-02-14 08:24:33 20431

原创 内核定时机制API之getnstimeofday

static inline void getnstimeofday(struct timespec *ts)用于获得系统当前时间并以timespec结构体的形式返回给用户.其源码分析如下:static inline void getnstimeofday(struct timespec *ts){ getnstimeofday64(ts);}直接调用getnstimeofday64

2018-02-14 08:23:48 5372

原创 redis中的watch命令

watch 用于在进行事务操作的最后一步也就是在执行exec 之前对某个key进行监视如果这个被监视的key被改动,那么事务就被取消,否则事务正常执行.一般在MULTI 命令前就用watch命令对某个key进行监控.如果想让key取消被监控,可以用unwatch命令被监视的key会被保存在两个地方一个是:typedef struct redisClient { // 被监视的键

2018-02-13 08:20:07 4769

原创 内核定时机制API之get_seconds

unsigned long get_seconds(void)用于获得内核自1970年1月1日0时0分0秒以来的秒数.其源码分析如下:unsigned long get_seconds(void){ struct timekeeper *tk = &tk_core.timekeeper; return tk->xtime_sec;}首先获得timekeeper的指针,然后返回tim

2018-02-13 08:19:24 1413

原创 内核定时机制API之do_settimeofday64

int do_settimeofday64(const struct timespec64 *ts)用于修改当前timekeeper的时间.其源码分析如下:int do_settimeofday64(const struct timespec64 *ts){ #得到当前timekeeper的指针 struct timekeeper *tk = &tk_core.timekeeper;

2018-02-13 08:18:30 3603

原创 redis中事务的取消

redis的事务不能实现回滚,但是可以在正在执行的事务中通过discard 命令来取消事务的执行。struct redisCommand redisCommandTable[] = { {"discard",discardCommand,1,"rs",0,NULL,0,0,0,0,0},}void discardCommand(redisClient *c) { // 可

2018-02-12 08:22:45 1619

原创 内核定时机制API之do_gettimeofday

void do_gettimeofday(struct timeval *tv) 用于按照timeval的格式返回当前系统时间.其最终是从timekeeper中拿到时间.其timeval的定义如下:struct timeval { __kernel_time_t tv_sec; /* seconds */ __kernel_suseconds_t tv_usec; /* microse

2018-02-12 08:21:52 2128

原创 内核定时机制API之del_timer_sync

int del_timer_sync(struct timer_list *timer)的作用类似del_timer,但是删除的时候如果timer正在执行,则会等待timer执行完成再删除.其源码分析如下:int del_timer_sync(struct timer_list *timer){#检查死锁的code#ifdef CONFIG_LOCKDEP unsigned long

2018-02-12 08:21:06 3577

原创 redis中的事务

redis页支持事务。redis的事务是在MULTI 和 EXEC 命令之间的一条或者多条命令.从redis.c 中可以知道MULTI 命令的实现如下: {"multi",multiCommand,1,"rs",0,NULL,0,0,0,0,0},void multiCommand(redisClient *c) { // REDIS_MULTI 表示当前正在进行事务操作,...

2018-02-11 15:16:44 367

原创 内核定时机制API之del_timer

int del_timer(struct timer_list *timer) 用于删除一个timer。一般和add_timer 配合使用.其源码分析如下:int del_timer(struct timer_list *timer){ struct timer_base *base; unsigned long flags; int ret = 0; debug_assert_i

2018-02-11 08:38:37 2393

原创 内核定时机制API之current_kernel_time

inline struct timespec current_kernel_time(void) 此函数用于返回当前内核时间。该时间是距离1970开始的秒和纳秒.static inline struct timespec current_kernel_time(void){ #首先得到时间并存在timespec64 类型的now中 struct timespec64 now = curre

2018-02-11 08:37:50 5108

原创 fuser

fuser 主要用于显示文件/socket/filesystem是 正在被哪个进程使用。通过-k参数可以杀掉正在使用文件的进程

2018-02-09 16:27:38 1340

原创 centos 中单机安装redis

下载安装并是能redisyum install redissystemctl  enable redis.service启动服务端启动客户端并并设置一个key-value 键值对

2018-02-09 14:42:19 337

原创 redis中的memory管理

redis 中申请memory的实现在zmalloc.c/h 中。仔细阅读这两个文件可以返现redis 对memory的申请和释放方式都是在glibc中提供的malloc/free 的封装.我们以申请memory函数中的zmalloc 为例void *zmalloc(size_t size) { //调用malloc 来申请内存,注意这里申请的size ,会在形参size的基础上加上PRE

2018-02-09 08:19:58 752

原创 内核定时机制API之add_timer

void add_timer(struct timer_list *timer)用于开始一个定时器。这个函数在内核中用的实在是太多了。其源码分析如下:void add_timer(struct timer_list *timer){ BUG_ON(timer_pending(timer)); mod_timer(timer, timer->expires);}首先通过timer_p

2018-02-09 08:18:46 4866

原创 内核定时机制API之__round_jiffies_relative

unsigned long __round_jiffies_relative(unsigned long j, int cpu) 这个函数和__round_jiffies 函数的作用相同,区别在于形参j在计算之前会round_up 一个jiffies其源码分析如下:unsigned long __round_jiffies_relative(unsigned long j, int cpu)

2018-02-09 08:17:43 880

原创 redis中的server/client/sentinel/集群

redis服务器是一个一对多的架构,服务端通过I/O 多路复用技术实现的文件事件处理,采用单线程单进程的方式来处理和多个client的请求.struct redisServer { // 保存了所有客户端状态结构 list *clients; /* List of active clients */ // 链表,保存了所有待关闭的客户端

2018-02-08 20:39:53 701

原创 redis中的文件事件和时间事件

redis服务器是一个事件驱动程序。可以分为文件事件和时间事件,其中文件事件是服务器和客户端之间连接套接字的抽象,而时间事件又分为定时事件和周期事件,目前redis 只实现了周期事件.redis 文件事件是通过select/epoll等这些函数库的包装.举例如下:例如我们通过下面这个函数关联事件到fdstatic int aeApiAddEvent(aeEventLoop *eventL

2018-02-08 08:24:07 875

原创 内核定时机制API之__round_jiffies

unsigned long __round_jiffies(unsigned long j, int cpu)用户将jiffies 转成HZ的整数倍也就是整秒.其源码分析如下:unsigned long __round_jiffies(unsigned long j, int cpu){ return round_jiffies_common(j, cpu, false);}stati

2018-02-08 08:22:15 934

原创 内存管理API之vmalloc_user

void *vmalloc_user(unsigned long size)用于申请一段虚拟地址连续的内存给user space使用。一般情况下这段虚拟内存是在当前进程空间的,因此会给它添加一个VM_USERMAP的flag。防止将kernelspace的数据泄露到user space.其源码分析如下:void *vmalloc_user(unsigned long size){ v

2018-02-08 08:21:21 2629

原创 redis中的持久化

redis 用redisServer 表示server端struct redisServer { /* General */ // 配置文件的绝对路径 char *configfile; /* Absolute config file path, or NULL */ // serverCron() 每秒调用的次数 int hz;

2018-02-07 08:34:15 538

原创 内存管理API之vmalloc_to_pfn

unsigned long vmalloc_to_pfn(const void *addr)用于返回虚拟地址addr所映射物理页的页框编号。其源码分析如下:unsigned long vmalloc_to_pfn(const void *addr){ return page_to_pfn(virt_to_page(addr));}这个函数首先通过virt_to_page找到虚拟地址ad

2018-02-07 08:33:37 1305

原创 内存管理API之vmalloc_to_page

struct page *vmalloc_to_page(const void *addr)用于找到虚拟地址addr对应的物理page其源码分析如下:struct page *vmalloc_to_page(const void *addr){ return virt_to_page(addr);}调用virt_to_page 得到addr对应的物理page页通过__virt_to_

2018-02-07 08:32:43 4009 2

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除