os-k/src/kaleid/kernel/ke/lock.h

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