blob: fe54fe110d5223e592a9564b8efa4c9d59c0903b [file]
/* Copyright 2024 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef __LIBC_RECURSIVE_MUTEX_H
#define __LIBC_RECURSIVE_MUTEX_H
#include "atomic_t.h"
#include "task.h"
enum mutex_r_state {
MUTEX_R_UNLOCKED = 0,
MUTEX_R_LOCKED = 1,
MUTEX_R_LOCKED_WAITING = 2,
};
struct mutex_r {
atomic_t state;
atomic_t waiters;
int count;
task_id_t owner;
};
/**
* K_MUTEX_R_DEFINE is a macro that allows to create static mutex without the
* need to initialize it at runtime.
*/
#define K_MUTEX_R_DEFINE(name) \
struct mutex_r name = { \
.state = MUTEX_R_UNLOCKED, \
.waiters = 0, \
.count = 0, \
.owner = -1, \
}
/**
* Initialize recursive mutex.
*/
void mutex_init_recursive(struct mutex_r *mtx);
/**
* Lock a recursive mutex.
*
* If the mutex is unlocked, lock it and set the 'count' to 1.
* If the mutex is already locked by the current task, increase the 'count'
* and let the task go.
* If the mutex is already locked by another task, de-schedules the current
* task until the mutex is again unlocked.
*
* Must not be used in interrupt context!
*/
void mutex_lock_recursive(struct mutex_r *mtx);
/**
* Attempt to lock a recursive mutex
*
* If the mutex is unlocked, lock it, set the 'count' to 1 and return 1
* If the mutex is already locked by the current task, increase the 'count'
* and return 1.
* If the mutex is already locked by another task, return 0.
*
* Must not be used in interrupt context!
*/
int mutex_try_lock_recursive(struct mutex_r *mtx);
/**
* Decrease the 'count' of recursive mutex.
*
* If the 'count' becomes 0, the mutex is unlocked. Must be called on locked
* mutex only.
*
* Must not be used in interrupt context!
*/
void mutex_unlock_recursive(struct mutex_r *mtx);
#endif /* __LIBC_RECURSIVE_MUTEX_H */