Whamcloud - gitweb
b=16098
[fs/lustre-release.git] / libcfs / include / libcfs / user-prim.h
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 [sun.com URL with a
20  * copy of GPLv2].
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  * libcfs/include/libcfs/user-prim.h
37  *
38  * Author: Nikita Danilov <nikita@clusterfs.com>
39  */
40
41 #ifndef __LIBCFS_USER_PRIM_H__
42 #define __LIBCFS_USER_PRIM_H__
43
44 #ifndef __LIBCFS_LIBCFS_H__
45 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
46 #endif
47
48 /* Implementations of portable APIs for liblustre */
49
50 /*
51  * liblustre is single-threaded, so most "synchronization" APIs are trivial.
52  */
53
54 #ifndef __KERNEL__
55
56 #include <stdlib.h>
57 #include <string.h>
58 #include <sys/signal.h>
59 #include <sys/mman.h>
60 #include <libcfs/list.h>
61 #include <libcfs/user-time.h>
62 #include <signal.h>
63 #include <stdlib.h>
64 #include <unistd.h>
65
66 #ifdef HAVE_LIBPTHREAD
67 #include <pthread.h>
68 #endif
69
70
71 /*
72  * Wait Queue. No-op implementation.
73  */
74
75 typedef struct cfs_waitlink {
76         struct list_head sleeping;
77         void *process;
78 } cfs_waitlink_t;
79
80 typedef struct cfs_waitq {
81         struct list_head sleepers;
82 } cfs_waitq_t;
83
84 void cfs_waitq_init(struct cfs_waitq *waitq);
85 void cfs_waitlink_init(struct cfs_waitlink *link);
86 void cfs_waitq_add(struct cfs_waitq *waitq, struct cfs_waitlink *link);
87 void cfs_waitq_add_exclusive(struct cfs_waitq *waitq, 
88                              struct cfs_waitlink *link);
89 void cfs_waitq_forward(struct cfs_waitlink *link, struct cfs_waitq *waitq);
90 void cfs_waitq_del(struct cfs_waitq *waitq, struct cfs_waitlink *link);
91 int  cfs_waitq_active(struct cfs_waitq *waitq);
92 void cfs_waitq_signal(struct cfs_waitq *waitq);
93 void cfs_waitq_signal_nr(struct cfs_waitq *waitq, int nr);
94 void cfs_waitq_broadcast(struct cfs_waitq *waitq);
95 void cfs_waitq_wait(struct cfs_waitlink *link, int state);
96 int64_t cfs_waitq_timedwait(struct cfs_waitlink *link, int state, int64_t timeout);
97 #define cfs_schedule_timeout(s, t)              \
98         do {                                    \
99                 cfs_waitlink_t    l;            \
100                 cfs_waitq_timedwait(&l, s, t);  \
101         } while (0)
102
103 #define CFS_TASK_INTERRUPTIBLE  (0)
104 #define CFS_TASK_UNINT          (0)
105
106 /* 2.4 defines */
107
108 /* XXX
109  * for this moment, liblusre will not rely OST for non-page-aligned write
110  */
111 #define LIBLUSTRE_HANDLE_UNALIGNED_PAGE
112
113 struct page {
114         void   *addr;
115         unsigned long index;
116         struct list_head list;
117         unsigned long private;
118
119         /* internally used by liblustre file i/o */
120         int     _offset;
121         int     _count;
122 #ifdef LIBLUSTRE_HANDLE_UNALIGNED_PAGE
123         int     _managed;
124 #endif
125         struct list_head _node;
126 };
127
128 typedef struct page cfs_page_t;
129
130 #ifndef PAGE_SIZE
131
132 /* 4K */
133 #define CFS_PAGE_SHIFT 12
134 #define CFS_PAGE_SIZE (1UL << CFS_PAGE_SHIFT)
135 #define CFS_PAGE_MASK (~((__u64)CFS_PAGE_SIZE-1))
136
137 #else
138
139 #define CFS_PAGE_SIZE                   PAGE_SIZE
140 #define CFS_PAGE_SHIFT                  PAGE_SHIFT
141 #define CFS_PAGE_MASK                   (~((__u64)CFS_PAGE_SIZE-1))
142
143 #endif
144
145 cfs_page_t *cfs_alloc_page(unsigned int flags);
146 void cfs_free_page(cfs_page_t *pg);
147 void *cfs_page_address(cfs_page_t *pg);
148 void *cfs_kmap(cfs_page_t *pg);
149 void cfs_kunmap(cfs_page_t *pg);
150
151 #define cfs_get_page(p)                 __I_should_not_be_called__(at_all)
152 #define cfs_page_count(p)               __I_should_not_be_called__(at_all)
153 #define cfs_page_index(p)               ((p)->index)
154
155 /*
156  * Memory allocator
157  * Inline function, so utils can use them without linking of libcfs
158  */
159 #define __ALLOC_ZERO    (1 << 2)
160 static inline void *cfs_alloc(size_t nr_bytes, u_int32_t flags)
161 {
162         void *result;
163
164         result = malloc(nr_bytes);
165         if (result != NULL && (flags & __ALLOC_ZERO))
166                 memset(result, 0, nr_bytes);
167         return result;
168 }
169
170 #define cfs_free(addr)  free(addr)
171 #define cfs_alloc_large(nr_bytes) cfs_alloc(nr_bytes, 0)
172 #define cfs_free_large(addr) cfs_free(addr)
173
174 #define CFS_ALLOC_ATOMIC_TRY   (0)
175 /*
176  * SLAB allocator
177  */
178 typedef struct {
179          int size;
180 } cfs_mem_cache_t;
181
182 #define SLAB_HWCACHE_ALIGN 0
183 #define SLAB_KERNEL 0
184 #define SLAB_NOFS 0
185
186 cfs_mem_cache_t *
187 cfs_mem_cache_create(const char *, size_t, size_t, unsigned long);
188 int cfs_mem_cache_destroy(cfs_mem_cache_t *c);
189 void *cfs_mem_cache_alloc(cfs_mem_cache_t *c, int gfp);
190 void cfs_mem_cache_free(cfs_mem_cache_t *c, void *addr);
191
192 typedef int (cfs_read_proc_t)(char *page, char **start, off_t off,
193                           int count, int *eof, void *data);
194
195 struct file; /* forward ref */
196 typedef int (cfs_write_proc_t)(struct file *file, const char *buffer,
197                                unsigned long count, void *data);
198
199 /*
200  * Signal
201  */
202 typedef sigset_t                        cfs_sigset_t;
203
204 /*
205  * Timer
206  */
207 #include <sys/time.h>
208
209 typedef struct {
210         struct list_head tl_list;
211         void (*function)(unsigned long unused);
212         unsigned long data;
213         long expires;
214 } cfs_timer_t;
215
216 #define cfs_init_timer(t)       do {} while(0)
217 #define cfs_jiffies                             \
218 ({                                              \
219         unsigned long _ret = 0;                 \
220         struct timeval tv;                      \
221         if (gettimeofday(&tv, NULL) == 0)       \
222                 _ret = tv.tv_sec;               \
223         _ret;                                   \
224 })
225
226 static inline int cfs_timer_init(cfs_timer_t *l, void (* func)(unsigned long), void *arg)
227 {
228         CFS_INIT_LIST_HEAD(&l->tl_list);
229         l->function = func;
230         l->data = (unsigned long)arg;
231         return 0;
232 }
233
234 static inline int cfs_timer_is_armed(cfs_timer_t *l)
235 {
236         if (cfs_time_before(cfs_jiffies, l->expires))
237                 return 1;
238         else
239                 return 0;
240 }
241
242 static inline void cfs_timer_arm(cfs_timer_t *l, int thetime)
243 {
244         l->expires = thetime;
245 }
246
247 static inline void cfs_timer_disarm(cfs_timer_t *l)
248 {
249 }
250
251 static inline long cfs_timer_deadline(cfs_timer_t *l)
252 {
253         return l->expires;
254 }
255
256 #if 0
257 #define cfs_init_timer(t)       do {} while(0)
258 void cfs_timer_init(struct cfs_timer *t, void (*func)(unsigned long), void *arg);
259 void cfs_timer_done(struct cfs_timer *t);
260 void cfs_timer_arm(struct cfs_timer *t, cfs_time_t deadline);
261 void cfs_timer_disarm(struct cfs_timer *t);
262 int  cfs_timer_is_armed(struct cfs_timer *t);
263
264 cfs_time_t cfs_timer_deadline(struct cfs_timer *t);
265 #endif
266
267 #define in_interrupt()    (0)
268
269 static inline void cfs_pause(cfs_duration_t d)
270 {
271         struct timespec s;
272         
273         cfs_duration_nsec(d, &s);
274         nanosleep(&s, NULL);
275 }
276
277 typedef void cfs_psdev_t;
278
279 static inline int cfs_psdev_register(cfs_psdev_t *foo)
280 {
281         return 0;
282 }
283
284 static inline int cfs_psdev_deregister(cfs_psdev_t *foo)
285 {
286         return 0;
287 }
288
289 #define cfs_lock_kernel()               do {} while (0)
290 #define cfs_sigfillset(l) do {}         while (0)
291 #define cfs_recalc_sigpending(l)        do {} while (0)
292 #define cfs_kernel_thread(l,m,n)        LBUG()
293
294 #ifdef HAVE_LIBPTHREAD
295 typedef int (*cfs_thread_t)(void *);
296 int cfs_create_thread(cfs_thread_t func, void *arg);
297 #else
298 #define cfs_create_thread(l,m) LBUG()
299 #endif
300
301 int cfs_parse_int_tunable(int *value, char *name);
302 uid_t cfs_curproc_uid(void);
303
304 #define LIBCFS_REALLOC(ptr, size) realloc(ptr, size)
305
306 #define cfs_online_cpus() sysconf(_SC_NPROCESSORS_ONLN)
307
308 // static inline void local_irq_save(unsigned long flag) {return;}
309 // static inline void local_irq_restore(unsigned long flag) {return;}
310
311 enum {
312         CFS_STACK_TRACE_DEPTH = 16
313 };
314
315 struct cfs_stack_trace {
316         void *frame[CFS_STACK_TRACE_DEPTH];
317 };
318
319 /*
320  * arithmetic
321  */
322 #define do_div(a,b)                     \
323         ({                              \
324                 unsigned long remainder;\
325                 remainder = (a) % (b);  \
326                 (a) = (a) / (b);        \
327                 (remainder);            \
328         })
329
330 /* !__KERNEL__ */
331 #endif
332
333 /* __LIBCFS_USER_PRIM_H__ */
334 #endif
335 /*
336  * Local variables:
337  * c-indentation-style: "K&R"
338  * c-basic-offset: 8
339  * tab-width: 8
340  * fill-column: 80
341  * scroll-step: 1
342  * End:
343  */