1
/*
2
* \brief Basic locking primitive
3
* \author Norman Feske
4
* \date 2006-07-26
5
*/
6
7
/*
8
* Copyright (C) 2006-2013 Genode Labs GmbH
9
*
10
* This file is part of the Genode OS framework, which is distributed
11
* under the terms of the GNU General Public License version 2.
12
*/
13
14
#
ifndef _INCLUDE__BASE__CANCELABLE_LOCK_H_
15
#
define _INCLUDE__BASE__CANCELABLE_LOCK_H_
16
17
#
include <base/lock_guard.h>
18
#
include <base/blocking.h>
19
20
namespace
Genode {
21
22
class
Thread_base;
23
class
Cancelable_lock;
24
}
25
26
27
class
Genode::
Cancelable_lock
28
{
29
private
:
30
31
class
Applicant
32
{
33
private
:
34
35
Thread_base *
_thread_base;
36
Applicant *
_to_wake_up;
37
38
public
:
39
40
explicit
Applicant(
Thread_base *
thread_base
)
41
:
_thread_base(
thread_base)
,
_to_wake_up(
0)
{
}
42
43
void
applicant_to_wake_up(
Applicant *
to_wake_up
)
{
44
_to_wake_up =
to_wake_up;
}
45
46
Applicant *
applicant_to_wake_up(
)
{
return
_to_wake_up
;
}
47
48
Thread_base *
thread_base(
)
{
return
_thread_base
;
}
49
50
/**
51
* Called from previous lock owner
52
*/
53
void
wake_up(
)
;
54
55
bool
operator
==
(
Applicant &
a
)
{
return
_thread_base ==
a.
thread_base(
)
;
}
56
bool
operator
!=
(
Applicant &
a
)
{
return
_thread_base !=
a.
thread_base(
)
;
}
57
}
;
58
59
/*
60
* Note that modifications of the applicants queue must be performed
61
* atomically. Hence, we use the additional spinlock here.
62
*/
63
64
volatile
int _spinlock_state;
65
volatile
int _state;
66
67
Applicant*
volatile
_last_applicant;
68
Applicant _owner;
69
70
public
:
71
72
enum
State {
LOCKED
,
UNLOCKED
}
;
73
74
/**
75
* Constructor
76
*/
77
explicit
Cancelable_lock(
State
initial
=
UNLOCKED
)
;
78
79
/**
80
* Try to aquire the lock and block while the lock is not free
81
*
82
* \throw Genode::Blocking_canceled
83
*/
84
void
lock(
)
;
85
86
/**
87
* Release lock
88
*/
89
void
unlock(
)
;
90
91
/**
92
* Lock guard
93
*/
94
typedef
Genode::
Lock_guard<
Cancelable_lock
>
Guard
;
95
}
;
96
97
#
endif /* _INCLUDE__BASE__CANCELABLE_LOCK_H_ */