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