CS350 COS
COS
Loading...
Searching...
No Matches
spinlock.h File Reference
#include <stdint.h>
#include <sys/cdefs.h>
#include <sys/queue.h>
Include dependency graph for spinlock.h:

Go to the source code of this file.

Data Structures

struct  Spinlock
 

Macros

#define SPINLOCK_NAMELEN   32
 
#define SPINLOCK_TYPE_NORMAL   1
 
#define SPINLOCK_TYPE_RECURSIVE   2
 

Typedefs

typedef struct Spinlock Spinlock
 

Functions

void Critical_Init ()
 
void Critical_Enter ()
 
void Critical_Exit ()
 
uint32_t Critical_Level ()
 
void Spinlock_EarlyInit ()
 
void Spinlock_Init (Spinlock *lock, const char *name, uint64_t type)
 
void Spinlock_Destroy (Spinlock *lock)
 
void Spinlock_Lock (Spinlock *lock) __LOCK_EX(*lock)
 
void Spinlock_Unlock (Spinlock *lock) __UNLOCK_EX(*lock)
 
bool Spinlock_IsHeld (Spinlock *lock) __LOCK_EX_ASSERT(*lock)
 

Macro Definition Documentation

◆ SPINLOCK_NAMELEN

#define SPINLOCK_NAMELEN   32

Definition at line 10 of file spinlock.h.

◆ SPINLOCK_TYPE_NORMAL

#define SPINLOCK_TYPE_NORMAL   1

Definition at line 12 of file spinlock.h.

◆ SPINLOCK_TYPE_RECURSIVE

#define SPINLOCK_TYPE_RECURSIVE   2

Definition at line 13 of file spinlock.h.

Typedef Documentation

◆ Spinlock

typedef struct Spinlock Spinlock

Function Documentation

◆ Critical_Enter()

void Critical_Enter ( )

Definition at line 28 of file critical.c.

29{
31 lockLevel[CPU()]++;
32}
static INLINE void disable_interrupts()
Definition: amd64op.h:14
uint32_t lockLevel[MAX_CPUS]
Definition: critical.c:14
#define CPU
Definition: mp.h:7
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Critical_Exit()

void Critical_Exit ( )

Definition at line 35 of file critical.c.

36{
37 lockLevel[CPU()]--;
38 if (lockLevel[CPU()] == 0)
39 {
41 }
42}
static INLINE void enable_interrupts()
Definition: amd64op.h:9
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Critical_Init()

void Critical_Init ( )

Definition at line 17 of file critical.c.

18{
19 int c;
20
21 for (c = 0; c < MAX_CPUS; c++)
22 {
23 lockLevel[c] = 0;
24 }
25}
#define MAX_CPUS
Definition: kconfig.h:8
Here is the caller graph for this function:

◆ Critical_Level()

uint32_t Critical_Level ( )

Definition at line 45 of file critical.c.

46{
47 return lockLevel[CPU()];
48}
Here is the caller graph for this function:

◆ Spinlock_Destroy()

void Spinlock_Destroy ( Spinlock lock)

Definition at line 61 of file spinlock.c.

62{
64 LIST_REMOVE(lock, lockList);
66}
#define LIST_REMOVE(elm, field)
Definition: queue.h:465
Spinlock lockListLock
Definition: spinlock.c:21
void Spinlock_Unlock(Spinlock *lock) __NO_LOCK_ANALYSIS
Definition: spinlock.c:109
void Spinlock_Lock(Spinlock *lock) __NO_LOCK_ANALYSIS
Definition: spinlock.c:75
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Spinlock_EarlyInit()

void Spinlock_EarlyInit ( )
Here is the caller graph for this function:

◆ Spinlock_Init()

void Spinlock_Init ( Spinlock lock,
const char *  name,
uint64_t  type 
)

Definition at line 43 of file spinlock.c.

