1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13/* An implementation of recursive mutexes. Assumptions are similar to pthread
14 * recursive mutexes. That is, the thread that locked the mutex needs to be the
15 * one who unlocks the mutex, mutexes must be unlocked as many times as they
16 * are locked, etc.
17 *
18 * Note that the address of your IPC buffer is used as a thread ID so if you
19 * have a situation where threads share an IPC buffer or do not have a valid
20 * IPC buffer, these locks will not work for you.
21 */
22
23#pragma once
24
25#include <sel4/sel4.h>
26#include <vka/vka.h>
27#include <vka/object.h>
28
29/* This struct is intended to be opaque, but is left here so you can
30 * stack-allocate mutexes. Callers should not touch any of its members.
31 */
32typedef struct {
33    vka_object_t notification;
34    void *owner;
35    unsigned int held;
36} sync_recursive_mutex_t;
37
38/* Initialise an unmanaged recursive mutex with a notification object
39 * @param mutex         A recursive mutex object to be initialised.
40 * @param notification  A notification object to use for the lock.
41 * @return              0 on success, an error code on failure. */
42int sync_recursive_mutex_init(sync_recursive_mutex_t *mutex, seL4_CPtr notification);
43
44/* Acquire a recursive mutex
45 * @param mutex         An initialised recursive mutex to acquire.
46 * @return              0 on success, an error code on failure. */
47int sync_recursive_mutex_lock(sync_recursive_mutex_t *mutex);
48
49/* Release a recursive mutex
50 * @param mutex         An initialised recursive mutex to release.
51 * @return              0 on success, an error code on failure. */
52int sync_recursive_mutex_unlock(sync_recursive_mutex_t *mutex);
53
54/* Allocate and initialise a managed recursive mutex
55 * @param vka           A VKA instance used to allocate a notification object.
56 * @param mutex         A recursive mutex object to initialise.
57 * @return              0 on success, an error code on failure. */
58int sync_recursive_mutex_new(vka_t *vka, sync_recursive_mutex_t *mutex);
59
60/* Deallocate a managed recursive mutex (do not use with sync_mutex_init)
61 * @param vka           A VKA instance used to deallocate the notification object.
62 * @param mutex         A recursive mutex object initialised by sync_recursive_mutex_new.
63 * @return              0 on success, an error code on failure. */
64int sync_recursive_mutex_destroy(vka_t *vka, sync_recursive_mutex_t *mutex);
65
66