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