1 #ifndef __LIBCFS_DARWIN_CFS_PRIM_H__
2 #define __LIBCFS_DARWIN_CFS_PRIM_H__
4 #ifndef __LIBCFS_LIBCFS_H__
5 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
10 #include <sys/systm.h>
13 # ifndef __APPLE_API_PRIVATE
14 # define __APPLE_API_PRIVATE
15 # include <sys/user.h>
16 # undef __APPLE_API_PRIVATE
18 # include <sys/user.h>
20 # include <mach/mach_traps.h>
21 # include <mach/thread_switch.h>
22 # include <machine/cpu_number.h>
23 #endif /* !__DARWIN8__ */
25 #include <sys/kernel.h>
27 #include <mach/thread_act.h>
28 #include <mach/mach_types.h>
29 #include <mach/time_value.h>
30 #include <kern/sched_prim.h>
32 #include <vm/vm_kern.h>
33 #include <mach/machine/vm_param.h>
34 #include <machine/machine_routines.h>
35 #include <kern/clock.h>
36 #include <kern/thread_call.h>
37 #include <sys/param.h>
40 #include <libcfs/darwin/darwin-types.h>
41 #include <libcfs/darwin/darwin-utils.h>
42 #include <libcfs/darwin/darwin-lock.h>
45 * Symbol functions for libcfs
47 * OSX has no facility for use to register symbol.
48 * So we have to implement it.
50 #define CFS_SYMBOL_LEN 64
53 char name[CFS_SYMBOL_LEN];
56 struct list_head sym_list;
59 extern kern_return_t cfs_symbol_register(const char *, const void *);
60 extern kern_return_t cfs_symbol_unregister(const char *);
61 extern void * cfs_symbol_get(const char *);
62 extern kern_return_t cfs_symbol_put(const char *);
67 * User can register/unregister a list of sysctl_oids
68 * sysctl_oid is data struct of osx's sysctl-entry
70 #define CONFIG_SYSCTL 1
72 typedef struct sysctl_oid * cfs_sysctl_table_t;
73 typedef cfs_sysctl_table_t cfs_sysctl_table_header_t;
74 cfs_sysctl_table_header_t *cfs_register_sysctl_table (cfs_sysctl_table_t *table, int arg);
75 void cfs_unregister_sysctl_table (cfs_sysctl_table_header_t *table);
78 * Proc file system APIs, no /proc fs support in OSX
80 typedef struct cfs_proc_dir_entry {
82 } cfs_proc_dir_entry_t;
84 cfs_proc_dir_entry_t * cfs_create_proc_entry(char *name, int mod,
85 cfs_proc_dir_entry_t *parent);
86 void cfs_free_proc_entry(cfs_proc_dir_entry_t *de);
87 void cfs_remove_proc_entry(char *name, cfs_proc_dir_entry_t *entry);
89 typedef int (cfs_read_proc_t)(char *page, char **start, off_t off,
90 int count, int *eof, void *data);
91 typedef int (cfs_write_proc_t)(struct file *file, const char *buffer,
92 unsigned long count, void *data);
99 * cfs_psdev_deregister:
105 struct cdevsw *devsw;
109 extern kern_return_t cfs_psdev_register(cfs_psdev_t *);
110 extern kern_return_t cfs_psdev_deregister(cfs_psdev_t *);
113 * Task struct and ...
115 * Using BSD current_proc in Darwin
117 extern boolean_t assert_wait_possible(void);
118 extern void *get_bsdtask_info(task_t);
122 typedef struct {} cfs_task_t;
123 #define cfs_current() ((cfs_task_t *)current_thread())
124 #else /* !__DARWIN8__ */
126 typedef struct uthread cfs_task_t;
128 #define current_uthread() ((struct uthread *)get_bsdthread_info(current_act()))
129 #define cfs_current() current_uthread()
131 #endif /* !__DARWIN8__ */
133 #define cfs_task_lock(t) do {;} while (0)
134 #define cfs_task_unlock(t) do {;} while (0)
136 #define set_current_state(s) do {;} while (0)
138 #define CFS_DECL_JOURNAL_DATA
139 #define CFS_PUSH_JOURNAL do {;} while(0)
140 #define CFS_POP_JOURNAL do {;} while(0)
142 #define THREAD_NAME(comm, fmt, a...)
146 * OSX kernel thread can not be created with args,
147 * so we have to implement new APIs to create thread with args
150 typedef int (*cfs_thread_t)(void *);
152 extern task_t kernel_task;
155 * cloning flags, no use in OSX, just copy them from Linux
157 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
158 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
159 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
160 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
161 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */
162 #define CLONE_PID 0x00001000 /* set if pid shared */
163 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
164 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
165 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
166 #define CLONE_THREAD 0x00010000 /* Same thread group? */
167 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
169 #define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD)
171 extern int cfs_kernel_thread(cfs_thread_t func, void *arg, int flag);
175 * Wait Queue implementation
177 * Like wait_queue in Linux
179 typedef struct cfs_waitq {
180 struct ksleep_chan wq_ksleep_chan;
183 typedef struct cfs_waitlink {
184 struct cfs_waitq *wl_waitq;
185 struct ksleep_link wl_ksleep_link;
188 typedef int cfs_task_state_t;
190 #define CFS_TASK_INTERRUPTIBLE THREAD_ABORTSAFE
191 #define CFS_TASK_UNINT THREAD_UNINT
193 void cfs_waitq_init(struct cfs_waitq *waitq);
194 void cfs_waitlink_init(struct cfs_waitlink *link);
196 void cfs_waitq_add(struct cfs_waitq *waitq, struct cfs_waitlink *link);
197 void cfs_waitq_add_exclusive(struct cfs_waitq *waitq,
198 struct cfs_waitlink *link);
199 void cfs_waitq_forward(struct cfs_waitlink *link, struct cfs_waitq *waitq);
200 void cfs_waitq_del(struct cfs_waitq *waitq, struct cfs_waitlink *link);
201 int cfs_waitq_active(struct cfs_waitq *waitq);
203 void cfs_waitq_signal(struct cfs_waitq *waitq);
204 void cfs_waitq_signal_nr(struct cfs_waitq *waitq, int nr);
205 void cfs_waitq_broadcast(struct cfs_waitq *waitq);
207 void cfs_waitq_wait(struct cfs_waitlink *link, cfs_task_state_t state);
208 cfs_duration_t cfs_waitq_timedwait(struct cfs_waitlink *link,
209 cfs_task_state_t state,
210 cfs_duration_t timeout);
213 * Thread schedule APIs.
215 #define MAX_SCHEDULE_TIMEOUT ((long)(~0UL>>12))
216 extern void thread_set_timer_deadline(uint64_t deadline);
217 extern void thread_cancel_timer(void);
219 static inline int cfs_schedule_timeout(int state, int64_t timeout)
224 result = assert_wait((event_t)current_thread(), state);
226 result = assert_wait((event_t)current_uthread(), state);
230 nanoseconds_to_absolutetime(timeout, &expire);
231 clock_absolutetime_interval_to_deadline(expire, &expire);
232 thread_set_timer_deadline(expire);
234 if (result == THREAD_WAITING)
235 result = thread_block(THREAD_CONTINUE_NULL);
237 thread_cancel_timer();
238 if (result == THREAD_TIMED_OUT)
245 #define cfs_schedule() cfs_schedule_timeout(CFS_TASK_UNINT, CFS_TICK)
246 #define cfs_pause(tick) cfs_schedule_timeout(CFS_TASK_UNINT, tick)
248 #define __wait_event(wq, condition) \
250 struct cfs_waitlink __wait; \
252 cfs_waitlink_init(&__wait); \
254 cfs_waitq_add(&wq, &__wait); \
257 cfs_waitq_wait(&__wait, CFS_TASK_UNINT); \
258 cfs_waitq_del(&wq, &__wait); \
260 cfs_waitq_del(&wq, &__wait); \
263 #define wait_event(wq, condition) \
267 __wait_event(wq, condition); \
270 #define __wait_event_interruptible(wq, condition, ex, ret) \
272 struct cfs_waitlink __wait; \
274 cfs_waitlink_init(&__wait); \
277 cfs_waitq_add(&wq, &__wait); \
279 cfs_waitq_add_exclusive(&wq, &__wait); \
282 if (!cfs_signal_pending()) { \
283 cfs_waitq_wait(&__wait, \
284 CFS_TASK_INTERRUPTIBLE); \
285 cfs_waitq_del(&wq, &__wait); \
288 ret = -ERESTARTSYS; \
291 cfs_waitq_del(&wq, &__wait); \
294 #define wait_event_interruptible(wq, condition) \
298 __wait_event_interruptible(wq, condition, \
303 #define wait_event_interruptible_exclusive(wq, condition) \
307 __wait_event_interruptible(wq, condition, \
313 extern void wakeup_one __P((void * chan));
315 /* only used in tests */
316 #define wake_up_process(p) \
318 wakeup_one((caddr_t)p); \
321 /* used in couple of places */
322 static inline void sleep_on(cfs_waitq_t *waitq)
326 cfs_waitlink_init(&link);
327 cfs_waitq_add(waitq, &link);
328 cfs_waitq_wait(&link, CFS_TASK_UNINT);
329 cfs_waitq_del(waitq, &link);
335 typedef sigset_t cfs_sigset_t;
337 #define SIGNAL_MASK_ASSERT()
341 typedef struct cfs_timer {
345 #define cfs_init_timer(t) do {} while(0)
346 void cfs_timer_init(struct cfs_timer *t, void (*func)(unsigned long), void *arg);
347 void cfs_timer_done(struct cfs_timer *t);
348 void cfs_timer_arm(struct cfs_timer *t, cfs_time_t deadline);
349 void cfs_timer_disarm(struct cfs_timer *t);
350 int cfs_timer_is_armed(struct cfs_timer *t);
352 cfs_time_t cfs_timer_deadline(struct cfs_timer *t);
356 * We don't need to copy out everything in osx
358 #define cfs_ioctl_data_out(a, d, l) \
362 assert((l) >= sizeof(*d)); \
363 __size = (l) - sizeof(*d); \
365 __rc = copy_to_user((void *)a + __size, \
366 (void *)d + __size, \
374 /* Run in PowerG5 who is PPC64 */
375 #define SMP_CACHE_BYTES 128
376 #define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
380 * XXX Liang: patch xnu and export current_processor()?
382 * #define smp_processor_id() current_processor()
384 #define smp_processor_id() 0
385 /* XXX smp_call_function is not supported in xnu */
386 #define smp_call_function(f, a, n, w) do {} while(0)
387 int cfs_online_cpus(void);
388 #define smp_num_cpus cfs_online_cpus()
393 extern int is_suser(void);
396 #define likely(exp) (exp)
399 #define unlikely(exp) (exp)
402 #define lock_kernel() do {} while(0)
403 #define unlock_kernel() do {} while(0)
405 #define CAP_SYS_BOOT 0
406 #define CAP_SYS_ADMIN 1
407 #define capable(a) ((a) == CAP_SYS_BOOT ? is_suser(): is_suser1())
409 #define USERMODEHELPER(path, argv, envp) (0)
411 #define cfs_module(name, version, init, fini) \
412 extern kern_return_t _start(kmod_info_t *ki, void *data); \
413 extern kern_return_t _stop(kmod_info_t *ki, void *data); \
414 __private_extern__ kern_return_t name##_start(kmod_info_t *ki, void *data); \
415 __private_extern__ kern_return_t name##_stop(kmod_info_t *ki, void *data); \
417 kmod_info_t KMOD_INFO_NAME = { 0, KMOD_INFO_VERSION, -1, \
418 { "com.clusterfs.lustre." #name }, { version }, \
419 -1, 0, 0, 0, 0, name##_start, name##_stop }; \
421 __private_extern__ kmod_start_func_t *_realmain = name##_start; \
422 __private_extern__ kmod_stop_func_t *_antimain = name##_stop; \
423 __private_extern__ int _kext_apple_cc = __APPLE_CC__ ; \
425 kern_return_t name##_start(kmod_info_t *ki, void *d) \
430 kern_return_t name##_stop(kmod_info_t *ki, void *d) \
433 return KERN_SUCCESS; \
437 * to allow semicolon after cfs_module(...) \
439 struct __dummy_ ## name ## _struct {}
441 #define inter_module_get(n) cfs_symbol_get(n)
442 #define inter_module_put(n) cfs_symbol_put(n)
444 static inline int request_module(char *name)
456 #define EXPORT_SYMBOL(s)
457 #define MODULE_AUTHOR(s)
458 #define MODULE_DESCRIPTION(s)
459 #define MODULE_LICENSE(s)
460 #define MODULE_PARM(a, b)
461 #define MODULE_PARM_DESC(a, b)
463 #define KERNEL_VERSION(a,b,c) ((a)*100+(b)*10+c)
464 #define LINUX_VERSION_CODE KERNEL_VERSION(2,5,0)
467 #define in_interrupt() ml_at_interrupt_context()
469 #define KERN_EMERG "<0>" /* system is unusable */
470 #define KERN_ALERT "<1>" /* action must be taken immediately */
471 #define KERN_CRIT "<2>" /* critical conditions */
472 #define KERN_ERR "<3>" /* error conditions */
473 #define KERN_WARNING "<4>" /* warning conditions */
474 #define KERN_NOTICE "<5>" /* normal but significant condition */
475 #define KERN_INFO "<6>" /* informational */
476 #define KERN_DEBUG "<7>" /* debug-level messages */
478 static inline long PTR_ERR(const void *ptr)
483 #define ERR_PTR(err) ((void *)err)
484 #define IS_ERR(p) ((unsigned long)(p) + 1000 < 1000)
486 #else /* !__KERNEL__ */
488 typedef struct cfs_proc_dir_entry {
490 } cfs_proc_dir_entry_t;
492 #include <libcfs/user-prim.h>
493 #define __WORDSIZE 32
495 #endif /* END __KERNEL__ */
500 #define EPROTO EPROTOTYPE
503 #define EBADR EBADRPC
506 #define ERESTARTSYS 512
509 #define EDEADLOCK EDEADLK
515 #define ENODATA EINVAL
518 #define ENOTSUPP EINVAL
521 #if BYTE_ORDER == BIG_ENDIAN
522 # define __BIG_ENDIAN
524 # define __LITTLE_ENDIAN
527 #endif /* __LIBCFS_DARWIN_CFS_PRIM_H__ */