Whamcloud - gitweb
catch extra args without dashes
[fs/lustre-release.git] / lustre / utils / platform.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (C) 2002 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  */
22 #ifndef __LUSTRE_UTILS_PLATFORM_H
23 #define __LUSTRE_UTILS_PLATFORM_H
24
25 #ifdef __linux__
26
27 #ifdef HAVE_LIBREADLINE
28 #define READLINE_LIBRARY
29 #include <readline/readline.h>
30
31 /* completion_matches() is #if 0-ed out in modern glibc */
32
33 #ifndef completion_matches
34 #  define completion_matches rl_completion_matches
35 #endif
36 extern void using_history(void);
37 extern void stifle_history(int);
38 extern void add_history(char *);
39 #endif /* HAVE_LIBREADLINE */
40
41 #include <errno.h>
42 #include <string.h>
43 #if HAVE_LIBPTHREAD
44 #include <sys/ipc.h>
45 #include <sys/shm.h>
46 #include <pthread.h>
47
48 typedef pthread_mutex_t l_mutex_t;
49 typedef pthread_cond_t  l_cond_t;
50 #define l_mutex_init(s)         pthread_mutex_init(s, NULL)
51 #define l_mutex_lock(s)         pthread_mutex_lock(s)
52 #define l_mutex_unlock(s)       pthread_mutex_unlock(s)
53 #define l_cond_init(c)          pthread_cond_init(c, NULL)
54 #define l_cond_broadcast(c)     pthread_cond_broadcast(c)
55 #define l_cond_wait(c, s)       pthread_cond_wait(c, s)
56 #endif
57
58 #elif __APPLE__
59
60 #ifdef HAVE_LIBREADLINE
61 #define READLINE_LIBRARY
62 #include <readline/readline.h>
63 typedef VFunction       rl_vintfunc_t;
64 typedef VFunction       rl_voidfunc_t;
65 #endif /* HAVE_LIBREADLINE */
66
67 #include <stdlib.h>
68 #include <errno.h>
69 #include <sys/types.h>
70 #include <fcntl.h>
71 #include <stdio.h>
72 #include <sys/shm.h>
73 #include <sys/semaphore.h>
74
75 /*
76  * POSIX compliant inter-process synchronization aren't supported well
77  * in Darwin, pthread_mutex_t and pthread_cond_t can only work as
78  * inter-thread synchronization, they wouldn't work even being put in
79  * shared memory for multi-process. PTHREAD_PROCESS_SHARED is not 
80  * supported by Darwin also (pthread_mutexattr_setpshared() with the 
81  * PTHREAD_PROCESS_SHARED attribute will return EINVAL). 
82  *
83  * The only inter-process sychronization mechanism can be used in Darwin
84  * is POSIX NAMED semaphores and file lock, here we use NAMED semaphore
85  * to implement mutex and condition. 
86  *
87  * XXX Liang:
88  * They are just proto-type now, more tests are needed. 
89  */
90 #define L_LOCK_DEBUG            (0)             
91
92 #define L_SEM_NAMESIZE          32
93
94 typedef struct {
95         sem_t           *s_sem;
96 #if L_LOCK_DEBUG
97         char            s_name[L_SEM_NAMESIZE];
98 #endif
99 } l_sem_t;
100
101 typedef l_sem_t         l_mutex_t;
102
103 typedef struct {
104         l_mutex_t       c_guard;
105         int             c_count;
106         l_sem_t         c_waiter;
107 } l_cond_t;
108
109 static inline int l_sem_init(l_sem_t *sem, int val)
110 {
111         char *s_name;
112 #if L_LOCK_DEBUG
113         s_name = sem->s_name;
114 #else
115         char buf[L_SEM_NAMESIZE];
116         s_name = buf;
117 #endif
118         /* get an unique name for named semaphore */
119         snprintf(s_name, L_SEM_NAMESIZE, "%d-%p", (int)getpid(), sem);
120         sem->s_sem = sem_open(s_name, O_CREAT, 0600, val);
121         if ((int)sem->s_sem == SEM_FAILED) {
122                 fprintf(stderr, "lock %s creating fail: %d, %d!\n",
123                                 s_name, (int)sem->s_sem, errno);
124                 return -1;
125         } else {
126 #if L_LOCK_DEBUG
127                 printf("open lock: %s\n", s_name);
128 #endif
129         }
130         return 0;
131 }
132
133 static inline void l_sem_done(l_sem_t *sem)
134 {
135 #if L_LOCK_DEBUG
136         printf("close lock: %s.\n", sem->s_name);
137 #endif
138         sem_close(sem->s_sem);
139 }
140
141 static inline void l_sem_down(l_sem_t *sem)
142 {
143 #if L_LOCK_DEBUG
144         printf("sem down :%s\n", sem->s_name);
145 #endif
146         sem_wait(sem->s_sem);
147 }
148
149 static inline void l_sem_up(l_sem_t *sem)
150 {
151 #if L_LOCK_DEBUG
152         printf("sem up  :%s\n", sem->s_name);
153 #endif
154         sem_post(sem->s_sem);
155 }
156
157 static inline void l_mutex_init(l_mutex_t *mutex)
158 {
159         l_sem_init((l_sem_t *)mutex, 1);
160 }
161
162 static inline void l_mutex_init_locked(l_mutex_t *mutex)
163 {
164         l_sem_init((l_sem_t *)mutex, 0);
165 }
166
167 static inline void l_mutex_done(l_mutex_t *mutex)
168 {
169         l_sem_done((l_sem_t *)mutex);
170 }
171
172 static inline void l_mutex_lock(l_mutex_t *mutex)
173 {
174 #if L_LOCK_DEBUG
175         printf("lock mutex  :%s\n", mutex->s_name);
176 #endif
177         sem_wait(mutex->s_sem);
178 }
179
180 static inline void l_mutex_unlock(l_mutex_t *mutex)
181 {
182 #if L_LOCK_DEBUG
183         printf("unlock mutex: %s\n", mutex->s_name);
184 #endif
185         sem_post(mutex->s_sem);
186 }
187
188 static inline void l_cond_init(l_cond_t *cond)
189 {
190         l_mutex_init(&cond->c_guard);
191         l_sem_init(&cond->c_waiter, 0);
192         cond->c_count = 0;
193 }
194
195 static inline void l_cond_done(l_cond_t *cond)
196 {
197         if (cond->c_count != 0)
198                 fprintf(stderr, "your waiter list is not empty: %d!\n", cond->c_count);
199         l_mutex_done(&cond->c_guard);
200         l_sem_done(&cond->c_waiter);
201 }
202
203 static inline void l_cond_wait(l_cond_t *cond, l_mutex_t *lock)
204 {
205         l_mutex_lock(&cond->c_guard);
206         cond->c_count --;
207         l_mutex_unlock(&cond->c_guard);
208         l_mutex_unlock(lock);
209         l_sem_down(&cond->c_waiter);
210         l_mutex_lock(lock);
211 }
212
213 static inline void l_cond_broadcast(l_cond_t *cond)
214 {
215         l_mutex_lock(&cond->c_guard);
216         while (cond->c_count < 0) {
217                 l_sem_up(&cond->c_waiter);
218                 cond->c_count ++;
219         }
220         l_mutex_unlock(&cond->c_guard);
221 }
222
223 #else /* other platform */
224
225 #ifdef HAVE_LIBREADLINE
226 #define READLINE_LIBRARY
227 #include <readline/readline.h>
228 #endif /* HAVE_LIBREADLINE */
229 #include <errno.h>
230 #include <string.h>
231 #if HAVE_LIBPTHREAD
232 #include <sys/ipc.h>
233 #include <sys/shm.h>
234 #include <pthread.h>
235
236 typedef pthread_mutex_t l_mutex_t;
237 typedef pthread_cond_t  l_cond_t;
238 #define l_mutex_init(s)         pthread_mutex_init(s, NULL)
239 #define l_mutex_lock(s)         pthread_mutex_lock(s)
240 #define l_mutex_unlock(s)       pthread_mutex_unlock(s)
241 #define l_cond_init(c)          pthread_cond_init(c, NULL)
242 #define l_cond_broadcast(c)     pthread_cond_broadcast(c)
243 #define l_cond_wait(c, s)       pthread_cond_wait(c, s)
244 #endif /* HAVE_LIBPTHREAD */
245
246 #endif /* __linux__  */
247
248 #endif