4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
35 #ifndef __LIBCFS_DARWIN_CFS_PRIM_H__
36 #define __LIBCFS_DARWIN_CFS_PRIM_H__
38 #ifndef __LIBCFS_LIBCFS_H__
39 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
43 # define EXPORT_SYMBOL(s)
47 #include <sys/types.h>
48 #include <sys/systm.h>
51 # ifndef __APPLE_API_PRIVATE
52 # define __APPLE_API_PRIVATE
53 # include <sys/user.h>
54 # undef __APPLE_API_PRIVATE
56 # include <sys/user.h>
58 # include <mach/mach_traps.h>
59 # include <mach/thread_switch.h>
60 # include <machine/cpu_number.h>
61 #endif /* !__DARWIN8__ */
63 #include <sys/kernel.h>
65 #include <mach/thread_act.h>
66 #include <mach/mach_types.h>
67 #include <mach/time_value.h>
68 #include <kern/sched_prim.h>
70 #include <vm/vm_kern.h>
71 #include <mach/machine/vm_param.h>
72 #include <machine/machine_routines.h>
73 #include <kern/clock.h>
74 #include <kern/thread_call.h>
75 #include <sys/param.h>
78 #include <libcfs/darwin/darwin-types.h>
79 #include <libcfs/darwin/darwin-utils.h>
80 #include <libcfs/darwin/darwin-lock.h>
83 * Symbol functions for libcfs
85 * OSX has no facility for use to register symbol.
86 * So we have to implement it.
88 #define CFS_SYMBOL_LEN 64
91 char name[CFS_SYMBOL_LEN];
94 struct list_head sym_list;
97 extern kern_return_t cfs_symbol_register(const char *, const void *);
98 extern kern_return_t cfs_symbol_unregister(const char *);
99 extern void * cfs_symbol_get(const char *);
100 extern kern_return_t cfs_symbol_put(const char *);
105 * User can register/unregister a list of sysctl_oids
106 * sysctl_oid is data struct of osx's sysctl-entry
108 #define CONFIG_SYSCTL 1
110 #define ctl_table sysctl_oid
111 struct ctl_table *register_sysctl_table(struct ctl_table *table);
112 void unregister_sysctl_table(struct ctl_table *table);
115 * Proc file system APIs, no /proc fs support in OSX
117 typedef struct cfs_proc_dir_entry {
119 } cfs_proc_dir_entry_t;
121 cfs_proc_dir_entry_t * cfs_create_proc_entry(char *name, int mod,
122 cfs_proc_dir_entry_t *parent);
123 void cfs_free_proc_entry(cfs_proc_dir_entry_t *de);
124 void cfs_remove_proc_entry(char *name, cfs_proc_dir_entry_t *entry);
126 typedef int (read_proc_t)(char *page, char **start, off_t off,
127 int count, int *eof, void *data);
128 typedef int (write_proc_t)(struct file *file, const char *buffer,
129 unsigned long count, void *data);
142 struct cdevsw *devsw;
146 extern kern_return_t misc_register(struct miscdevice *);
147 extern kern_return_t misc_deregister(struct miscdevice *);
150 * Task struct and ...
152 * Using BSD current_proc in Darwin
154 extern boolean_t assert_wait_possible(void);
155 extern void *get_bsdtask_info(task_t);
159 typedef struct task_struct {};
160 #define current ((struct task_struct *)current_thread())
161 #else /* !__DARWIN8__ */
163 #define task_struct uthread
165 #define current_uthread() ((struct uthread *)get_bsdthread_info(current_act()))
166 #define current current_uthread()
168 #endif /* !__DARWIN8__ */
170 #define task_lock(t) do {;} while (0)
171 #define task_unlock(t) do {;} while (0)
173 #define set_current_state(s) do {;} while (0)
175 #define DECL_JOURNAL_DATA
176 #define PUSH_JOURNAL do {;} while(0)
177 #define POP_JOURNAL do {;} while(0)
182 * OSX kernel thread can not be created with args,
183 * so we have to implement new APIs to create thread with args
186 typedef int (*cfs_thread_t)(void *);
188 extern task_t kernel_task;
191 * cloning flags, no use in OSX, just copy them from Linux
193 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
194 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
195 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
196 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
197 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */
198 #define CLONE_PID 0x00001000 /* set if pid shared */
199 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
200 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
201 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
202 #define CLONE_THREAD 0x00010000 /* Same thread group? */
203 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
205 #define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD)
207 extern struct task_struct kthread_run(cfs_thread_t func, void *arg,
208 const char namefmt[], ...);
211 * Wait Queue implementation
213 * Like wait_queue in Linux
215 typedef struct cfs_waitq {
216 struct ksleep_chan wq_ksleep_chan;
219 typedef struct cfs_waitlink {
220 struct cfs_waitq *wl_waitq;
221 struct ksleep_link wl_ksleep_link;
224 #define TASK_INTERRUPTIBLE THREAD_ABORTSAFE
225 #define TASK_UNINTERRUPTIBLE THREAD_UNINT
227 void init_waitqueue_head(struct cfs_waitq *waitq);
228 void init_waitqueue_entry_current(struct cfs_waitlink *link);
230 void add_wait_queue(struct cfs_waitq *waitq, struct cfs_waitlink *link);
231 void add_wait_queue_exclusive(struct cfs_waitq *waitq,
232 struct cfs_waitlink *link);
233 void remove_wait_queue(struct cfs_waitq *waitq, struct cfs_waitlink *link);
234 int waitqueue_active(struct cfs_waitq *waitq);
236 void wake_up(struct cfs_waitq *waitq);
237 void wake_up_nr(struct cfs_waitq *waitq, int nr);
238 void wake_up_all(struct cfs_waitq *waitq);
240 void waitq_wait(struct cfs_waitlink *link, long state);
241 cfs_duration_t waitq_timedwait(struct cfs_waitlink *link,
243 cfs_duration_t timeout);
246 * Thread schedule APIs.
248 #define MAX_SCHEDULE_TIMEOUT ((long)(~0UL>>12))
249 extern void thread_set_timer_deadline(__u64 deadline);
250 extern void thread_cancel_timer(void);
252 static inline int schedule_timeout(int state, int64_t timeout)
257 result = assert_wait((event_t)current_thread(), state);
259 result = assert_wait((event_t)current_uthread(), state);
263 nanoseconds_to_absolutetime(timeout, &expire);
264 clock_absolutetime_interval_to_deadline(expire, &expire);
265 thread_set_timer_deadline(expire);
267 if (result == THREAD_WAITING)
268 result = thread_block(THREAD_CONTINUE_NULL);
270 thread_cancel_timer();
271 if (result == THREAD_TIMED_OUT)
278 #define schedule() schedule_timeout(TASK_UNINTERRUPTIBLE, CFS_TICK)
279 #define cfs_pause(tick) schedule_timeout(TASK_UNINTERRUPTIBLE, tick)
281 #define __wait_event(wq, condition) \
283 struct cfs_waitlink __wait; \
285 init_waitqueue_entry_current(&__wait); \
287 add_wait_queue(&wq, &__wait); \
290 waitq_wait(&__wait, TASK_UNINTERRUPTIBLE); \
291 remove_wait_queue(&wq, &__wait); \
293 remove_wait_queue(&wq, &__wait); \
296 #define wait_event(wq, condition) \
300 __wait_event(wq, condition); \
303 #define __wait_event_interruptible(wq, condition, ex, ret) \
305 struct cfs_waitlink __wait; \
307 init_waitqueue_entry_current(&__wait); \
310 add_wait_queue(&wq, &__wait); \
312 add_wait_queue_exclusive(&wq, &__wait); \
315 if (!cfs_signal_pending()) { \
316 waitq_wait(&__wait, \
317 TASK_INTERRUPTIBLE); \
318 remove_wait_queue(&wq, &__wait); \
321 ret = -ERESTARTSYS; \
324 remove_wait_queue(&wq, &__wait); \
327 #define wait_event_interruptible(wq, condition) \
331 __wait_event_interruptible(wq, condition, \
336 #define wait_event_interruptible_exclusive(wq, condition) \
340 __wait_event_interruptible(wq, condition, \
346 extern void wakeup_one __P((void * chan));
348 /* only used in tests */
349 #define wake_up_process(p) \
351 wakeup_one((caddr_t)p); \
354 /* used in couple of places */
355 static inline void sleep_on(wait_queue_head_t *waitq)
359 init_waitqueue_entry_current(&link);
360 add_wait_queue(waitq, &link);
361 waitq_wait(&link, TASK_UNINTERRUPTIBLE);
362 remove_wait_queue(waitq, &link);
376 #define cfs_init_timer(t) do {} while(0)
377 void cfs_timer_init(struct timer_list *t, void (*func)(unsigned long), void *arg);
378 void cfs_timer_done(struct timer_list *t);
379 void cfs_timer_arm(struct timer_list *t, cfs_time_t deadline);
380 void cfs_timer_disarm(struct timer_list *t);
381 int cfs_timer_is_armed(struct timer_list *t);
383 cfs_time_t cfs_timer_deadline(struct timer_list *t);
387 * We don't need to copy out everything in osx
389 #define cfs_ioctl_data_out(a, d, l) \
393 assert((l) >= sizeof(*d)); \
394 __size = (l) - sizeof(*d); \
396 __rc = copy_to_user((void *)a + __size, \
397 (void *)d + __size, \
405 /* Run in PowerG5 who is PPC64 */
406 #define SMP_CACHE_BYTES 128
407 #define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
411 * XXX Liang: patch xnu and export current_processor()?
413 * #define smp_processor_id() current_processor()
415 #define smp_processor_id() 0
416 /* XXX smp_call_function is not supported in xnu */
417 #define smp_call_function(f, a, n, w) do {} while(0)
418 int cfs_online_cpus(void);
423 extern int is_suser(void);
426 #define likely(exp) (exp)
429 #define unlikely(exp) (exp)
432 #define lock_kernel() do {} while(0)
433 #define unlock_kernel() do {} while(0)
435 #define call_usermodehelper(path, argv, envp, 1) (0)
437 #define cfs_module(name, version, init, fini) \
438 extern kern_return_t _start(kmod_info_t *ki, void *data); \
439 extern kern_return_t _stop(kmod_info_t *ki, void *data); \
440 __private_extern__ kern_return_t name##_start(kmod_info_t *ki, void *data); \
441 __private_extern__ kern_return_t name##_stop(kmod_info_t *ki, void *data); \
443 kmod_info_t KMOD_INFO_NAME = { 0, KMOD_INFO_VERSION, -1, \
444 { "com.clusterfs.lustre." #name }, { version }, \
445 -1, 0, 0, 0, 0, name##_start, name##_stop }; \
447 __private_extern__ kmod_start_func_t *_realmain = name##_start; \
448 __private_extern__ kmod_stop_func_t *_antimain = name##_stop; \
449 __private_extern__ int _kext_apple_cc = __APPLE_CC__ ; \
451 kern_return_t name##_start(kmod_info_t *ki, void *d) \
456 kern_return_t name##_stop(kmod_info_t *ki, void *d) \
459 return KERN_SUCCESS; \
463 * to allow semicolon after cfs_module(...) \
465 struct __dummy_ ## name ## _struct {}
467 #define inter_module_get(n) cfs_symbol_get(n)
468 #define inter_module_put(n) cfs_symbol_put(n)
470 static inline int request_module(const char *name, ...)
482 #define MODULE_AUTHOR(s)
483 #define MODULE_DESCRIPTION(s)
484 #define MODULE_LICENSE(s)
485 #define MODULE_PARM(a, b)
486 #define MODULE_PARM_DESC(a, b)
489 #define in_interrupt() ml_at_interrupt_context()
491 #define KERN_EMERG "<0>" /* system is unusable */
492 #define KERN_ALERT "<1>" /* action must be taken immediately */
493 #define KERN_CRIT "<2>" /* critical conditions */
494 #define KERN_ERR "<3>" /* error conditions */
495 #define KERN_WARNING "<4>" /* warning conditions */
496 #define KERN_NOTICE "<5>" /* normal but significant condition */
497 #define KERN_INFO "<6>" /* informational */
498 #define KERN_DEBUG "<7>" /* debug-level messages */
500 #else /* !__KERNEL__ */
502 typedef struct cfs_proc_dir_entry {
504 } cfs_proc_dir_entry_t;
506 #include <libcfs/user-prim.h>
507 #define __WORDSIZE 32
509 #endif /* END __KERNEL__ */
514 #define EPROTO EPROTOTYPE
517 #define EBADR EBADRPC
520 #define ERESTARTSYS 512
523 #define EDEADLOCK EDEADLK
529 #define ENODATA EINVAL
532 #define ENOTSUPP EINVAL
535 #if BYTE_ORDER == BIG_ENDIAN
536 # define __BIG_ENDIAN
538 # define __LITTLE_ENDIAN
541 #endif /* __LIBCFS_DARWIN_CFS_PRIM_H__ */