Loading [MathJax]/extensions/tex2jax.js
CS350 COS
COS
All Data Structures Files Functions Variables Typedefs Macros
semaphore.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <sys/kassert.h>
#include <sys/kconfig.h>
#include <sys/kdebug.h>
#include <sys/ktime.h>
#include <sys/mp.h>
#include <sys/spinlock.h>
#include <sys/semaphore.h>
#include <sys/thread.h>
Include dependency graph for semaphore.c:

Go to the source code of this file.

Functions

 LIST_HEAD (SemaListHead, Semaphore)
 
void Semaphore_Destroy (Semaphore *sema)
 
void Semaphore_Acquire (Semaphore *sema)
 
void Semaphore_Release (Semaphore *sema)
 
bool Semaphore_TryAcquire (Semaphore *sema)
 
void Debug_Semaphores (int argc, const char *argv[])
 
 REGISTER_DBGCMD (semaphores, "Display list of semaphores", Debug_Semaphores)
 

Variables

Spinlock semaListLock = { 0, 0, 0, 0, 0, 0, 0, 0, "Semaphore List" }
 

Function Documentation

◆ Debug_Semaphores()

void Debug_Semaphores ( int  argc,
const char *  argv[] 
)

Definition at line 102 of file semaphore.c.

103{
104 Semaphore *sema;
105
107
108 kprintf("%-36s Count\n", "Lock Name");
109 LIST_FOREACH(sema, &semaList, semaphoreList)
110 {
111 Thread *thr;
112 kprintf("%-36s %8d\n", sema->name, sema->count);
113 TAILQ_FOREACH(thr, &sema->waiters, semaQueue) {
114 kprintf("waiting: %d:%d\n", thr->proc->pid, thr->tid);
115 }
116 }
117
119}
int kprintf(const char *fmt,...)
Definition: printf.c:210
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:557
#define LIST_FOREACH(var, head, field)
Definition: queue.h:410
Spinlock semaListLock
Definition: semaphore.c:19
void Spinlock_Unlock(Spinlock *lock) __UNLOCK_EX(*lock)
Definition: spinlock.c:109
void Spinlock_Lock(Spinlock *lock) __LOCK_EX(*lock)
Definition: spinlock.c:75
uint64_t pid
Definition: thread.h:66
int count
Definition: semaphore.h:16
char name[SEMAPHORE_NAMELEN]
Definition: semaphore.h:15
Definition: thread.h:31
struct Process * proc
Definition: thread.h:39
uint64_t tid
Definition: thread.h:36
Here is the call graph for this function:

◆ LIST_HEAD()

LIST_HEAD ( SemaListHead  ,
Semaphore   
)

Definition at line 20 of file semaphore.c.

26{
27 Spinlock_Init(&sema->lock, name, SPINLOCK_TYPE_NORMAL);
28 sema->count = count;
29
30 strncpy(&sema->name[0], name, SEMAPHORE_NAMELEN);
31 TAILQ_INIT(&sema->waiters);
32
34 LIST_INSERT_HEAD(&semaList, sema, semaphoreList);
36}
#define TAILQ_INIT(head)
Definition: queue.h:597
#define LIST_INSERT_HEAD(head, elm, field)
Definition: queue.h:451
#define SEMAPHORE_NAMELEN
Definition: semaphore.h:8
#define SPINLOCK_TYPE_NORMAL
Definition: spinlock.h:12
void Spinlock_Init(Spinlock *lock, const char *name, uint64_t type)
Definition: spinlock.c:43
char * strncpy(char *to, const char *from, size_t len)
Definition: string.c:34

◆ REGISTER_DBGCMD()

REGISTER_DBGCMD ( semaphores  ,
"Display list of semaphores"  ,
Debug_Semaphores   
)

◆ Semaphore_Acquire()

void Semaphore_Acquire ( Semaphore sema)

Definition at line 49 of file semaphore.c.

50{
51 Thread *cur = Sched_Current();
52
53 while (1) {
54 Spinlock_Lock(&sema->lock);
55 if (sema->count > 0) {
56 sema->count -= 1;
57 Spinlock_Unlock(&sema->lock);
58 Thread_Release(cur);
59 return;
60 }
61
62 // Add to sleeper list
63 TAILQ_INSERT_TAIL(&sema->waiters, cur, semaQueue);
65
66 Spinlock_Unlock(&sema->lock);
68 }
69}
void Sched_SetWaiting(Thread *thr)
Definition: sched.c:104
void Sched_Scheduler()
Definition: sched.c:189
void Thread_Release(Thread *thr)
Definition: thread.c:265
Thread * Sched_Current()
Definition: sched.c:56
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:641
Spinlock lock
Definition: semaphore.h:14
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Semaphore_Destroy()

void Semaphore_Destroy ( Semaphore sema)

Definition at line 39 of file semaphore.c.

40{
42 LIST_REMOVE(sema, semaphoreList);
44
45 Spinlock_Destroy(&sema->lock);
46}
#define LIST_REMOVE(elm, field)
Definition: queue.h:465
void Spinlock_Destroy(Spinlock *lock)
Definition: spinlock.c:61
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Semaphore_Release()

void Semaphore_Release ( Semaphore sema)

Definition at line 72 of file semaphore.c.

73{
74 Thread *thr;
75
76 Spinlock_Lock(&sema->lock);
77 sema->count += 1;
78
79 // Wakeup thread
80 thr = TAILQ_FIRST(&sema->waiters);
81 if (thr != NULL) {
82 TAILQ_REMOVE(&sema->waiters, thr, semaQueue);
84 }
85 Spinlock_Unlock(&sema->lock);
86}
void Sched_SetRunnable(Thread *thr)
Definition: sched.c:77
#define TAILQ_FIRST(head)
Definition: queue.h:555
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:659
#define NULL
Definition: stddef.h:6
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Semaphore_TryAcquire()

bool Semaphore_TryAcquire ( Semaphore sema)

Definition at line 89 of file semaphore.c.

90{
91 Spinlock_Lock(&sema->lock);
92 if (sema->count > 0) {
93 sema->count -= 1;
94 Spinlock_Unlock(&sema->lock);
95 return true;
96 }
97 Spinlock_Unlock(&sema->lock);
98 return false;
99}
Here is the call graph for this function:

Variable Documentation

◆ semaListLock

Spinlock semaListLock = { 0, 0, 0, 0, 0, 0, 0, 0, "Semaphore List" }

Definition at line 19 of file semaphore.c.