1## ====================================================================
2## Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com>
3## Copyright (c) 1999-2006 The OSSP Project <http://www.ossp.org/>
4##
5## Redistribution and use in source and binary forms, with or without
6## modification, are permitted provided that the following conditions
7## are met:
8##
9## 1. Redistributions of source code must retain the above copyright
10##    notice, this list of conditions and the following disclaimer.
11##
12## 2. Redistributions in binary form must reproduce the above copyright
13##    notice, this list of conditions and the following disclaimer in
14##    the documentation and/or other materials provided with the
15##    distribution.
16##
17## 3. All advertising materials mentioning features or use of this
18##    software must display the following acknowledgment:
19##    "This product includes software developed by
20##     Ralf S. Engelschall <rse@engelschall.com>."
21##
22## 4. Redistributions of any form whatsoever must retain the following
23##    acknowledgment:
24##    "This product includes software developed by
25##     Ralf S. Engelschall <rse@engelschall.com>."
26##
27## THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
28## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30## PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL RALF S. ENGELSCHALL OR
31## ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
33## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36## STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
38## OF THE POSSIBILITY OF SUCH DAMAGE.
39## ====================================================================
40
41define(AC_CHECK_DEBUGGING,[dnl
42AC_MSG_CHECKING(for compilation debug mode)
43AC_ARG_ENABLE(debug,dnl
44[  --enable-debug          build for debugging (default=no)],
45[dnl
46if test ".$ac_cv_prog_gcc" = ".yes"; then
47    case "$CFLAGS" in
48        *-O2* ) ;;
49            * ) CFLAGS="$CFLAGS -O2" ;;
50    esac
51    case "$CFLAGS" in
52        *-g* ) ;;
53           * ) CFLAGS="$CFLAGS -g" ;;
54    esac
55    CFLAGS="$CFLAGS -Wall -Wshadow -Wpointer-arith -Wcast-align"
56    CFLAGS="$CFLAGS -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline"
57else
58    case "$CFLAGS" in
59        *-g* ) ;;
60           * ) CFLAGS="$CFLAGS -g" ;;
61    esac
62fi
63msg="enabled"
64AC_DEFINE(MM_DEBUG, 1, [define to enable debugging])
65],[
66case "$CFLAGS" in
67    *-g* ) CFLAGS=`echo "$CFLAGS" |\
68                   sed -e 's/ -g / /g' -e 's/ -g$//' -e 's/^-g //g' -e 's/^-g$//'` ;;
69esac
70msg=disabled
71])dnl
72AC_MSG_RESULT([$msg])
73])
74
75define(AC_CONFIGURE_PART,[dnl
76AC_MSG_RESULT()
77AC_MSG_RESULT(${T_MD}$1:${T_ME})
78])dnl
79
80define(AC_CHECK_DEFINE,[dnl
81  AC_CACHE_CHECK(for $1 in $2, ac_cv_define_$1,
82    AC_EGREP_CPP([YES_IS_DEFINED], [
83#include <$2>
84#ifdef $1
85YES_IS_DEFINED
86#endif
87    ], ac_cv_define_$1=yes, ac_cv_define_$1=no)
88  )
89  if test "$ac_cv_define_$1" = "yes" ; then
90    AC_DEFINE(HAVE_$1, 1, [define to 1 if you have the $1 define])
91  fi
92])dnl
93AC_DEFINE(HAVE_$1)
94
95define(AC_IFALLYES,[dnl
96ac_rc=yes
97for ac_spec in $1; do
98    ac_type=`echo "$ac_spec" | sed -e 's/:.*$//'`
99    ac_item=`echo "$ac_spec" | sed -e 's/^.*://'`
100    case $ac_type in
101        header )
102            ac_item=`echo "$ac_item" | sed 'y%./+-%__p_%'`
103            ac_var="ac_cv_header_$ac_item"
104            ;;
105        file )
106            ac_item=`echo "$ac_item" | sed 'y%./+-%__p_%'`
107            ac_var="ac_cv_file_$ac_item"
108            ;;
109        func )   ac_var="ac_cv_func_$ac_item"   ;;
110        define ) ac_var="ac_cv_define_$ac_item" ;;
111        custom ) ac_var="$ac_item" ;;
112    esac
113    eval "ac_val=\$$ac_var"
114    if test ".$ac_val" != .yes; then
115        ac_rc=no
116        break
117    fi
118done
119if test ".$ac_rc" = .yes; then
120    :
121    $2
122else
123    :
124    $3
125fi
126])dnl
127
128define(AC_BEGIN_DECISION,[dnl
129ac_decision_item='$1'
130ac_decision_msg='FAILED'
131ac_decision=''
132])dnl
133define(AC_DECIDE,[dnl
134ac_decision='$1'
135ac_decision_msg='$2'
136ac_decision_$1=yes
137ac_decision_$1_msg='$2'
138])dnl
139define(AC_DECISION_OVERRIDE,[dnl
140    ac_decision=''
141    for ac_item in $1; do
142         eval "ac_decision_this=\$ac_decision_${ac_item}"
143         if test ".$ac_decision_this" = .yes; then
144             ac_decision=$ac_item
145             eval "ac_decision_msg=\$ac_decision_${ac_item}_msg"
146         fi
147    done
148])dnl
149define(AC_DECISION_FORCE,[dnl
150ac_decision="$1"
151eval "ac_decision_msg=\"\$ac_decision_${ac_decision}_msg\""
152])dnl
153define(AC_END_DECISION,[dnl
154if test ".$ac_decision" = .; then
155    echo "[$]0:Error: decision on $ac_decision_item failed" 1>&2
156    exit 1
157else
158    if test ".$ac_decision_msg" = .; then
159        ac_decision_msg="$ac_decision"
160    fi
161    AC_MSG_RESULT([decision on $ac_decision_item... $ac_decision_msg])
162fi
163])dnl
164
165AC_DEFUN(AC_TEST_FILE,
166[AC_REQUIRE([AC_PROG_CC])
167ac_safe=`echo "$1" | sed 'y%./+-%__p_%'`
168AC_MSG_CHECKING([for $1])
169AC_CACHE_VAL(ac_cv_file_$ac_safe, [
170  if test -r $1; then
171    eval "ac_cv_file_$ac_safe=yes"
172  else
173    eval "ac_cv_file_$ac_safe=no"
174  fi
175])dnl
176if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then
177  AC_MSG_RESULT(yes)
178  ifelse([$2], , :, [$2])
179else
180  AC_MSG_RESULT(no)
181ifelse([$3], , , [$3])
182fi
183])
184
185AC_DEFUN(AC_PROG_NM,
186[AC_MSG_CHECKING([for BSD-compatible nm])
187AC_CACHE_VAL(ac_cv_path_NM,
188[if test -n "$NM"; then
189  # Let the user override the test.
190  ac_cv_path_NM="$NM"
191else
192  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
193  for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
194    test -z "$ac_dir" && ac_dir=.
195    if test -f $ac_dir/nm; then
196      # Check to see if the nm accepts a BSD-compat flag.
197      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
198      #   nm: unknown option "B" ignored
199      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
200        ac_cv_path_NM="$ac_dir/nm -B"
201      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
202        ac_cv_path_NM="$ac_dir/nm -p"
203      else
204        ac_cv_path_NM="$ac_dir/nm"
205      fi
206      break
207    fi
208  done
209  IFS="$ac_save_ifs"
210  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
211fi])
212NM="$ac_cv_path_NM"
213AC_MSG_RESULT([$NM])
214AC_SUBST(NM)
215])
216
217define(AC_CHECK_MAXSEGSIZE,[dnl
218AC_MSG_CHECKING(for shared memory maximum segment size)
219AC_CACHE_VAL(ac_cv_maxsegsize,[
220OCFLAGS="$CFLAGS"
221case "$1" in
222    MM_SHMT_MM*    ) CFLAGS="-DTEST_MMAP   $CFLAGS" ;;
223    MM_SHMT_IPCSHM ) CFLAGS="-DTEST_SHMGET $CFLAGS" ;;
224esac
225cross_compile=no
226AC_TRY_RUN(
227changequote(<<, >>)dnl
228<<
229#include <stdio.h>
230#include <stdlib.h>
231#include <unistd.h>
232#include <fcntl.h>
233#include <sys/file.h>
234#include <sys/types.h>
235#include <sys/stat.h>
236#ifdef TEST_MMAP
237#include <sys/mman.h>
238#endif
239#ifdef TEST_SHMGET
240#ifdef MM_OS_SUNOS
241#define KERNEL 1
242#endif
243#ifdef MM_OS_BS2000
244#define _KMEMUSER
245#endif
246#include <sys/ipc.h>
247#include <sys/shm.h>
248#ifdef MM_OS_SUNOS
249#undef KERNEL
250#endif
251#ifdef MM_OS_BS2000
252#undef _KMEMUSER
253#endif
254#if !defined(SHM_R)
255#define SHM_R 0400
256#endif
257#if !defined(SHM_W)
258#define SHM_W 0200
259#endif
260#endif
261#if !defined(MAP_FAILED)
262#define MAP_FAILED ((void *)(-1))
263#endif
264#ifdef MM_OS_BEOS
265#include <kernel/OS.h>
266#endif
267
268int testit(int size)
269{
270    int fd;
271    void *segment;
272#ifdef TEST_MMAP
273    char file[] = "./ac_test.tmp";
274    unlink(file);
275    if ((fd = open(file, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) == -1)
276        return 0;
277    if (ftruncate(fd, size) == -1)
278        return 0;
279    if ((segment = (void *)mmap(NULL, size, PROT_READ|PROT_WRITE,
280                                MAP_SHARED, fd, 0)) == (void *)MAP_FAILED) {
281        close(fd);
282        return 0;
283    }
284    munmap((caddr_t)segment, size);
285    close(fd);
286    unlink(file);
287#endif
288#ifdef TEST_SHMGET
289    if ((fd = shmget(IPC_PRIVATE, size, SHM_R|SHM_W|IPC_CREAT)) == -1)
290        return 0;
291    if ((segment = (void *)shmat(fd, NULL, 0)) == ((void *)-1)) {
292        shmctl(fd, IPC_RMID, NULL);
293        return 0;
294    }
295    shmdt(segment);
296    shmctl(fd, IPC_RMID, NULL);
297#endif
298#ifdef TEST_BEOS
299    area_id id;
300    id = create_area("mm_test", (void*)&segment, B_ANY_ADDRESS, size,
301                     B_LAZY_LOCK, B_READ_AREA|B_WRITE_AREA);
302    if (id < 0)
303        return 0;
304    delete_area(id);
305#endif
306    return 1;
307}
308
309#define ABS(n) ((n) >= 0 ? (n) : (-(n)))
310
311int main(int argc, char *argv[])
312{
313    int t, m, b;
314    int d;
315    int rc;
316    FILE *f;
317
318    /*
319     * Find maximum possible allocation size by performing a
320     * binary search starting with a search space between 0 and
321     * 64MB of memory.
322     */
323    t = 1024*1024*64 /* = 67108864 */;
324    if (testit(t))
325        m = t;
326    else {
327        m = 1024*1024*32;
328        b = 0;
329        for (;;) {
330            /* fprintf(stderr, "t=%d, m=%d, b=%d\n", t, m, b); */
331            rc = testit(m);
332            if (rc) {
333                d = ((t-m)/2);
334                b = m;
335            }
336            else {
337                d = -((m-b)/2);
338                t = m;
339            }
340            if (ABS(d) < 1024*1) {
341                if (!rc)
342                    m = b;
343                break;
344            }
345            if (m < 1024*8)
346                break;
347            m += d;
348        }
349        if (m < 1024*8)
350            m = 0;
351    }
352    if ((f = fopen("conftestval", "w")) == NULL)
353        exit(1);
354    fprintf(f, "%d\n", m);
355    fclose(f);
356    exit(0);
357}
358>>
359changequote([, ])dnl
360,[ac_cv_maxsegsize="`cat conftestval`"
361],
362ac_cv_maxsegsize=0
363,
364ac_cv_maxsegsize=0
365)
366CFLAGS="$OCFLAGS"
367])
368msg="$ac_cv_maxsegsize"
369if test $msg -eq 67108864; then
370    msg="64MB (soft limit)"
371elif test $msg -gt 1048576; then
372    msg="`expr $msg / 1024`"
373    msg="`expr $msg / 1024`"
374    msg="${msg}MB"
375elif test $msg -gt 1024; then
376    msg="`expr $msg / 1024`"
377    msg="${msg}KB"
378else
379    ac_cv_maxsegsize=0
380    msg=unknown
381fi
382MM_SHM_MAXSEGSIZE=$ac_cv_maxsegsize
383test ".$msg" = .unknown && AC_MSG_ERROR([Unable to determine maximum shared memory segment size])
384AC_MSG_RESULT([$msg])
385AC_DEFINE_UNQUOTED(MM_SHM_MAXSEGSIZE, $MM_SHM_MAXSEGSIZE, [maximum segment size])
386])
387
388