99 lines
2.9 KiB
C
99 lines
2.9 KiB
C
//----------------------------------------------------------------------------//
|
|
// GNU GPL OS/K //
|
|
// //
|
|
// Authors: spectral` //
|
|
// NeoX //
|
|
// //
|
|
// Desc: Locks //
|
|
//----------------------------------------------------------------------------//
|
|
|
|
#ifndef _KALKERN_KE_LOCK_H
|
|
#define _KALKERN_KE_LOCK_H
|
|
|
|
#ifndef _KALKERN_H
|
|
#include <kalkern.h>
|
|
#endif
|
|
|
|
enum lock_type {
|
|
//
|
|
// Mutex-type lock
|
|
//
|
|
// WARNING
|
|
// AquireLock() panics when used on a mutex while not running a process
|
|
//
|
|
KLOCK_MUTEX,
|
|
|
|
//
|
|
// Spinlock-type lock
|
|
// Turns into a Mutex-type lock when MULTIPROCESSOR is off
|
|
//
|
|
KLOCK_SPINLOCK,
|
|
|
|
};
|
|
|
|
typedef struct {
|
|
uchar lk_type; // lock type?
|
|
uint lk_lock; // is locked?
|
|
void *lk_owner; // unused
|
|
void *lk_waiting; // unused
|
|
uint lk_init; // unused if _NO_DEBUG
|
|
} lock_t;
|
|
|
|
//
|
|
// Initialize a lock
|
|
//
|
|
#define InitLock(lk, type) \
|
|
do { \
|
|
(lk)->lk_type = (type); \
|
|
(lk)->lk_lock = FALSE; \
|
|
(lk)->lk_owner = NULL; \
|
|
(lk)->lk_waiting = NULL; \
|
|
(lk)->lk_init = INITOK; \
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Alternative way to initalize a lock
|
|
//
|
|
#define INITLOCK(type) { (type), FALSE, NULL, NULL, INITOK }
|
|
|
|
//
|
|
// Does nothing
|
|
//
|
|
#define DestroyLock(lk) ((lk)->lk_init = FALSE)
|
|
|
|
//
|
|
// Aquires the lock
|
|
// Panics on double aquisition since that should never happen
|
|
// until we have at least a basic scheduler
|
|
//
|
|
#define AquireLock(lk) \
|
|
do { \
|
|
DisableInterrupts(); \
|
|
Assert((lk)->lk_init == INITOK); \
|
|
if ((lk)->lk_lock++) \
|
|
StartPanic("DosAquireLock on an already locked object"); \
|
|
EnableInterrupts(); \
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Releases an already aquired lock
|
|
// Panics if the lock was never aquired (this will change)
|
|
//
|
|
#define ReleaseLock(lk) \
|
|
do { \
|
|
DisableInterrupts(); \
|
|
Assert((lk)->lk_init == INITOK); \
|
|
if ((lk)->lk_lock++) \
|
|
StartPanic("DosReleaseLock on an unlocked object"); \
|
|
EnableInterrupts(); \
|
|
} while (FALSE);
|
|
|
|
//
|
|
// Tries to aquire lock
|
|
// Doesn't work at all for obvious reasons
|
|
//
|
|
#define AttemptLock(lk) ((lk)->lk_lock++)
|
|
|
|
#endif
|
|
|