nckernel
0.1
Main Page
Related Pages
Modules
Data Structures
Files
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
common
src
page_frame.c
Go to the documentation of this file.
1
#include <
sys/types.h
>
2
#include <
stdio.h
>
3
#include <
errno.h
>
4
#include <
stddef.h
>
5
#include <
stdlib.h
>
6
#include <
stdint.h
>
7
#include <
unistd.h
>
8
#include <
string.h
>
9
#include <
pthread.h
>
10
11
#include <
debug.h
>
12
13
#include <
list.h
>
14
#include <
cpu_node.h
>
15
#include <
zone.h
>
16
#include <
page_frame.h
>
17
#include <
page_allocator.h
>
18
19
static
pthread_mutex_t
s_lock =
PTHREAD_MUTEX_INITIALIZER
;
20
21
static
inline
struct
page_frame
*find_frame(
void
*page,
struct
zone
**_zone)
22
{
23
struct
zone
*
zone
;
24
struct
list_head
*pos;
25
struct
list_head
*n;
26
struct
page_frame
*frame;
27
28
zone =
find_zone_by_addr
(page);
29
if
(!zone) {
30
return
NULL
;
31
}
32
33
frame =
NULL
;
34
list_for_each_safe
(pos, n, &zone->
page_list
) {
35
frame =
list_entry
(pos,
struct
page_frame
,
page_head
);
36
if
(frame->
pma
== page) {
37
break
;
38
}
39
40
frame =
NULL
;
41
}
42
43
if
(_zone) {
44
*_zone = zone;
45
}
46
47
return
frame;
48
}
49
50
int
page_frame_init
(
struct
zone *zone,
void
*base,
size_t
size)
51
{
52
void
*
info
;
53
54
info =
malloc
(
page_allocator_info_size
(size));
55
if
(!info) {
56
return
-
ENOMEM
;
57
}
58
59
zone->
handle
=
page_allocator_init
(info, base, size);
60
if
(!zone->
handle
) {
61
free
(info);
62
return
-
EFAULT
;
63
}
64
65
return
0;
66
}
67
68
int
page_frame_fini
(
struct
zone *zone)
69
{
70
struct
list_head
*pos;
71
struct
list_head
*n;
72
struct
page_frame
*frame;
73
74
list_for_each_safe
(pos, n, &zone->
page_list
) {
75
frame =
list_entry
(pos,
struct
page_frame
,
page_head
);
76
page_allocator_free
(zone->
handle
, frame->
pma
);
77
}
78
79
list_for_each_safe
(pos, n, &zone->
managed_page_list
) {
80
frame =
list_entry
(pos,
struct
page_frame
,
page_head
);
81
list_del(&frame->
page_head
);
82
free
(frame);
83
}
84
85
return
0;
86
}
87
92
void
*
page_frame_alloc
(
enum
zone_type
zone_type
,
size_t
nr_of_pages)
93
{
94
struct
page_frame
*frame;
95
struct
zone *zone;
96
void
*ret =
NULL
;
97
98
pthread_mutex_lock
(&s_lock);
99
NEED_LOCK_TEST_BEGIN
100
101
zone =
find_zone
(zone_type);
102
if
(!zone) {
103
dbg_printf
(
"Failed to find a zone\n"
);
104
goto
out;
105
}
106
107
frame =
malloc
(
sizeof
(*frame));
108
if
(!frame) {
109
dbg_printf
(
"Failed to allocate frame\n"
);
110
goto
out;
111
}
112
113
frame->
pma
=
page_allocator_alloc
(zone->handle, nr_of_pages);
114
if
(frame->
pma
== (
void
*)-1) {
115
free
(frame);
116
dbg_printf
(
"Failed to allocate a page\n"
);
117
goto
out;
118
}
119
120
frame->
refcnt
= 1;
121
list_add_tail(&frame->
page_head
, &zone->page_list);
122
123
ret = frame->
pma
;
124
125
out:
126
NEED_LOCK_TEST_END
127
pthread_mutex_unlock
(&s_lock);
128
return
ret;
129
}
130
131
int
page_frame_free
(
void
*page)
132
{
133
struct
page_frame
*frame;
134
struct
zone *zone;
135
int
ret = 0;
136
137
pthread_mutex_lock
(&s_lock);
138
NEED_LOCK_TEST_BEGIN
139
140
frame = find_frame(page, &zone);
141
if
(!frame) {
142
ret = -
EINVAL
;
143
goto
out;
144
}
145
146
frame->refcnt--;
147
if
(frame->refcnt > 0) {
148
goto
out;
149
}
150
151
page_allocator_free
(zone->
handle
, frame->pma);
152
list_del(&frame->page_head);
153
free
(frame);
154
155
out:
156
NEED_LOCK_TEST_END
157
pthread_mutex_unlock
(&s_lock);
158
return
ret;
159
}
160
161
int
page_frame_ref
(
void
*page)
162
{
163
struct
page_frame
*frame;
164
int
ret = 0;
165
166
pthread_mutex_lock
(&s_lock);
167
NEED_LOCK_TEST_BEGIN
168
169
frame = find_frame(page,
NULL
);
170
if
(!frame) {
171
ret = -
ENOENT
;
172
goto
out;
173
}
174
175
frame->refcnt++;
176
177
out:
178
NEED_LOCK_TEST_END
179
pthread_mutex_unlock
(&s_lock);
180
return
ret;
181
}
182
183
int
page_frame_refcnt
(
void
*page)
184
{
185
struct
page_frame
*frame;
186
int
refcnt
;
187
188
pthread_mutex_lock
(&s_lock);
189
NEED_LOCK_TEST_BEGIN
190
191
frame = find_frame(page,
NULL
);
192
if
(!frame) {
193
refcnt = -
ENOENT
;
194
goto
out;
195
}
196
197
refcnt = frame->refcnt;
198
199
out:
200
NEED_LOCK_TEST_END
201
pthread_mutex_unlock
(&s_lock);
202
return
refcnt
;
203
}
204
205
int
page_frame_manage
(
enum
zone_type
type,
void
*page,
int
nr_of_pages)
206
{
207
struct
page_frame
*frame;
208
struct
zone *zone;
209
int
ret = 0;
210
211
pthread_mutex_lock
(&s_lock);
212
NEED_LOCK_TEST_BEGIN
213
214
frame = find_frame(page,
NULL
);
215
if
(frame) {
216
ret = -
EEXIST
;
217
goto
out;
218
}
219
220
zone =
find_zone
(type);
221
if
(!zone) {
222
ret = -
EINVAL
;
223
goto
out;
224
}
225
226
frame =
malloc
(
sizeof
(*frame));
227
if
(!frame) {
228
ret = -
ENOMEM
;
229
goto
out;
230
}
231
232
frame->pma = page;
233
frame->refcnt = 1;
234
235
list_add_tail(&frame->page_head, &zone->
managed_page_list
);
236
237
out:
238
NEED_LOCK_TEST_END
239
pthread_mutex_unlock
(&s_lock);
240
return
ret;
241
}
242
243
/* @} End of a file */
Generated on Thu Nov 7 2013 02:45:25 for nckernel by
1.8.4