44{
45 lock->lock = 0;
46 lock->cpu = 0;
47 lock->count = 0;
48 lock->rCount = 0;
49 lock->lockTime = 0;
50 lock->waitTime = 0;
51 lock->type = type;
52
53 strncpy(&lock->name[0], name, SPINLOCK_NAMELEN);
54
56 LIST_INSERT_HEAD(&lockList, lock, lockList);
58}
uint32_t type
Definition: multiboot.h:8
#define LIST_INSERT_HEAD(head, elm, field)
Definition: queue.h:451
#define SPINLOCK_NAMELEN
Definition: spinlock.h:10
char * strncpy(char *to, const char *from, size_t len)
Definition: string.c:34
uint64_t type
Definition: spinlock.h:24
uint64_t cpu
Definition: spinlock.h:18
uint64_t count
Definition: spinlock.h:19
uint64_t rCount
Definition: spinlock.h:20
volatile uint64_t lock
Definition: spinlock.h:17
uint64_t lockTime
Definition: spinlock.h:21
uint64_t waitTime
Definition: spinlock.h:22
char name[SPINLOCK_NAMELEN]
Definition: spinlock.h:25
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Spinlock_IsHeld()

bool Spinlock_IsHeld ( Spinlock lock)

Definition at line 126 of file spinlock.c.

127{
128 return (lock->cpu == CPU()) && (lock->lock == 1);
129}
Here is the caller graph for this function:

◆ Spinlock_Lock()

void Spinlock_Lock ( Spinlock lock)

Spinlock_Lock –

Spin until we acquire the spinlock. This will also disable interrupts to prevent deadlocking with interrupt handlers.

Definition at line 75 of file spinlock.c.

76{
77 uint64_t startTSC;
79
80 startTSC = Time_GetTSC();
81 while (atomic_swap_uint64(&lock->lock, 1) == 1)
82 {
83 if (lock->type == SPINLOCK_TYPE_RECURSIVE && lock->cpu == CPU()) {
84 break;
85 }
86 if ((Time_GetTSC() - startTSC) / ticksPerSecond > 1) {
87 kprintf("Spinlock_Lock(%s): waiting for over a second!\n", lock->name);
88 breakpoint();
89 }
90 }
91 lock->waitTime += Time_GetTSC() - startTSC;
92
93 lock->cpu = CPU();
94 lock->count++;
95
96 lock->rCount++;
97 if (lock->rCount == 1)
98 lock->lockedTSC = Time_GetTSC();
99
100 TAILQ_INSERT_TAIL(&lockStack[CPU()], lock, lockStack);
101}
static INLINE void breakpoint()
Definition: amd64op.h:29
static INLINE uint64_t atomic_swap_uint64(volatile uint64_t *dst, uint64_t newval)
Definition: atomic.h:15
void Critical_Enter()
Definition: critical.c:28
int kprintf(const char *fmt,...)
Definition: printf.c:210
uint64_t ticksPerSecond
Definition: ktime.c:17
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:641
#define SPINLOCK_TYPE_RECURSIVE
Definition: spinlock.h:13
uint64_t lockedTSC
Definition: spinlock.h:23
uint64_t Time_GetTSC()
Definition: time.c:13
unsigned long uint64_t
Definition: types.h:13
Here is the call graph for this function:

◆ Spinlock_Unlock()

void Spinlock_Unlock ( Spinlock lock)

Spinlock_Unlock –

Release the spinlock. This will re-enable interrupts.

Definition at line 109 of file spinlock.c.

110{
111 ASSERT(lock->cpu == CPU());
112
113 TAILQ_REMOVE(&lockStack[CPU()], lock, lockStack);
114
115 lock->rCount--;
116 if (lock->rCount == 0) {
117 lock->cpu = 0;
118 lock->lockTime += Time_GetTSC() - lock->lockedTSC;
119 atomic_set_uint64(&lock->lock, 0);
120 }
121
123}
static void atomic_set_uint64(volatile uint64_t *dst, uint64_t newval)
Definition: atomic.h:24
void Critical_Exit()
Definition: critical.c:35
#define ASSERT(_x)
Definition: kassert.h:8
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:659
Here is the call graph for this function: