Whamcloud - gitweb
b=16098
[fs/lustre-release.git] / libcfs / libcfs / winnt / winnt-mem.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #define DEBUG_SUBSYSTEM S_LNET
38
39 #include <libcfs/libcfs.h>
40
41
42 cfs_mem_cache_t *cfs_page_t_slab = NULL;
43 cfs_mem_cache_t *cfs_page_p_slab = NULL;
44
45 /*
46  * cfs_alloc_page
47  *   To allocate the cfs_page_t and also 1 page of memory
48  *
49  * Arguments:
50  *   flags:  the allocation options
51  *
52  * Return Value:
53  *   pointer to the cfs_page_t strcture in success or
54  *   NULL in failure case
55  *
56  * Notes: 
57  *   N/A
58  */
59
60 cfs_page_t * cfs_alloc_page(int flags)
61 {
62     cfs_page_t *pg;
63     pg = cfs_mem_cache_alloc(cfs_page_t_slab, 0);
64     
65     if (NULL == pg) {
66         cfs_enter_debugger();
67         return NULL;
68     }
69
70     memset(pg, 0, sizeof(cfs_page_t));
71     pg->addr = cfs_mem_cache_alloc(cfs_page_p_slab, 0);
72     atomic_set(&pg->count, 1);
73
74     if (pg->addr) {
75         if (cfs_is_flag_set(flags, CFS_ALLOC_ZERO)) {
76             memset(pg->addr, 0, CFS_PAGE_SIZE);
77         }
78     } else {
79         cfs_enter_debugger();
80         cfs_mem_cache_free(cfs_page_t_slab, pg);
81         pg = NULL;
82     }
83
84     return pg;
85 }
86
87 /*
88  * cfs_free_page
89  *   To free the cfs_page_t including the page
90  *
91  * Arguments:
92  *   pg:  pointer to the cfs_page_t strcture
93  *
94  * Return Value:
95  *   N/A
96  *
97  * Notes: 
98  *   N/A
99  */
100 void cfs_free_page(cfs_page_t *pg)
101 {
102     ASSERT(pg != NULL);
103     ASSERT(pg->addr  != NULL);
104     ASSERT(atomic_read(&pg->count) <= 1);
105
106     cfs_mem_cache_free(cfs_page_p_slab, pg->addr);
107     cfs_mem_cache_free(cfs_page_t_slab, pg);
108 }
109
110
111 /*
112  * cfs_alloc
113  *   To allocate memory from system pool
114  *
115  * Arguments:
116  *   nr_bytes:  length in bytes of the requested buffer
117  *   flags:     flags indiction
118  *
119  * Return Value:
120  *   NULL: if there's no enough memory space in system
121  *   the address of the allocated memory in success.
122  *
123  * Notes: 
124  *   This operation can be treated as atomic.
125  */
126
127 void *
128 cfs_alloc(size_t nr_bytes, u_int32_t flags)
129 {
130         void *ptr;
131
132     /* Ignore the flags: always allcoate from NonPagedPool */
133
134         ptr = ExAllocatePoolWithTag(NonPagedPool, nr_bytes, 'Lufs');
135
136         if (ptr != NULL && (flags & CFS_ALLOC_ZERO)) {
137                 memset(ptr, 0, nr_bytes);
138     }
139
140     if (!ptr) {
141         cfs_enter_debugger();
142     }
143
144         return ptr;
145 }
146
147 /*
148  * cfs_free
149  *   To free the sepcified memory to system pool
150  *
151  * Arguments:
152  *   addr:   pointer to the buffer to be freed
153  *
154  * Return Value:
155  *   N/A
156  *
157  * Notes: 
158  *    This operation can be treated as atomic.
159  */
160
161 void
162 cfs_free(void *addr)
163 {
164         ExFreePool(addr);
165 }
166
167 /*
168  * cfs_alloc_large
169  *   To allocate large block of memory from system pool
170  *
171  * Arguments:
172  *   nr_bytes:  length in bytes of the requested buffer
173  *
174  * Return Value:
175  *   NULL: if there's no enough memory space in system
176  *   the address of the allocated memory in success.
177  *
178  * Notes: 
179  *   N/A
180  */
181
182 void *
183 cfs_alloc_large(size_t nr_bytes)
184 {
185         return cfs_alloc(nr_bytes, 0);
186 }
187
188 /*
189  * cfs_free_large
190  *   To free the sepcified memory to system pool
191  *
192  * Arguments:
193  *   addr:   pointer to the buffer to be freed
194  *
195  * Return Value:
196  *   N/A
197  *
198  * Notes: 
199  *   N/A
200  */
201
202 void
203 cfs_free_large(void *addr)
204 {
205         cfs_free(addr);
206 }
207
208
209 /*
210  * cfs_mem_cache_create
211  *   To create a SLAB cache
212  *
213  * Arguments:
214  *   name:   name string of the SLAB cache to be created
215  *   size:   size in bytes of SLAB entry buffer
216  *   offset: offset in the page
217  *   flags:  SLAB creation flags
218 *
219  * Return Value:
220  *   The poitner of cfs_memory_cache structure in success.
221  *   NULL pointer in failure case.
222  *
223  * Notes: 
224  *   1, offset won't be used here.
225  *   2, it could be better to induce a lock to protect the access of the
226  *       SLAB structure on SMP if there's not outside lock protection.
227  *   3, parameters C/D are removed.
228  */
229
230 cfs_mem_cache_t *
231 cfs_mem_cache_create(
232     const char * name,
233     size_t size,
234     size_t offset,
235     unsigned long flags
236     )
237 {
238     cfs_mem_cache_t * kmc = NULL;
239
240     /*  The name of the SLAB could not exceed 20 chars */
241
242     if (name && strlen(name) >= 20) {
243         goto errorout;
244     }
245
246     /* Allocate and initialize the SLAB strcture */
247
248     kmc = cfs_alloc (sizeof(cfs_mem_cache_t), 0);
249
250     if (NULL == kmc) {
251         goto errorout;
252     }
253
254     memset(kmc, 0, sizeof(cfs_mem_cache_t));
255
256     kmc->flags = flags;
257
258     if (name) {
259         strcpy(&kmc->name[0], name);
260     }
261
262     /* Initialize the corresponding LookAside list */
263
264     ExInitializeNPagedLookasideList(
265             &(kmc->npll),
266             NULL,
267             NULL,
268             0,
269             size,
270             'pnmk',
271             0);
272  
273 errorout:
274
275     return kmc;
276 }
277
278 /*
279  * cfs_mem_cache_destroy
280  *   To destroy the unused SLAB cache
281  *
282  * Arguments:
283  *   kmc: the SLAB cache to be destroied.
284  *
285  * Return Value:
286  *   0: in success case.
287  *   1: in failure case.
288  *
289  * Notes: 
290  *   N/A
291  */
292
293 int cfs_mem_cache_destroy (cfs_mem_cache_t * kmc)
294 {
295     ASSERT(kmc != NULL);
296
297     ExDeleteNPagedLookasideList(&(kmc->npll));
298
299     cfs_free(kmc);
300
301     return 0;
302 }
303
304 /*
305  * cfs_mem_cache_alloc
306  *   To allocate an object (LookAside entry) from the SLAB
307  *
308  * Arguments:
309  *   kmc:   the SLAB cache to be allocated from.
310  *   flags: flags for allocation options
311  *
312  * Return Value:
313  *   object buffer address: in success case.
314  *   NULL: in failure case.
315  *
316  * Notes: 
317  *   N/A
318  */
319
320 void *cfs_mem_cache_alloc(cfs_mem_cache_t * kmc, int flags)
321 {
322     void *buf = NULL;
323
324     buf = ExAllocateFromNPagedLookasideList(&(kmc->npll));
325
326     return buf;
327 }
328
329 /*
330  * cfs_mem_cache_free
331  *   To free an object (LookAside entry) to the SLAB cache
332  *
333  * Arguments:
334  *   kmc: the SLAB cache to be freed to.
335  *   buf: the pointer to the object to be freed.
336  *
337  * Return Value:
338  *   N/A
339  *
340  * Notes: 
341  *   N/A
342  */
343
344 void cfs_mem_cache_free(cfs_mem_cache_t * kmc, void * buf)
345 {
346     ExFreeToNPagedLookasideList(&(kmc->npll), buf);
347 }