📄 semaphore.c
字号:
os_semaphore* CreateSemaphore(UCHAR semVal)
{
os_semaphore* temp_semaphore;
temp_semaphore = (os_thread*)g_freesemaphores;
if (temp_semaphore == NULL) return -1;
// pop a free thread from the list
g_freesemaphores = temp_semaphore->next;
g_freesemaphores->prev = NULL;
// push the free thread on the used threads list
temp_semaphore->next = g_usedsemaphores;
g_usedsemaphores->prev = temp_semaphore;
g_usedsemaphores = temp_semaphore;
temp_semaphore->remaining = semVal;
return temp_semaphore;
}
/*
void FreeSemaphore(os_semaphore* semaphore)
{
// this is harder than threadsem since its not always equal g_usedsemaphores
}
*/
os_threadsem* CreateThreadSem(os_thread *thread)
{
os_threadsem* temp_threadsem;
temp_threadsem = (os_thread*)g_freethreadsems;
if (temp_threadsem == NULL) return -1;
// pop a free thread from the list
g_freethreadsems = temp_threadsem->next;
// push the free thread on the used threads list
temp_threadsem->next = g_usedthreadsems;
g_usedthreadsems = temp_threadsem;
temp_threadsem->thread = thread;
return temp_threadsem;
}
void FreeThreadSem(os_threadsem* threadsem)
{
// threadsem should always equal g_usedthreadsem since its a queue
g_usedthreadsems = threadsem->next;
threadsem->next = g_freethreadsems;
g_freethreadsems = threadsem;
}
// return 1 if you had to wait at all
UCHAR WaitSemaphore(os_semaphore* semaphore)
{
register UCHAR ret;
os_threadsem *temp_threadsem;
#asm("cli");
ret = 1;
if (semaphore->remaining > 0)
{
--(semaphore->remaining);
ret = 0;
}
else
{
if (semaphore->queue != NULL)
{
// we have to wait
temp_threadsem = semaphore->queue;
while (temp_threadsem->next != NULL)
{
temp_threadsem = temp_threadsem->next;
}
temp_threadsem->next = CreateThreadSem(g_currthread);
}
else
{
semaphore->queue = CreateThreadSem(g_currthread);
}
g_currthread->state = THREADSTATE_BLOCKED;
os_schedule();
}
#asm("sei");
return ret;
}
void SignalSemaphore(os_semaphore* semaphore)
{
os_threadsem* temp_threadsem;
#asm("cli");
if (semaphore->queue == NULL)
{
++semaphore->remaining;
}
else
{
// pop first in off
temp_threadsem = semaphore->queue;
semaphore->queue = temp_threadsem->next;
temp_threadsem->thread->state = THREADSTATE_RUNNING;
FreeThreadSem(temp_threadsem);
os_schedule();
}
#asm("sei");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -