CS350 COS
COS
Loading...
Searching...
No Matches
ktimer.c File Reference
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/kassert.h>
#include <sys/queue.h>
#include <sys/spinlock.h>
#include <sys/kmem.h>
#include <sys/mp.h>
#include <sys/ktime.h>
#include <sys/ktimer.h>
Include dependency graph for ktimer.c:

Go to the source code of this file.

Macros

#define TIMER_WHEEL_LENGTH   256
 

Functions

static LIST_HEAD (TimerWheelHead, DEFINE_SLAB(KTimerEvent)
 
KTimerEventKTimer_Create (uint64_t timeout, KTimerCB cb, void *arg)
 
void KTimer_Retain (KTimerEvent *evt)
 
void KTimer_Release (KTimerEvent *evt)
 
void KTimer_Cancel (KTimerEvent *evt)
 
void KTimer_Process ()
 

Variables

static int timerHead = 0
 
static uint64_t timerNow = 0
 

Macro Definition Documentation

◆ TIMER_WHEEL_LENGTH

#define TIMER_WHEEL_LENGTH   256

Definition at line 14 of file ktimer.c.

Function Documentation

◆ KTimer_Cancel()

void KTimer_Cancel ( KTimerEvent evt)

Definition at line 77 of file ktimer.c.

78{
79 Spinlock_Lock(&timerLock);
80
81 LIST_REMOVE(evt, timerQueue);
82 KTimer_Release(evt);
83
84 Spinlock_Unlock(&timerLock);
85}
void KTimer_Release(KTimerEvent *evt)
Definition: ktimer.c:68
#define LIST_REMOVE(elm, field)
Definition: queue.h:465
void Spinlock_Unlock(Spinlock *lock) __UNLOCK_EX(*lock)
Definition: spinlock.c:109
void Spinlock_Lock(Spinlock *lock) __LOCK_EX(*lock)
Definition: spinlock.c:75
Here is the call graph for this function:

◆ KTimer_Create()

KTimerEvent * KTimer_Create ( uint64_t  timeout,
KTimerCB  cb,
void *  arg 
)

Definition at line 41 of file ktimer.c.

42{
43 int slot;
44 KTimerEvent *evt = KTimerEvent_Alloc();
45
46 evt->refCount = 2; // One for the wheel and one for the callee
47 evt->timeout = timerNow + timeout;
48 evt->cb = cb;
49 evt->arg = arg;
50
51 Spinlock_Lock(&timerLock);
52 slot = (timerHead + timeout + TIMER_WHEEL_LENGTH - 1) % TIMER_WHEEL_LENGTH;
53 // XXX: should insert into tail
54 LIST_INSERT_HEAD(&timerSlot[slot], evt, timerQueue);
55 Spinlock_Unlock(&timerLock);
56
57 return evt;
58}
static uint64_t timerNow
Definition: ktimer.c:17
static int timerHead
Definition: ktimer.c:16
#define TIMER_WHEEL_LENGTH
Definition: ktimer.c:14
#define LIST_INSERT_HEAD(head, elm, field)
Definition: queue.h:451
uint64_t refCount
Definition: ktimer.h:10
KTimerCB cb
Definition: ktimer.h:12
uint64_t timeout
Definition: ktimer.h:11
void * arg
Definition: ktimer.h:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ KTimer_Process()

void KTimer_Process ( )

Definition at line 88 of file ktimer.c.

89{
90 uint64_t now;
91
92 if (CPU() != 0) {
93 return;
94 }
95
96 now = KTime_GetEpoch();
97
98 Spinlock_Lock(&timerLock);
99
100 while (now > timerNow) {
101 KTimerEvent *it, *tmp;
102
103 // Dispatch pending timer events
104 LIST_FOREACH_SAFE(it, &timerSlot[timerHead], timerQueue, tmp) {
105 if (it->timeout <= now) {
106 (it->cb)(it->arg);
107 LIST_REMOVE(it, timerQueue);
108 KTimer_Release(it);
109 }
110 }
111
112 // Rotate wheel forward
113 timerNow = timerNow + 1;
115 }
116
117 Spinlock_Unlock(&timerLock);
118}
#define CPU
Definition: mp.h:7
UnixEpoch KTime_GetEpoch()
Definition: ktime.c:180
#define LIST_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:420
unsigned long uint64_t
Definition: types.h:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ KTimer_Release()

void KTimer_Release ( KTimerEvent evt)

Definition at line 68 of file ktimer.c.

69{
70 ASSERT(evt->refCount != 0);
71 if (__sync_fetch_and_sub(&evt->refCount, 1) == 1) {
72 KTimerEvent_Free(evt);
73 }
74}
#define ASSERT(_x)
Definition: kassert.h:8
Here is the caller graph for this function:

◆ KTimer_Retain()

void KTimer_Retain ( KTimerEvent evt)

Definition at line 61 of file ktimer.c.

62{
63 ASSERT(evt->refCount != 0);
64 __sync_fetch_and_add(&evt->refCount, 1);
65}

◆ LIST_HEAD()

static LIST_HEAD ( TimerWheelHead  ,
DEFINE_SLAB KTimerEvent 
)
static

Definition at line 18 of file ktimer.c.

26{
27 int i;
28
29 Spinlock_Init(&timerLock, "KTimer Lock", SPINLOCK_TYPE_NORMAL);
30 Slab_Init(&timerSlab, "KTimerEvent Slab", sizeof(KTimerEvent), 16);
31
32 // Initialize wheel
33 timerHead = 0;
35 for (i = 0; i < TIMER_WHEEL_LENGTH; i++) {
36 LIST_INIT(&timerSlot[i]);
37 }
38}
void Slab_Init(Slab *slab, const char *name, uintptr_t objsz, uintptr_t align)
#define LIST_INIT(head)
Definition: queue.h:430
#define SPINLOCK_TYPE_NORMAL
Definition: spinlock.h:12
void Spinlock_Init(Spinlock *lock, const char *name, uint64_t type)
Definition: spinlock.c:43

Variable Documentation

◆ timerHead

int timerHead = 0
static

Definition at line 16 of file ktimer.c.

◆ timerNow

uint64_t timerNow = 0
static

Definition at line 17 of file ktimer.c.