diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2003-05-28 22:04:40 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2003-05-28 22:04:40 +0000 |
commit | b359e82ceabbf42b1e3d8069627701fde5d7cb90 (patch) | |
tree | 38a5f38a753bd8420933e58d0da2dd6732afe406 /newlib/libc/sys/linux/linuxthreads | |
parent | 4218d888971213c57c903845e16a10bc8bde616b (diff) | |
download | cygnal-b359e82ceabbf42b1e3d8069627701fde5d7cb90.tar.gz cygnal-b359e82ceabbf42b1e3d8069627701fde5d7cb90.tar.bz2 cygnal-b359e82ceabbf42b1e3d8069627701fde5d7cb90.zip |
2003-05-28 Jeff Johnston <jjohnstn@redhat.com>
Tom Fitzsimmons <fitzsim@redhat.com>
* configure.in: Add iconvdata support for x86 linux.
* configure: Regenerated.
* libc/sys/linux/Makefile.am: Add EL/IX level 3 network, dynamic
library, iconv, and linuxthreads support.
* libc/sys/linux/configure.in: Ditto.
* libc/sys/linux/Makefile.in: Regenerated.
* libc/sys/linux/configure: Ditto.
* iconvdata/EUC-JP.irreversible: New file.
* iconvdata/Makefile.am: Ditto.
* iconvdata/Makefile.in: Ditto.
* iconvdata/SJIS.irreversible: Ditto.
* iconvdata/aclocal.m4: Ditto.
* iconvdata/configure: Ditto.
* iconvdata/configure.in: Ditto.
* iconvdata/dummy.c: Ditto.
* iconvdata/euc-jp.c: Ditto.
* iconvdata/gconv-modules: Ditto.
* iconvdata/jis0201.c: Ditto.
* iconvdata/jis0201.h: Ditto.
* iconvdata/jis0208.c: Ditto.
* iconvdata/jis0208.h: Ditto.
* iconvdata/jis0212.c: Ditto.
* iconvdata/jis0212.h: Ditto.
* iconvdata/sjis.c: Ditto.
* libc/include/errno.h: Protect definition of error_t.
* libc/sys/linux/gethostid.c: New file.
* libc/sys/linux/sethostid.c: Ditto.
* libc/sys/linux/dl/Makefile.am: Ditto.
* libc/sys/linux/dl/Makefile.in: Ditto.
* libc/sys/linux/dl/abi-tag.h: Ditto.
* libc/sys/linux/dl/atomicity.h: Ditto.
* libc/sys/linux/dl/dl-addr.c: Ditto.
* libc/sys/linux/dl/dl-cache.c: Ditto.
* libc/sys/linux/dl/dl-cache.h: Ditto.
* libc/sys/linux/dl/dl-close.c: Ditto.
* libc/sys/linux/dl/dl-debug.c: Ditto.
* libc/sys/linux/dl/dl-deps.c: Ditto.
* libc/sys/linux/dl/dl-dst.h: Ditto.
* libc/sys/linux/dl/dl-error.c: Ditto.
* libc/sys/linux/dl/dl-fini.c: Ditto.
* libc/sys/linux/dl/dl-init.c: Ditto.
* libc/sys/linux/dl/dl-iteratephdr.c: Ditto.
* libc/sys/linux/dl/dl-libc.c: Ditto.
* libc/sys/linux/dl/dl-librecon.h: Ditto.
* libc/sys/linux/dl/dl-load.c: Ditto.
* libc/sys/linux/dl/dl-lookup.c: Ditto.
* libc/sys/linux/dl/dl-lookupcfg.h: Ditto.
* libc/sys/linux/dl/dl-minimal.c: Ditto.
* libc/sys/linux/dl/dl-misc.c: Ditto.
* libc/sys/linux/dl/dl-object.c: Ditto.
* libc/sys/linux/dl/dl-open.c: Ditto.
* libc/sys/linux/dl/dl-osinfo.h: Ditto.
* libc/sys/linux/dl/dl-profile.c: Ditto.
* libc/sys/linux/dl/dl-profstub.c: Ditto.
* libc/sys/linux/dl/dl-reloc.c: Ditto.
* libc/sys/linux/dl/dl-runtime.c: Ditto.
* libc/sys/linux/dl/dl-support.c: Ditto.
* libc/sys/linux/dl/dl-sym.c: Ditto.
* libc/sys/linux/dl/dl-version.c: Ditto.
* libc/sys/linux/dl/dlfcn.h: Ditto.
* libc/sys/linux/dl/do-lookup.h: Ditto.
* libc/sys/linux/dl/do-rel.h: Ditto.
* libc/sys/linux/dl/dynamic-link.h: Ditto.
* libc/sys/linux/dl/kernel-features.h: Ditto.
* libc/sys/linux/dl/ldsodefs.h: Ditto.
* libc/sys/linux/dl/libintl.h: Ditto.
* libc/sys/linux/dl/trusted-dirs.h: Ditto.
* libc/sys/linux/dl/unsecvars.h: Ditto.
* libc/sys/linux/iconv/Makefile.am: Ditto.
* libc/sys/linux/iconv/Makefile.in: Ditto.
* libc/sys/linux/iconv/categories.def: Ditto.
* libc/sys/linux/iconv/dummy-repertoire.c: Ditto.
* libc/sys/linux/iconv/gconv.c: Ditto.
* libc/sys/linux/iconv/gconv_builtin.c: Ditto.
* libc/sys/linux/iconv/gconv_builtin.h: Ditto.
* libc/sys/linux/iconv/gconv_cache.c: Ditto.
* libc/sys/linux/iconv/gconv_charset.h: Ditto.
* libc/sys/linux/iconv/gconv_close.c: Ditto.
* libc/sys/linux/iconv/gconv_conf.c: Ditto.
* libc/sys/linux/iconv/gconv_db.c: Ditto.
* libc/sys/linux/iconv/gconv_dl.c: Ditto.
* libc/sys/linux/iconv/gconv_int.h: Ditto.
* libc/sys/linux/iconv/gconv_open.c: Ditto.
* libc/sys/linux/iconv/gconv_simple.c: Ditto.
* libc/sys/linux/iconv/gconv_trans.c: Ditto.
* libc/sys/linux/iconv/hash-string.h: Ditto.
* libc/sys/linux/iconv/iconv.c: Ditto.
* libc/sys/linux/iconv/iconv.h: Ditto.
* libc/sys/linux/iconv/iconv_charmap.c: Ditto.
* libc/sys/linux/iconv/iconv_close.c: Ditto.
* libc/sys/linux/iconv/iconv_open.c: Ditto.
* libc/sys/linux/iconv/iconvconfig.c: Ditto.
* libc/sys/linux/iconv/iconvconfig.h: Ditto.
* libc/sys/linux/iconv/loadinfo.h: Ditto.
* libc/sys/linux/iconv/localeinfo.h: Ditto.
* libc/sys/linux/iconv/loop.c: Ditto.
* libc/sys/linux/iconv/skeleton.c: Ditto.
* libc/sys/linux/iconv/strtab.c: Ditto.
* libc/sys/linux/include/dl-hash.h: Ditto.
* libc/sys/linux/include/dlfcn.h: Ditto.
* libc/sys/linux/include/fnmatch.h: Ditto.
* libc/sys/linux/include/gconv.h: Ditto.
* libc/sys/linux/include/glob.h: Ditto.
* libc/sys/linux/include/hesiod.h: Ditto.
* libc/sys/linux/include/ifaddrs.h: Ditto.
* libc/sys/linux/include/libc_private.h: Ditto.
* libc/sys/linux/include/link.h: Ditto.
* libc/sys/linux/include/namespace.h: Ditto.
* libc/sys/linux/include/netconfig.h: Ditto.
* libc/sys/linux/include/netdb.h: Ditto.
* libc/sys/linux/include/nsswitch.h: Ditto.
* libc/sys/linux/include/regex.h: Ditto.
* libc/sys/linux/include/resolv.h: Ditto.
* libc/sys/linux/include/rune.h: Ditto.
* libc/sys/linux/include/runetype.h: Ditto.
* libc/sys/linux/include/semaphore.h: Ditto.
* libc/sys/linux/include/setlocale.h: Ditto.
* libc/sys/linux/include/un-namespace.h: Ditto.
* libc/sys/linux/include/wordexp.h: Ditto.
* libc/sys/linux/include/arpa/ftp.h: Ditto.
* libc/sys/linux/include/arpa/inet.h: Ditto.
* libc/sys/linux/include/arpa/nameser.h: Ditto.
* libc/sys/linux/include/arpa/nameser_compat.h: Ditto.
* libc/sys/linux/include/arpa/telnet.h: Ditto.
* libc/sys/linux/include/arpa/tftp.h: Ditto.
* libc/sys/linux/include/net/bpf.h: Ditto.
* libc/sys/linux/include/net/bpf_compat.h: Ditto.
* libc/sys/linux/include/net/bpfdesc.h: Ditto.
* libc/sys/linux/include/net/bridge.h: Ditto.
* libc/sys/linux/include/net/ethernet.h: Ditto.
* libc/sys/linux/include/net/fddi.h: Ditto.
* libc/sys/linux/include/net/if.h: Ditto.
* libc/sys/linux/include/net/if_arc.h: Ditto.
* libc/sys/linux/include/net/if_arp.h: Ditto.
* libc/sys/linux/include/net/if_atm.h: Ditto.
* libc/sys/linux/include/net/if_dl.h: Ditto.
* libc/sys/linux/include/net/if_gif.h: Ditto.
* libc/sys/linux/include/net/if_ieee80211.h: Ditto.
* libc/sys/linux/include/net/if_llc.h: Ditto.
* libc/sys/linux/include/net/if_media.h: Ditto.
* libc/sys/linux/include/net/if_mib.h: Ditto.
* libc/sys/linux/include/net/if_ppp.h: Ditto.
* libc/sys/linux/include/net/if_pppvar.h: Ditto.
* libc/sys/linux/include/net/if_slvar.h: Ditto.
* libc/sys/linux/include/net/if_sppp.h: Ditto.
* libc/sys/linux/include/net/if_stf.h: Ditto.
* libc/sys/linux/include/net/if_tap.h: Ditto.
* libc/sys/linux/include/net/if_tapvar.h: Ditto.
* libc/sys/linux/include/net/if_tun.h: Ditto.
* libc/sys/linux/include/net/if_tunvar.h: Ditto.
* libc/sys/linux/include/net/if_types.h: Ditto.
* libc/sys/linux/include/net/if_var.h: Ditto.
* libc/sys/linux/include/net/if_vlan_var.h: Ditto.
* libc/sys/linux/include/net/intrq.h: Ditto.
* libc/sys/linux/include/net/iso88025.h: Ditto.
* libc/sys/linux/include/net/net_osdep.h: Ditto.
* libc/sys/linux/include/net/netisr.h: Ditto.
* libc/sys/linux/include/net/pfil.h: Ditto.
* libc/sys/linux/include/net/pfkeyv2.h: Ditto.
* libc/sys/linux/include/net/ppp_comp.h: Ditto.
* libc/sys/linux/include/net/ppp_defs.h: Ditto.
* libc/sys/linux/include/net/radix.h: Ditto.
* libc/sys/linux/include/net/raw_cb.h: Ditto.
* libc/sys/linux/include/net/route.h: Ditto.
* libc/sys/linux/include/net/slcompress.h: Ditto.
* libc/sys/linux/include/net/slip.h: Ditto.
* libc/sys/linux/include/net/zlib.h: Ditto.
* libc/sys/linux/include/netinet/icmp6.h: Ditto.
* libc/sys/linux/include/netinet/icmp_var.h: Ditto.
* libc/sys/linux/include/netinet/if_atm.h: Ditto.
* libc/sys/linux/include/netinet/if_ether.h: Ditto.
* libc/sys/linux/include/netinet/igmp.h: Ditto.
* libc/sys/linux/include/netinet/igmp_var.h: Ditto.
* libc/sys/linux/include/netinet/in.h: Ditto.
* libc/sys/linux/include/netinet/in_gif.h: Ditto.
* libc/sys/linux/include/netinet/in_pcb.h: Ditto.
* libc/sys/linux/include/netinet/in_systm.h: Ditto.
* libc/sys/linux/include/netinet/in_var.h: Ditto.
* libc/sys/linux/include/netinet/ip.h: Ditto.
* libc/sys/linux/include/netinet/ip6.h: Ditto.
* libc/sys/linux/include/netinet/ip_dummynet.h: Ditto.
* libc/sys/linux/include/netinet/ip_ecn.h: Ditto.
* libc/sys/linux/include/netinet/ip_encap.h: Ditto.
* libc/sys/linux/include/netinet/ip_flow.h: Ditto.
* libc/sys/linux/include/netinet/ip_fw.h: Ditto.
* libc/sys/linux/include/netinet/ip_icmp.h: Ditto.
* libc/sys/linux/include/netinet/ip_mroute.h: Ditto.
* libc/sys/linux/include/netinet/ip_var.h: Ditto.
* libc/sys/linux/include/netinet/ipprotosw.h: Ditto.
* libc/sys/linux/include/netinet/tcp.h: Ditto.
* libc/sys/linux/include/netinet/tcp_debug.h: Ditto.
* libc/sys/linux/include/netinet/tcp_fsm.h: Ditto.
* libc/sys/linux/include/netinet/tcp_seq.h: Ditto.
* libc/sys/linux/include/netinet/tcp_timer.h: Ditto.
* libc/sys/linux/include/netinet/tcp_var.h: Ditto.
* libc/sys/linux/include/netinet/tcpip.h: Ditto.
* libc/sys/linux/include/netinet/udp.h: Ditto.
* libc/sys/linux/include/netinet/udp_var.h: Ditto.
* libc/sys/linux/include/netinet6/ah.h: Ditto.
* libc/sys/linux/include/netinet6/ah6.h: Ditto.
* libc/sys/linux/include/netinet6/esp.h: Ditto.
* libc/sys/linux/include/netinet6/esp6.h: Ditto.
* libc/sys/linux/include/netinet6/esp_rijndael.h: Ditto.
* libc/sys/linux/include/netinet6/icmp6.h: Ditto.
* libc/sys/linux/include/netinet6/in6.h: Ditto.
* libc/sys/linux/include/netinet6/in6_gif.h: Ditto.
* libc/sys/linux/include/netinet6/in6_ifattach.h: Ditto.
* libc/sys/linux/include/netinet6/in6_pcb.h: Ditto.
* libc/sys/linux/include/netinet6/in6_prefix.h: Ditto.
* libc/sys/linux/include/netinet6/in6_var.h: Ditto.
* libc/sys/linux/include/netinet6/ip6.h: Ditto.
* libc/sys/linux/include/netinet6/ip6_ecn.h: Ditto.
* libc/sys/linux/include/netinet6/ip6_fw.h: Ditto.
* libc/sys/linux/include/netinet6/ip6_mroute.h: Ditto.
* libc/sys/linux/include/netinet6/ip6_var.h: Ditto.
* libc/sys/linux/include/netinet6/ip6protosw.h: Ditto.
* libc/sys/linux/include/netinet6/ipcomp.h: Ditto.
* libc/sys/linux/include/netinet6/ipcomp6.h: Ditto.
* libc/sys/linux/include/netinet6/ipsec.h: Ditto.
* libc/sys/linux/include/netinet6/ipsec6.h: Ditto.
* libc/sys/linux/include/netinet6/mld6_var.h: Ditto.
* libc/sys/linux/include/netinet6/nd6.h: Ditto.
* libc/sys/linux/include/netinet6/pim6.h: Ditto.
* libc/sys/linux/include/netinet6/pim6_var.h: Ditto.
* libc/sys/linux/include/netinet6/raw_ip6.h: Ditto.
* libc/sys/linux/include/netinet6/scope6_var.h: Ditto.
* libc/sys/linux/include/netinet6/tcp6_var.h: Ditto.
* libc/sys/linux/include/netinet6/udp6_var.h: Ditto.
* libc/sys/linux/include/netns/idp.h: Ditto.
* libc/sys/linux/include/netns/idp_var.h: Ditto.
* libc/sys/linux/include/netns/ns.h: Ditto.
* libc/sys/linux/include/netns/ns_error.h: Ditto.
* libc/sys/linux/include/netns/ns_if.h: Ditto.
* libc/sys/linux/include/netns/ns_pcb.h: Ditto.
* libc/sys/linux/include/netns/sp.h: Ditto.
* libc/sys/linux/include/netns/spidp.h: Ditto.
* libc/sys/linux/include/netns/spp_debug.h: Ditto.
* libc/sys/linux/include/netns/spp_timer.h: Ditto.
* libc/sys/linux/include/netns/spp_var.h: Ditto.
* libc/sys/linux/include/rpc/Makefile: Ditto.
* libc/sys/linux/include/rpc/auth.h: Ditto.
* libc/sys/linux/include/rpc/auth_des.h: Ditto.
* libc/sys/linux/include/rpc/auth_kerb.h: Ditto.
* libc/sys/linux/include/rpc/auth_unix.h: Ditto.
* libc/sys/linux/include/rpc/clnt.h: Ditto.
* libc/sys/linux/include/rpc/clnt_soc.h: Ditto.
* libc/sys/linux/include/rpc/clnt_stat.h: Ditto.
* libc/sys/linux/include/rpc/des.h: Ditto.
* libc/sys/linux/include/rpc/des_crypt.h: Ditto.
* libc/sys/linux/include/rpc/nettype.h: Ditto.
* libc/sys/linux/include/rpc/pmap_clnt.h: Ditto.
* libc/sys/linux/include/rpc/pmap_prot.h: Ditto.
* libc/sys/linux/include/rpc/pmap_rmt.h: Ditto.
* libc/sys/linux/include/rpc/raw.h: Ditto.
* libc/sys/linux/include/rpc/rpc.h: Ditto.
* libc/sys/linux/include/rpc/rpc_com.h: Ditto.
* libc/sys/linux/include/rpc/rpc_msg.h: Ditto.
* libc/sys/linux/include/rpc/rpcb_clnt.h: Ditto.
* libc/sys/linux/include/rpc/rpcb_prot.h: Ditto.
* libc/sys/linux/include/rpc/rpcb_prot.x: Ditto.
* libc/sys/linux/include/rpc/rpcent.h: Ditto.
* libc/sys/linux/include/rpc/svc.h: Ditto.
* libc/sys/linux/include/rpc/svc_auth.h: Ditto.
* libc/sys/linux/include/rpc/svc_dg.h: Ditto.
* libc/sys/linux/include/rpc/svc_soc.h: Ditto.
* libc/sys/linux/include/rpc/types.h: Ditto.
* libc/sys/linux/include/rpc/xdr.h: Ditto.
* libc/sys/linux/intl/Makefile.am: Ditto.
* libc/sys/linux/intl/Makefile.in: Ditto.
* libc/sys/linux/intl/bindtextdom.c: Ditto.
* libc/sys/linux/intl/catgets.c: Ditto.
* libc/sys/linux/intl/catgetsinfo.h: Ditto.
* libc/sys/linux/intl/config.h: Ditto.
* libc/sys/linux/intl/dcgettext.c: Ditto.
* libc/sys/linux/intl/dcigettext.c: Ditto.
* libc/sys/linux/intl/dcngettext.c: Ditto.
* libc/sys/linux/intl/dgettext.c: Ditto.
* libc/sys/linux/intl/dngettext.c: Ditto.
* libc/sys/linux/intl/explodename.c: Ditto.
* libc/sys/linux/intl/finddomain.c: Ditto.
* libc/sys/linux/intl/gettext.c: Ditto.
* libc/sys/linux/intl/gettext.h: Ditto.
* libc/sys/linux/intl/gettextP.h: Ditto.
* libc/sys/linux/intl/hash-string.h: Ditto.
* libc/sys/linux/intl/l10nflist.c: Ditto.
* libc/sys/linux/intl/loadinfo.h: Ditto.
* libc/sys/linux/intl/loadmsgcat.c: Ditto.
* libc/sys/linux/intl/locale.alias: Ditto.
* libc/sys/linux/intl/localealias.c: Ditto.
* libc/sys/linux/intl/ngettext.c: Ditto.
* libc/sys/linux/intl/open_catalog.c: Ditto.
* libc/sys/linux/intl/plural.c: Ditto.
* libc/sys/linux/intl/plural.y: Ditto.
* libc/sys/linux/intl/stpcpy.c: Ditto.
* libc/sys/linux/intl/textdomain.c: Ditto.
* libc/sys/linux/linuxthreads/LICENSE: Ditto.
* libc/sys/linux/linuxthreads/Makefile.am: Ditto.
* libc/sys/linux/linuxthreads/Makefile.in: Ditto.
* libc/sys/linux/linuxthreads/aclocal.m4: Ditto.
* libc/sys/linux/linuxthreads/attr.c: Ditto.
* libc/sys/linux/linuxthreads/barrier.c: Ditto.
* libc/sys/linux/linuxthreads/bp-sym.h: Ditto.
* libc/sys/linux/linuxthreads/cancel.c: Ditto.
* libc/sys/linux/linuxthreads/condvar.c: Ditto.
* libc/sys/linux/linuxthreads/config.h: Ditto.
* libc/sys/linux/linuxthreads/configure: Ditto.
* libc/sys/linux/linuxthreads/configure.in: Ditto.
* libc/sys/linux/linuxthreads/defs.awk: Ditto.
* libc/sys/linux/linuxthreads/ecmutex.c: Ditto.
* libc/sys/linux/linuxthreads/events.c: Ditto.
* libc/sys/linux/linuxthreads/getcpuclockid.c: Ditto.
* libc/sys/linux/linuxthreads/getreent.c: Ditto.
* libc/sys/linux/linuxthreads/internals.h: Ditto.
* libc/sys/linux/linuxthreads/join.c: Ditto.
* libc/sys/linux/linuxthreads/joinrace.c: Ditto.
* libc/sys/linux/linuxthreads/kernel-features.h: Ditto.
* libc/sys/linux/linuxthreads/libc-internal.h: Ditto.
* libc/sys/linux/linuxthreads/libc-symbols.h: Ditto.
* libc/sys/linux/linuxthreads/linuxthreads.texi: Ditto.
* libc/sys/linux/linuxthreads/lockfile.c: Ditto.
* libc/sys/linux/linuxthreads/manager.c: Ditto.
* libc/sys/linux/linuxthreads/mq_notify.c: Ditto.
* libc/sys/linux/linuxthreads/mutex.c: Ditto.
* libc/sys/linux/linuxthreads/no-tsd.c: Ditto.
* libc/sys/linux/linuxthreads/oldsemaphore.c: Ditto.
* libc/sys/linux/linuxthreads/posix-timer.h: Ditto.
* libc/sys/linux/linuxthreads/prio.c: Ditto.
* libc/sys/linux/linuxthreads/proc_service.h: Ditto.
* libc/sys/linux/linuxthreads/pt-machine.c: Ditto.
* libc/sys/linux/linuxthreads/ptclock_gettime.c: Ditto.
* libc/sys/linux/linuxthreads/ptclock_settime.c: Ditto.
* libc/sys/linux/linuxthreads/ptfork.c: Ditto.
* libc/sys/linux/linuxthreads/pthread.c: Ditto.
* libc/sys/linux/linuxthreads/ptlongjmp.c: Ditto.
* libc/sys/linux/linuxthreads/queue.h: Ditto.
* libc/sys/linux/linuxthreads/reent.c: Ditto.
* libc/sys/linux/linuxthreads/reqsyscalls.c: Ditto.
* libc/sys/linux/linuxthreads/restart.h: Ditto.
* libc/sys/linux/linuxthreads/rwlock.c: Ditto.
* libc/sys/linux/linuxthreads/semaphore.c: Ditto.
* libc/sys/linux/linuxthreads/semaphore.h: Ditto.
* libc/sys/linux/linuxthreads/shlib-compat.h: Ditto.
* libc/sys/linux/linuxthreads/signals.c: Ditto.
* libc/sys/linux/linuxthreads/specific.c: Ditto.
* libc/sys/linux/linuxthreads/spinlock.c: Ditto.
* libc/sys/linux/linuxthreads/spinlock.h: Ditto.
* libc/sys/linux/linuxthreads/sysctl.c: Ditto.
* libc/sys/linux/linuxthreads/td_init.c: Ditto.
* libc/sys/linux/linuxthreads/td_log.c: Ditto.
* libc/sys/linux/linuxthreads/td_symbol_list.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_clear_event.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_delete.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_enable_stats.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_event_addr.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_event_getmsg.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_get_nthreads.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_get_ph.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_get_stats.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_map_id2thr.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_map_lwp2thr.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_new.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_reset_stats.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_set_event.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_setconcurrency.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_thr_iter.c: Ditto.
* libc/sys/linux/linuxthreads/td_ta_tsd_iter.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_clear_event.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_dbresume.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_dbsuspend.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_event_enable.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_event_getmsg.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_get_info.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_getfpregs.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_getgregs.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_getxregs.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_getxregsize.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_set_event.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_setfpregs.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_setgregs.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_setprio.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_setsigpending.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_setxregs.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_sigsetmask.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_tsd.c: Ditto.
* libc/sys/linux/linuxthreads/td_thr_validate.c: Ditto.
* libc/sys/linux/linuxthreads/testrtsig.h: Ditto.
* libc/sys/linux/linuxthreads/thread_db.h: Ditto.
* libc/sys/linux/linuxthreads/thread_dbP.h: Ditto.
* libc/sys/linux/linuxthreads/timer_create.c: Ditto.
* libc/sys/linux/linuxthreads/timer_delete.c: Ditto.
* libc/sys/linux/linuxthreads/timer_getoverr.c: Ditto.
* libc/sys/linux/linuxthreads/timer_gettime.c: Ditto.
* libc/sys/linux/linuxthreads/timer_routines.c: Ditto.
* libc/sys/linux/linuxthreads/timer_settime.c: Ditto.
* libc/sys/linux/linuxthreads/tst-cancel.c: Ditto.
* libc/sys/linux/linuxthreads/tst-context.c: Ditto.
* libc/sys/linux/linuxthreads/tststack.c: Ditto.
* libc/sys/linux/linuxthreads/unload.c: Ditto.
* libc/sys/linux/linuxthreads/weaks.c: Ditto.
* libc/sys/linux/linuxthreads/wrapsyscall.c: Ditto.
* libc/sys/linux/linuxthreads/bits/initspin.h: Ditto.
* libc/sys/linux/linuxthreads/bits/libc-lock.h: Ditto.
* libc/sys/linux/linuxthreads/bits/libc-tsd.h: Ditto.
* libc/sys/linux/linuxthreads/bits/local_lim.h: Ditto.
* libc/sys/linux/linuxthreads/bits/posix_opt.h: Ditto.
* libc/sys/linux/linuxthreads/bits/pthreadtypes.h: Ditto.
* libc/sys/linux/linuxthreads/bits/sigthread.h: Ditto.
* libc/sys/linux/linuxthreads/machine/Makefile.am: Ditto.
* libc/sys/linux/linuxthreads/machine/Makefile.in: Ditto.
* libc/sys/linux/linuxthreads/machine/aclocal.m4: Ditto.
* libc/sys/linux/linuxthreads/machine/configure: Ditto.
* libc/sys/linux/linuxthreads/machine/configure.in: Ditto.
* libc/sys/linux/linuxthreads/machine/generic/generic-sysd: Ditto.ep.h
* libc/sys/linux/linuxthreads/machine/i386/Makefile.am: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/Makefile.in: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/aclocal.m4: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/bp-asm.h: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/clone.S: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/configure: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/configure.in: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.S: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.h: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/pspinlock.c: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/pt-machine.h: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/sigcontextinfo.h: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/stackinfo.h: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/sysdep.S: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/sysdep.h: Ditto.
* libc/sys/linux/linuxthreads/machine/i386/useldt.h: Ditto.
* libc/sys/linux/machine/i386/dl-machine.h: Ditto.
* libc/sys/linux/net/Makefile.am: Ditto.
* libc/sys/linux/net/Makefile.in: Ditto.
* libc/sys/linux/net/addr2ascii.3: Ditto.
* libc/sys/linux/net/addr2ascii.c: Ditto.
* libc/sys/linux/net/ascii2addr.c: Ditto.
* libc/sys/linux/net/base64.c: Ditto.
* libc/sys/linux/net/bindresvport.c: Ditto.
* libc/sys/linux/net/byteorder.3: Ditto.
* libc/sys/linux/net/ether_addr.c: Ditto.
* libc/sys/linux/net/ethers.3: Ditto.
* libc/sys/linux/net/getaddrinfo.3: Ditto.
* libc/sys/linux/net/getaddrinfo.c: Ditto.
* libc/sys/linux/net/gethostbydns.c: Ditto.
* libc/sys/linux/net/gethostbyht.c: Ditto.
* libc/sys/linux/net/gethostbyname.3: Ditto.
* libc/sys/linux/net/gethostbynis.c: Ditto.
* libc/sys/linux/net/gethostnamadr.c: Ditto.
* libc/sys/linux/net/getifaddrs.3: Ditto.
* libc/sys/linux/net/getifaddrs.c: Ditto.
* libc/sys/linux/net/getipnodebyname.3: Ditto.
* libc/sys/linux/net/getnameinfo.3: Ditto.
* libc/sys/linux/net/getnameinfo.c: Ditto.
* libc/sys/linux/net/getnetbydns.c: Ditto.
* libc/sys/linux/net/getnetbyht.c: Ditto.
* libc/sys/linux/net/getnetbynis.c: Ditto.
* libc/sys/linux/net/getnetent.3: Ditto.
* libc/sys/linux/net/getnetnamadr.c: Ditto.
* libc/sys/linux/net/getproto.c: Ditto.
* libc/sys/linux/net/getprotoent.3: Ditto.
* libc/sys/linux/net/getprotoent.c: Ditto.
* libc/sys/linux/net/getprotoname.c: Ditto.
* libc/sys/linux/net/getservbyname.c: Ditto.
* libc/sys/linux/net/getservbyport.c: Ditto.
* libc/sys/linux/net/getservent.3: Ditto.
* libc/sys/linux/net/getservent.c: Ditto.
* libc/sys/linux/net/herror.c: Ditto.
* libc/sys/linux/net/hesiod.3: Ditto.
* libc/sys/linux/net/hesiod.c: Ditto.
* libc/sys/linux/net/if_indextoname.3: Ditto.
* libc/sys/linux/net/ifname.c: Ditto.
* libc/sys/linux/net/inet.3: Ditto.
* libc/sys/linux/net/inet6_option_s: Ditto.pace.3
* libc/sys/linux/net/inet6_rthdr_space.3: Ditto.
* libc/sys/linux/net/inet_addr.c: Ditto.
* libc/sys/linux/net/inet_lnaof.c: Ditto.
* libc/sys/linux/net/inet_makeaddr.c: Ditto.
* libc/sys/linux/net/inet_net.3: Ditto.
* libc/sys/linux/net/inet_net_ntop.c: Ditto.
* libc/sys/linux/net/inet_net_pton.c: Ditto.
* libc/sys/linux/net/inet_neta.c: Ditto.
* libc/sys/linux/net/inet_netof.c: Ditto.
* libc/sys/linux/net/inet_network.c: Ditto.
* libc/sys/linux/net/inet_ntoa.c: Ditto.
* libc/sys/linux/net/inet_ntop.c: Ditto.
* libc/sys/linux/net/inet_pton.c: Ditto.
* libc/sys/linux/net/innetgr-stub.c: Ditto.
* libc/sys/linux/net/ip6opt.c: Ditto.
* libc/sys/linux/net/iso_addr.3: Ditto.
* libc/sys/linux/net/iso_addr.c: Ditto.
* libc/sys/linux/net/issetugid-stub.c: Ditto.
* libc/sys/linux/net/linkaddr.3: Ditto.
* libc/sys/linux/net/linkaddr.c: Ditto.
* libc/sys/linux/net/map_v4v6.c: Ditto.
* libc/sys/linux/net/name6.c: Ditto.
* libc/sys/linux/net/namespace.h: Ditto.
* libc/sys/linux/net/ns.3: Ditto.
* libc/sys/linux/net/ns_addr.c: Ditto.
* libc/sys/linux/net/ns_name.c: Ditto.
* libc/sys/linux/net/ns_netint.c: Ditto.
* libc/sys/linux/net/ns_ntoa.c: Ditto.
* libc/sys/linux/net/ns_parse.c: Ditto.
* libc/sys/linux/net/ns_print.c: Ditto.
* libc/sys/linux/net/ns_ttl.c: Ditto.
* libc/sys/linux/net/nsap_addr.c: Ditto.
* libc/sys/linux/net/nsdispatch.3: Ditto.
* libc/sys/linux/net/nsdispatch.c: Ditto.
* libc/sys/linux/net/nslexer.c: Ditto.
* libc/sys/linux/net/nslexer.l: Ditto.
* libc/sys/linux/net/nsparser.c: Ditto.
* libc/sys/linux/net/nsparser.h: Ditto.
* libc/sys/linux/net/nsparser.y: Ditto.
* libc/sys/linux/net/rcmd.3: Ditto.
* libc/sys/linux/net/rcmd.c: Ditto.
* libc/sys/linux/net/rcmdsh.3: Ditto.
* libc/sys/linux/net/rcmdsh.c: Ditto.
* libc/sys/linux/net/recv.c: Ditto.
* libc/sys/linux/net/res_comp.c: Ditto.
* libc/sys/linux/net/res_config.h: Ditto.
* libc/sys/linux/net/res_data.c: Ditto.
* libc/sys/linux/net/res_debug.c: Ditto.
* libc/sys/linux/net/res_init.c: Ditto.
* libc/sys/linux/net/res_mkquery.c: Ditto.
* libc/sys/linux/net/res_mkupdate.c: Ditto.
* libc/sys/linux/net/res_query.c: Ditto.
* libc/sys/linux/net/res_send.c: Ditto.
* libc/sys/linux/net/res_update.c: Ditto.
* libc/sys/linux/net/resolver.3: Ditto.
* libc/sys/linux/net/rthdr.c: Ditto.
* libc/sys/linux/net/send.c: Ditto.
* libc/sys/linux/net/un-namespace.h: Ditto.
* libc/sys/linux/net/vars.c: Ditto.
* libc/sys/linux/stdlib/COPYRIGHT: Ditto.
* libc/sys/linux/stdlib/Makefile.am: Ditto.
* libc/sys/linux/stdlib/Makefile.in: Ditto.
* libc/sys/linux/stdlib/cclass.h: Ditto.
* libc/sys/linux/stdlib/cname.h: Ditto.
* libc/sys/linux/stdlib/collate.c: Ditto.
* libc/sys/linux/stdlib/collate.h: Ditto.
* libc/sys/linux/stdlib/collcmp.c: Ditto.
* libc/sys/linux/stdlib/engine.c: Ditto.
* libc/sys/linux/stdlib/fnmatch.3: Ditto.
* libc/sys/linux/stdlib/fnmatch.c: Ditto.
* libc/sys/linux/stdlib/glob.3: Ditto.
* libc/sys/linux/stdlib/glob.c: Ditto.
* libc/sys/linux/stdlib/reallocf.c: Ditto.
* libc/sys/linux/stdlib/regcomp.c: Ditto.
* libc/sys/linux/stdlib/regerror.c: Ditto.
* libc/sys/linux/stdlib/regex.3: Ditto.
* libc/sys/linux/stdlib/regex2.h: Ditto.
* libc/sys/linux/stdlib/regexec.c: Ditto.
* libc/sys/linux/stdlib/regfree.c: Ditto.
* libc/sys/linux/stdlib/utils.h: Ditto.
* libc/sys/linux/stdlib/wordexp.c: Ditto.
* libc/sys/linux/stdlib/wordfree.c: Ditto.
* libc/sys/linux/sys/dlfcn.h: Ditto.
* libc/sys/linux/sys/elfclass.h: Ditto.
* libc/sys/linux/sys/event.h: Ditto.
* libc/sys/linux/sys/ioccom.h: Ditto.
* libc/sys/linux/sys/libc-tsd.h: Ditto.
* libc/sys/linux/sys/link.h: Ditto.
* libc/sys/linux/sys/lock.h: Ditto.
* libc/sys/linux/sys/param.h: Ditto.
* libc/sys/linux/sys/socket.h: Ditto.
* libc/sys/linux/sys/sockio.h: Ditto.
Diffstat (limited to 'newlib/libc/sys/linux/linuxthreads')
134 files changed, 33454 insertions, 0 deletions
diff --git a/newlib/libc/sys/linux/linuxthreads/LICENSE b/newlib/libc/sys/linux/linuxthreads/LICENSE new file mode 100644 index 000000000..7bcca6050 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/LICENSE @@ -0,0 +1,501 @@ +GNU LIBRARY GENERAL PUBLIC LICENSE +********************************** + + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + [This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + +Preamble +======== + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License, which was designed for utility +programs. This license, the GNU Library General Public License, +applies to certain designated libraries. This license is quite +different from the ordinary one; be sure to read it in full, and don't +assume that anything in it is the same as in the ordinary license. + + The reason we have a separate public license for some libraries is +that they blur the distinction we usually make between modifying or +adding to a program and simply using it. Linking a program with a +library, without changing the library, is in some sense simply using +the library, and is analogous to running a utility program or +application program. However, in a textual and legal sense, the linked +executable is a combined work, a derivative of the original library, +and the ordinary General Public License treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended +to permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to +achieve this as regards changes in header files, but we have achieved +it as regards changes in the actual functions of the Library.) The +hope is that this will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which + contains a notice placed by the copyright holder or other + authorized party saying it may be distributed under the terms of + this Library General Public License (also called "this License"). + Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data + prepared so as to be conveniently linked with application programs + (which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work + which has been distributed under these terms. A "work based on the + Library" means either the Library or any derivative work under + copyright law: that is to say, a work containing the Library or a + portion of it, either verbatim or with modifications and/or + translated straightforwardly into another language. (Hereinafter, + translation is included without limitation in the term + "modification".) + + "Source code" for a work means the preferred form of the work for + making modifications to it. For a library, complete source code + means all the source code for all modules it contains, plus any + associated interface definition files, plus the scripts used to + control compilation and installation of the library. + + Activities other than copying, distribution and modification are + not covered by this License; they are outside its scope. The act + of running a program using the Library is not restricted, and + output from such a program is covered only if its contents + constitute a work based on the Library (independent of the use of + the Library in a tool for writing it). Whether that is true + depends on what the Library does and what the program that uses + the Library does. + + 1. You may copy and distribute verbatim copies of the Library's + complete source code as you receive it, in any medium, provided + that you conspicuously and appropriately publish on each copy an + appropriate copyright notice and disclaimer of warranty; keep + intact all the notices that refer to this License and to the + absence of any warranty; and distribute a copy of this License + along with the Library. + + You may charge a fee for the physical act of transferring a copy, + and you may at your option offer warranty protection in exchange + for a fee. + + 2. You may modify your copy or copies of the Library or any portion + of it, thus forming a work based on the Library, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions: + + a. The modified work must itself be a software library. + + b. You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c. You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d. If a facility in the modified Library refers to a function or + a table of data to be supplied by an application program that + uses the facility, other than as an argument passed when the + facility is invoked, then you must make a good faith effort + to ensure that, in the event an application does not supply + such function or table, the facility still operates, and + performs whatever part of its purpose remains meaningful. + + (For example, a function in a library to compute square roots + has a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function + must be optional: if the application does not supply it, the + square root function must still compute square roots.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the + Library, and can be reasonably considered independent and separate + works in themselves, then this License, and its terms, do not + apply to those sections when you distribute them as separate + works. But when you distribute the same sections as part of a + whole which is a work based on the Library, the distribution of + the whole must be on the terms of this License, whose permissions + for other licensees extend to the entire whole, and thus to each + and every part regardless of who wrote it. + + Thus, it is not the intent of this section to claim rights or + contest your rights to work written entirely by you; rather, the + intent is to exercise the right to control the distribution of + derivative or collective works based on the Library. + + In addition, mere aggregation of another work not based on the + Library with the Library (or with a work based on the Library) on + a volume of a storage or distribution medium does not bring the + other work under the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public + License instead of this License to a given copy of the Library. + To do this, you must alter all the notices that refer to this + License, so that they refer to the ordinary GNU General Public + License, version 2, instead of to this License. (If a newer + version than version 2 of the ordinary GNU General Public License + has appeared, then you can specify that version instead if you + wish.) Do not make any other change in these notices. + + Once this change is made in a given copy, it is irreversible for + that copy, so the ordinary GNU General Public License applies to + all subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of + the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or + derivative of it, under Section 2) in object code or executable + form under the terms of Sections 1 and 2 above provided that you + accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software + interchange. + + If distribution of object code is made by offering access to copy + from a designated place, then offering equivalent access to copy + the source code from the same place satisfies the requirement to + distribute the source code, even though third parties are not + compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the + Library, but is designed to work with the Library by being + compiled or linked with it, is called a "work that uses the + Library". Such a work, in isolation, is not a derivative work of + the Library, and therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library + creates an executable that is a derivative of the Library (because + it contains portions of the Library), rather than a "work that + uses the library". The executable is therefore covered by this + License. Section 6 states terms for distribution of such + executables. + + When a "work that uses the Library" uses material from a header + file that is part of the Library, the object code for the work may + be a derivative work of the Library even though the source code is + not. Whether this is true is especially significant if the work + can be linked without the Library, or if the work is itself a + library. The threshold for this to be true is not precisely + defined by law. + + If such an object file uses only numerical parameters, data + structure layouts and accessors, and small macros and small inline + functions (ten lines or less in length), then the use of the object + file is unrestricted, regardless of whether it is legally a + derivative work. (Executables containing this object code plus + portions of the Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may + distribute the object code for the work under the terms of Section + 6. Any executables containing that work also fall under Section 6, + whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or + link a "work that uses the Library" with the Library to produce a + work containing portions of the Library, and distribute that work + under terms of your choice, provided that the terms permit + modification of the work for the customer's own use and reverse + engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the + Library is used in it and that the Library and its use are covered + by this License. You must supply a copy of this License. If the + work during execution displays copyright notices, you must include + the copyright notice for the Library among them, as well as a + reference directing the user to the copy of this License. Also, + you must do one of these things: + + a. Accompany the work with the complete corresponding + machine-readable source code for the Library including + whatever changes were used in the work (which must be + distributed under Sections 1 and 2 above); and, if the work + is an executable linked with the Library, with the complete + machine-readable "work that uses the Library", as object code + and/or source code, so that the user can modify the Library + and then relink to produce a modified executable containing + the modified Library. (It is understood that the user who + changes the contents of definitions files in the Library will + not necessarily be able to recompile the application to use + the modified definitions.) + + b. Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + c. If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the + above specified materials from the same place. + + d. Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the + Library" must include any data and utility programs needed for + reproducing the executable from it. However, as a special + exception, the source code distributed need not include anything + that is normally distributed (in either source or binary form) + with the major components (compiler, kernel, and so on) of the + operating system on which the executable runs, unless that + component itself accompanies the executable. + + It may happen that this requirement contradicts the license + restrictions of other proprietary libraries that do not normally + accompany the operating system. Such a contradiction means you + cannot use both them and the Library together in an executable + that you distribute. + + 7. You may place library facilities that are a work based on the + Library side-by-side in a single library together with other + library facilities not covered by this License, and distribute + such a combined library, provided that the separate distribution + of the work based on the Library and of the other library + facilities is otherwise permitted, and provided that you do these + two things: + + a. Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b. Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same + work. + + 8. You may not copy, modify, sublicense, link with, or distribute the + Library except as expressly provided under this License. Any + attempt otherwise to copy, modify, sublicense, link with, or + distribute the Library is void, and will automatically terminate + your rights under this License. However, parties who have + received copies, or rights, from you under this License will not + have their licenses terminated so long as such parties remain in + full compliance. + + 9. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify + or distribute the Library or its derivative works. These actions + are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Library (or any work + based on the Library), you indicate your acceptance of this + License to do so, and all its terms and conditions for copying, + distributing or modifying the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the + Library), the recipient automatically receives a license from the + original licensor to copy, distribute, link with or modify the + Library subject to these terms and conditions. You may not impose + any further restrictions on the recipients' exercise of the rights + granted herein. You are not responsible for enforcing compliance + by third parties to this License. + + 11. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent + issues), conditions are imposed on you (whether by court order, + agreement or otherwise) that contradict the conditions of this + License, they do not excuse you from the conditions of this + License. If you cannot distribute so as to satisfy simultaneously + your obligations under this License and any other pertinent + obligations, then as a consequence you may not distribute the + Library at all. For example, if a patent license would not permit + royalty-free redistribution of the Library by all those who + receive copies directly or indirectly through you, then the only + way you could satisfy both it and this License would be to refrain + entirely from distribution of the Library. + + If any portion of this section is held invalid or unenforceable + under any particular circumstance, the balance of the section is + intended to apply, and the section as a whole is intended to apply + in other circumstances. + + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of + any such claims; this section has the sole purpose of protecting + the integrity of the free software distribution system which is + implemented by public license practices. Many people have made + generous contributions to the wide range of software distributed + through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is + willing to distribute software through any other system and a + licensee cannot impose that choice. + + This section is intended to make thoroughly clear what is believed + to be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in + certain countries either by patents or by copyrighted interfaces, + the original copyright holder who places the Library under this + License may add an explicit geographical distribution limitation + excluding those countries, so that distribution is permitted only + in or among countries not thus excluded. In such case, this + License incorporates the limitation as if written in the body of + this License. + + 13. The Free Software Foundation may publish revised and/or new + versions of the Library General Public License from time to time. + Such new versions will be similar in spirit to the present version, + but may differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the + Library specifies a version number of this License which applies + to it and "any later version", you have the option of following + the terms and conditions either of that version or of any later + version published by the Free Software Foundation. If the Library + does not specify a license version number, you may choose any + version ever published by the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free + programs whose distribution conditions are incompatible with these, + write to the author to ask for permission. For software which is + copyrighted by the Free Software Foundation, write to the Free + Software Foundation; we sometimes make exceptions for this. Our + decision will be guided by the two goals of preserving the free + status of all derivatives of our free software and of promoting + the sharing and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE + LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT + NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE + QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE + LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY + SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY + MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, + INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR + INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF + DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU + OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY + OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries +============================================== + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of +the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should have +at least the "copyright" line and a pointer to where the full notice is +found. + + ONE LINE TO GIVE THE LIBRARY'S NAME AND AN IDEA OF WHAT IT DOES. + Copyright (C) YEAR NAME OF AUTHOR + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2 of the License, or (at + your option) any later version. + + This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + + Also add information on how to contact you by electronic and paper +mail. + + You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the library + `Frob' (a library for tweaking knobs) written by James Random Hacker. + + SIGNATURE OF TY COON, 1 April 1990 + Ty Coon, President of Vice + + That's all there is to it! + diff --git a/newlib/libc/sys/linux/linuxthreads/Makefile.am b/newlib/libc/sys/linux/linuxthreads/Makefile.am new file mode 100644 index 000000000..a47cecc17 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/Makefile.am @@ -0,0 +1,139 @@ +## Process this file with automake to generate Makefile.in + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = -I$(srcdir)/../include -I$(srcdir)/machine/$(machine_dir) -I$(srcdir)/machine/generic $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) -I$(srcdir)/.. + +LIBTOOL_VERSION_INFO = 0:0:0 + +LIB_SOURCES= \ + attr.c barrier.c condvar.c \ + events.c getcpuclockid.c getreent.c join.c lockfile.c manager.c \ + mq_notify.c oldsemaphore.c prio.c ptclock_gettime.c ptclock_settime.c \ + ptlongjmp.c pt-machine.c reent.c rwlock.c semaphore.c \ + signals.c spinlock.c sysctl.c \ + timer_create.c timer_getoverr.c timer_routines.c \ + timer_delete.c timer_gettime.c timer_settime.c \ + wrapsyscall.c + +LIB_DB_SOURCES = td_init.c td_log.c td_ta_delete.c td_ta_get_nthreads.c \ + td_ta_get_ph.c td_ta_map_id2thr.c td_ta_map_lwp2thr.c \ + td_ta_new.c td_ta_thr_iter.c td_ta_tsd_iter.c \ + td_thr_get_info.c td_thr_getfpregs.c td_thr_getgregs.c \ + td_thr_getxregs.c td_thr_getxregsize.c td_thr_setfpregs.c \ + td_thr_setgregs.c td_thr_setprio.c td_thr_setsigpending.c \ + td_thr_setxregs.c td_thr_sigsetmask.c td_thr_tsd.c \ + td_thr_validate.c td_thr_dbsuspend.c td_thr_dbresume.c \ + td_ta_setconcurrency.c td_ta_enable_stats.c \ + td_ta_reset_stats.c td_ta_get_stats.c td_ta_event_addr.c \ + td_thr_event_enable.c td_thr_set_event.c \ + td_thr_clear_event.c td_thr_event_getmsg.c \ + td_ta_set_event.c td_ta_event_getmsg.c \ + td_ta_clear_event.c td_symbol_list.c + +# Because of how libtool moves objects around, these files must be built last. +LIBADD_OBJS = mutex.$(oext) specific.$(oext) pthread.$(oext) \ + cancel.$(oext) + +ELIX_3_OBJS = \ + ptfork.$(oext) + +if ELIX_LEVEL_1 +EXTRA_OBJS = reqsyscalls.$(oext) +else +if ELIX_LEVEL_2 +EXTRA_OBJS = reqsyscalls.$(oext) +else +EXTRA_OBJS = $(ELIX_3_OBJS) +endif +endif + +SUBDIRS = machine . + +tooldir = $(tooldir) +toollibdir = $(top_toollibdir) + +libpthread_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO) -release newlib -no-undefined -Xcompiler -nostdlib -Xlinker --version-script=$(srcdir)/../shared.ld `cat extra-libtool-objlist` +libthread_db_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO) -release newlib -no-undefined -Xcompiler -nostdlib -Xlinker --version-script=$(srcdir)/../shared.ld + +if USE_LIBTOOL + +# objects listed later in LIBPTHREAD_OBJLISTS will override those listed earlier +extra-libtool-objlist: $(MACHINE_OBJLIST) + cat $(MACHINE_OBJLIST) | $(AWK) '{ libpthread[$$1] = $$2 }; END { for (x in libpthread) printf ("%s\n", libpthread[x]) }' > $@ + +toollib_LTLIBRARIES = libpthread.la libthread_db.la +libpthread_la_SOURCES = $(LIB_SOURCES) +libpthread_la_LIBADD = $(LIBADD_OBJS) $(EXTRA_OBJS) +## libpthread_la_DEPENDENCIES = defs.h crti.S +libpthread_la_DEPENDENCIES = $(LIBADD_OBJS) $(EXTRA_OBJS) extra-libtool-objlist +noinst_DATA=objectlist.awk.in +LIB_COMPILE = $(LTCOMPILE) + +libthread_db_la_SOURCES = $(LIB_DB_SOURCES) + +else + +toollib_LIBRARIES = libpthread.a libthread_db.a +libpthread_a_SOURCES = $(LIB_SOURCES) +libpthread_a_LIBADD = $(LIBADD_OBJS) $(EXTRA_OBJS) $(MACHINE_LIB) +## libpthread_a_DEPENDENCIES = defs.h crti.S +libpthread_a_DEPENDENCIES = $(LIBADD_OBJS) $(EXTRA_OBJS) $(MACHINE_LIB) +LIB_COMPILE = $(COMPILE) + +libthread_db_a_SOURCES = $(LIB_DB_SOURCES) + +endif # USE_LIBTOOL + +include $(srcdir)/../../../../Makefile.shared + +doc: + +install-data-local: install-toollibLIBRARIES + -rm -f $(DESTDIR)$(toollibdir)/libthread_db.so.1 + ln -s $(DESTDIR)$(toollibdir)/libthread_db.so $(DESTDIR)$(toollibdir)/libthread_db.so.1 || cp $(DESTDIR)$(toollibdir)/libthread_db.so $(DESTDIR)$(toollibdir)/libthread_db.so.1 + +AM_CFLAGS = -D_XOPEN_SOURCE=600 -D_GNU_SOURCE=1 +ACLOCAL_AMFLAGS = -I ../../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host + +## PTHREAD_HEADERS=pthread.h semaphore.h + +CFLAGS_pt_initfini = -g0 -fPIC -fno-inline-functions +CFLAGS_noweak=-D__NO_WEAK_PTHREAD_ALIASES +CFLAGS_cancel=-D__NO_WEAK_PTHREAD_ALIASES -D_RPC_THREAD_SAFE_ +CFLAGS_pthread=-D__NO_WEAK_PTHREAD_ALIASES -DHAVE_Z_NODELETE + +pt-initfini.s: $(srcdir)/pt-initfini.c + $(CC) -S $(CFLAGS_pt_initfini) -finhibit-size-directive \ + $(patsubst -f%,-fno-%,$(exceptions)) -o $@ + +# We only have one kind of startup code files. Static binaries and +# shared libraries are build using the PIC version. +crti.S: pt-initfini.s + sed -n -e '1,/@HEADER_ENDS/p' \ + -e '/@_.*_PROLOG_BEGINS/,/@_.*_PROLOG_ENDS/p' \ + -e '/@TRAILER_BEGINS/,$$p' $< > $@ + +defs.h: pt-initfini.s + sed -n -e '/@TESTS_BEGIN/,/@TESTS_END/p' $< | \ + $(AWK) -f defs.awk > $@ + +crti.o: crti.S defs.h + $(CC) -g0 $(ASFLAGS) -o $@ + +mutex.$(oext): $(srcdir)/mutex.c + $(LIB_COMPILE) $(CFLAGS_noweak) -c $< -o $@ + +specific.$(oext): $(srcdir)/specific.c + $(LIB_COMPILE) $(CFLAGS_noweak) -c $< -o $@ + +pthread.$(oext): $(srcdir)/pthread.c + $(LIB_COMPILE) $(CFLAGS_pthread) -c $< -o $@ + +ptfork.$(oext): $(srcdir)/ptfork.c + $(LIB_COMPILE) $(CFLAGS_noweak) -c $< -o $@ + +cancel.$(oext): $(srcdir)/cancel.c + $(LIB_COMPILE) $(CFLAGS_cancel) -c $< -o $@ + diff --git a/newlib/libc/sys/linux/linuxthreads/Makefile.in b/newlib/libc/sys/linux/linuxthreads/Makefile.in new file mode 100644 index 000000000..6ab7ced4c --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/Makefile.in @@ -0,0 +1,705 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AR = @AR@ +AS = @AS@ +AWK = @AWK@ +CC = @CC@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DLLTOOL = @DLLTOOL@ +EXEEXT = @EXEEXT@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MACHINE_LIB = @MACHINE_LIB@ +MACHINE_OBJLIST = @MACHINE_OBJLIST@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ +aext = @aext@ +libm_machine_dir = @libm_machine_dir@ +machine_dir = @machine_dir@ +newlib_basedir = @newlib_basedir@ +oext = @oext@ +sys_dir = @sys_dir@ + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = -I$(srcdir)/../include -I$(srcdir)/machine/$(machine_dir) -I$(srcdir)/machine/generic $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) -I$(srcdir)/.. + +LIBTOOL_VERSION_INFO = 0:0:0 + +LIB_SOURCES = \ + attr.c barrier.c condvar.c \ + events.c getcpuclockid.c getreent.c join.c lockfile.c manager.c \ + mq_notify.c oldsemaphore.c prio.c ptclock_gettime.c ptclock_settime.c \ + ptlongjmp.c pt-machine.c reent.c rwlock.c semaphore.c \ + signals.c spinlock.c sysctl.c \ + timer_create.c timer_getoverr.c timer_routines.c \ + timer_delete.c timer_gettime.c timer_settime.c \ + wrapsyscall.c + + +LIB_DB_SOURCES = td_init.c td_log.c td_ta_delete.c td_ta_get_nthreads.c \ + td_ta_get_ph.c td_ta_map_id2thr.c td_ta_map_lwp2thr.c \ + td_ta_new.c td_ta_thr_iter.c td_ta_tsd_iter.c \ + td_thr_get_info.c td_thr_getfpregs.c td_thr_getgregs.c \ + td_thr_getxregs.c td_thr_getxregsize.c td_thr_setfpregs.c \ + td_thr_setgregs.c td_thr_setprio.c td_thr_setsigpending.c \ + td_thr_setxregs.c td_thr_sigsetmask.c td_thr_tsd.c \ + td_thr_validate.c td_thr_dbsuspend.c td_thr_dbresume.c \ + td_ta_setconcurrency.c td_ta_enable_stats.c \ + td_ta_reset_stats.c td_ta_get_stats.c td_ta_event_addr.c \ + td_thr_event_enable.c td_thr_set_event.c \ + td_thr_clear_event.c td_thr_event_getmsg.c \ + td_ta_set_event.c td_ta_event_getmsg.c \ + td_ta_clear_event.c td_symbol_list.c + + +# Because of how libtool moves objects around, these files must be built last. +LIBADD_OBJS = mutex.$(oext) specific.$(oext) pthread.$(oext) \ + cancel.$(oext) + + +ELIX_3_OBJS = \ + ptfork.$(oext) + +@ELIX_LEVEL_1_TRUE@EXTRA_OBJS = @ELIX_LEVEL_1_TRUE@reqsyscalls.$(oext) +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@EXTRA_OBJS = @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@reqsyscalls.$(oext) +@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@EXTRA_OBJS = @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@$(ELIX_3_OBJS) + +SUBDIRS = machine . + +tooldir = $(tooldir) +toollibdir = $(top_toollibdir) + +libpthread_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO) -release newlib -no-undefined -Xcompiler -nostdlib -Xlinker --version-script=$(srcdir)/../shared.ld `cat extra-libtool-objlist` +libthread_db_la_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO) -release newlib -no-undefined -Xcompiler -nostdlib -Xlinker --version-script=$(srcdir)/../shared.ld + +@USE_LIBTOOL_TRUE@toollib_LTLIBRARIES = @USE_LIBTOOL_TRUE@libpthread.la libthread_db.la +@USE_LIBTOOL_TRUE@libpthread_la_SOURCES = @USE_LIBTOOL_TRUE@$(LIB_SOURCES) +@USE_LIBTOOL_TRUE@libpthread_la_LIBADD = @USE_LIBTOOL_TRUE@$(LIBADD_OBJS) $(EXTRA_OBJS) +@USE_LIBTOOL_TRUE@libpthread_la_DEPENDENCIES = @USE_LIBTOOL_TRUE@$(LIBADD_OBJS) $(EXTRA_OBJS) extra-libtool-objlist +@USE_LIBTOOL_TRUE@noinst_DATA = @USE_LIBTOOL_TRUE@objectlist.awk.in +@USE_LIBTOOL_TRUE@LIB_COMPILE = @USE_LIBTOOL_TRUE@$(LTCOMPILE) +@USE_LIBTOOL_FALSE@LIB_COMPILE = @USE_LIBTOOL_FALSE@$(COMPILE) + +@USE_LIBTOOL_TRUE@libthread_db_la_SOURCES = @USE_LIBTOOL_TRUE@$(LIB_DB_SOURCES) + +@USE_LIBTOOL_FALSE@toollib_LIBRARIES = @USE_LIBTOOL_FALSE@libpthread.a libthread_db.a +@USE_LIBTOOL_FALSE@libpthread_a_SOURCES = @USE_LIBTOOL_FALSE@$(LIB_SOURCES) +@USE_LIBTOOL_FALSE@libpthread_a_LIBADD = @USE_LIBTOOL_FALSE@$(LIBADD_OBJS) $(EXTRA_OBJS) $(MACHINE_LIB) +@USE_LIBTOOL_FALSE@libpthread_a_DEPENDENCIES = @USE_LIBTOOL_FALSE@$(LIBADD_OBJS) $(EXTRA_OBJS) $(MACHINE_LIB) + +@USE_LIBTOOL_FALSE@libthread_db_a_SOURCES = @USE_LIBTOOL_FALSE@$(LIB_DB_SOURCES) + +AM_CFLAGS = -D_XOPEN_SOURCE=600 -D_GNU_SOURCE=1 +ACLOCAL_AMFLAGS = -I ../../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host + +CFLAGS_pt_initfini = -g0 -fPIC -fno-inline-functions +CFLAGS_noweak = -D__NO_WEAK_PTHREAD_ALIASES +CFLAGS_cancel = -D__NO_WEAK_PTHREAD_ALIASES -D_RPC_THREAD_SAFE_ +CFLAGS_pthread = -D__NO_WEAK_PTHREAD_ALIASES -DHAVE_Z_NODELETE +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../../mkinstalldirs +CONFIG_CLEAN_FILES = +LIBRARIES = $(toollib_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LIBS = @LIBS@ +@USE_LIBTOOL_FALSE@libpthread_a_OBJECTS = attr.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@barrier.$(OBJEXT) condvar.$(OBJEXT) events.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@getcpuclockid.$(OBJEXT) getreent.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@join.$(OBJEXT) lockfile.$(OBJEXT) manager.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@mq_notify.$(OBJEXT) oldsemaphore.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@prio.$(OBJEXT) ptclock_gettime.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@ptclock_settime.$(OBJEXT) ptlongjmp.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@pt-machine.$(OBJEXT) reent.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@rwlock.$(OBJEXT) semaphore.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@signals.$(OBJEXT) spinlock.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@sysctl.$(OBJEXT) timer_create.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@timer_getoverr.$(OBJEXT) timer_routines.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@timer_delete.$(OBJEXT) timer_gettime.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@timer_settime.$(OBJEXT) wrapsyscall.$(OBJEXT) +libthread_db_a_LIBADD = +@USE_LIBTOOL_FALSE@libthread_db_a_OBJECTS = td_init.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_log.$(OBJEXT) td_ta_delete.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_get_nthreads.$(OBJEXT) td_ta_get_ph.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_map_id2thr.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_map_lwp2thr.$(OBJEXT) td_ta_new.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_thr_iter.$(OBJEXT) td_ta_tsd_iter.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_get_info.$(OBJEXT) td_thr_getfpregs.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_getgregs.$(OBJEXT) td_thr_getxregs.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_getxregsize.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_setfpregs.$(OBJEXT) td_thr_setgregs.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_setprio.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_setsigpending.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_setxregs.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_sigsetmask.$(OBJEXT) td_thr_tsd.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_validate.$(OBJEXT) td_thr_dbsuspend.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_dbresume.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_setconcurrency.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_enable_stats.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_reset_stats.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_get_stats.$(OBJEXT) td_ta_event_addr.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_event_enable.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_set_event.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_clear_event.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_thr_event_getmsg.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_set_event.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_event_getmsg.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@td_ta_clear_event.$(OBJEXT) td_symbol_list.$(OBJEXT) +LTLIBRARIES = $(toollib_LTLIBRARIES) + +@USE_LIBTOOL_TRUE@libpthread_la_OBJECTS = attr.lo barrier.lo condvar.lo \ +@USE_LIBTOOL_TRUE@events.lo getcpuclockid.lo getreent.lo join.lo \ +@USE_LIBTOOL_TRUE@lockfile.lo manager.lo mq_notify.lo oldsemaphore.lo \ +@USE_LIBTOOL_TRUE@prio.lo ptclock_gettime.lo ptclock_settime.lo \ +@USE_LIBTOOL_TRUE@ptlongjmp.lo pt-machine.lo reent.lo rwlock.lo \ +@USE_LIBTOOL_TRUE@semaphore.lo signals.lo spinlock.lo sysctl.lo \ +@USE_LIBTOOL_TRUE@timer_create.lo timer_getoverr.lo timer_routines.lo \ +@USE_LIBTOOL_TRUE@timer_delete.lo timer_gettime.lo timer_settime.lo \ +@USE_LIBTOOL_TRUE@wrapsyscall.lo +libthread_db_la_LIBADD = +@USE_LIBTOOL_TRUE@libthread_db_la_OBJECTS = td_init.lo td_log.lo \ +@USE_LIBTOOL_TRUE@td_ta_delete.lo td_ta_get_nthreads.lo td_ta_get_ph.lo \ +@USE_LIBTOOL_TRUE@td_ta_map_id2thr.lo td_ta_map_lwp2thr.lo td_ta_new.lo \ +@USE_LIBTOOL_TRUE@td_ta_thr_iter.lo td_ta_tsd_iter.lo \ +@USE_LIBTOOL_TRUE@td_thr_get_info.lo td_thr_getfpregs.lo \ +@USE_LIBTOOL_TRUE@td_thr_getgregs.lo td_thr_getxregs.lo \ +@USE_LIBTOOL_TRUE@td_thr_getxregsize.lo td_thr_setfpregs.lo \ +@USE_LIBTOOL_TRUE@td_thr_setgregs.lo td_thr_setprio.lo \ +@USE_LIBTOOL_TRUE@td_thr_setsigpending.lo td_thr_setxregs.lo \ +@USE_LIBTOOL_TRUE@td_thr_sigsetmask.lo td_thr_tsd.lo td_thr_validate.lo \ +@USE_LIBTOOL_TRUE@td_thr_dbsuspend.lo td_thr_dbresume.lo \ +@USE_LIBTOOL_TRUE@td_ta_setconcurrency.lo td_ta_enable_stats.lo \ +@USE_LIBTOOL_TRUE@td_ta_reset_stats.lo td_ta_get_stats.lo \ +@USE_LIBTOOL_TRUE@td_ta_event_addr.lo td_thr_event_enable.lo \ +@USE_LIBTOOL_TRUE@td_thr_set_event.lo td_thr_clear_event.lo \ +@USE_LIBTOOL_TRUE@td_thr_event_getmsg.lo td_ta_set_event.lo \ +@USE_LIBTOOL_TRUE@td_ta_event_getmsg.lo td_ta_clear_event.lo \ +@USE_LIBTOOL_TRUE@td_symbol_list.lo +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DATA = $(noinst_DATA) + +DIST_COMMON = Makefile.am Makefile.in aclocal.m4 configure configure.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libpthread_a_SOURCES) $(libthread_db_a_SOURCES) $(libpthread_la_SOURCES) $(libthread_db_la_SOURCES) +OBJECTS = $(libpthread_a_OBJECTS) $(libthread_db_a_OBJECTS) $(libpthread_la_OBJECTS) $(libthread_db_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../../../Makefile.shared + cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in \ + ../../../../acinclude.m4 ../../../../aclocal.m4 \ + ../../../../libtool.m4 + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +mostlyclean-toollibLIBRARIES: + +clean-toollibLIBRARIES: + -test -z "$(toollib_LIBRARIES)" || rm -f $(toollib_LIBRARIES) + +distclean-toollibLIBRARIES: + +maintainer-clean-toollibLIBRARIES: + +install-toollibLIBRARIES: $(toollib_LIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(toollibdir) + @list='$(toollib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_DATA) $$p $(DESTDIR)$(toollibdir)/$$p"; \ + $(INSTALL_DATA) $$p $(DESTDIR)$(toollibdir)/$$p; \ + else :; fi; \ + done + @$(POST_INSTALL) + @list='$(toollib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(RANLIB) $(DESTDIR)$(toollibdir)/$$p"; \ + $(RANLIB) $(DESTDIR)$(toollibdir)/$$p; \ + else :; fi; \ + done + +uninstall-toollibLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(toollib_LIBRARIES)'; for p in $$list; do \ + rm -f $(DESTDIR)$(toollibdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libpthread.a: $(libpthread_a_OBJECTS) $(libpthread_a_DEPENDENCIES) + -rm -f libpthread.a + $(AR) cru libpthread.a $(libpthread_a_OBJECTS) $(libpthread_a_LIBADD) + $(RANLIB) libpthread.a + +libthread_db.a: $(libthread_db_a_OBJECTS) $(libthread_db_a_DEPENDENCIES) + -rm -f libthread_db.a + $(AR) cru libthread_db.a $(libthread_db_a_OBJECTS) $(libthread_db_a_LIBADD) + $(RANLIB) libthread_db.a + +mostlyclean-toollibLTLIBRARIES: + +clean-toollibLTLIBRARIES: + -test -z "$(toollib_LTLIBRARIES)" || rm -f $(toollib_LTLIBRARIES) + +distclean-toollibLTLIBRARIES: + +maintainer-clean-toollibLTLIBRARIES: + +install-toollibLTLIBRARIES: $(toollib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(toollibdir) + @list='$(toollib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(toollibdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(toollibdir)/$$p; \ + else :; fi; \ + done + +uninstall-toollibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(toollib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(toollibdir)/$$p; \ + done + +libpthread.la: $(libpthread_la_OBJECTS) $(libpthread_la_DEPENDENCIES) + $(LINK) -rpath $(toollibdir) $(libpthread_la_LDFLAGS) $(libpthread_la_OBJECTS) $(libpthread_la_LIBADD) $(LIBS) + +libthread_db.la: $(libthread_db_la_OBJECTS) $(libthread_db_la_DEPENDENCIES) + $(LINK) -rpath $(toollibdir) $(libthread_db_la_LDFLAGS) $(libthread_db_la_OBJECTS) $(libthread_db_la_LIBADD) $(LIBS) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive install-info-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-info-am: +install-info: install-info-recursive +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: install-toollibLIBRARIES install-toollibLTLIBRARIES \ + install-data-local +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-toollibLIBRARIES uninstall-toollibLTLIBRARIES +uninstall: uninstall-recursive +all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(DATA) +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(toollibdir) $(DESTDIR)$(toollibdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-toollibLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-toollibLTLIBRARIES \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-toollibLIBRARIES clean-compile clean-libtool \ + clean-toollibLTLIBRARIES clean-tags clean-generic \ + mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-toollibLIBRARIES distclean-compile \ + distclean-libtool distclean-toollibLTLIBRARIES \ + distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-toollibLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-toollibLTLIBRARIES \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: mostlyclean-toollibLIBRARIES distclean-toollibLIBRARIES \ +clean-toollibLIBRARIES maintainer-clean-toollibLIBRARIES \ +uninstall-toollibLIBRARIES install-toollibLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool mostlyclean-toollibLTLIBRARIES \ +distclean-toollibLTLIBRARIES clean-toollibLTLIBRARIES \ +maintainer-clean-toollibLTLIBRARIES uninstall-toollibLTLIBRARIES \ +install-toollibLTLIBRARIES install-data-recursive \ +uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-info-am \ +install-info install-exec-am install-exec install-data-local \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs-am installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# objects listed later in LIBPTHREAD_OBJLISTS will override those listed earlier +@USE_LIBTOOL_TRUE@extra-libtool-objlist: $(MACHINE_OBJLIST) +@USE_LIBTOOL_TRUE@ cat $(MACHINE_OBJLIST) | $(AWK) '{ libpthread[$$1] = $$2 }; END { for (x in libpthread) printf ("%s\n", libpthread[x]) }' > $@ + +objectlist.awk.in: $(noinst_LTLIBRARIES) + -rm -f objectlist.awk.in + for i in `ls *.lo` ; \ + do \ + echo $$i `pwd`/$$i >> objectlist.awk.in ; \ + done + +doc: + +install-data-local: install-toollibLIBRARIES + -rm -f $(DESTDIR)$(toollibdir)/libthread_db.so.1 + ln -s $(DESTDIR)$(toollibdir)/libthread_db.so $(DESTDIR)$(toollibdir)/libthread_db.so.1 || cp $(DESTDIR)$(toollibdir)/libthread_db.so $(DESTDIR)$(toollibdir)/libthread_db.so.1 + +pt-initfini.s: $(srcdir)/pt-initfini.c + $(CC) -S $(CFLAGS_pt_initfini) -finhibit-size-directive \ + $(patsubst -f%,-fno-%,$(exceptions)) -o $@ + +# We only have one kind of startup code files. Static binaries and +# shared libraries are build using the PIC version. +crti.S: pt-initfini.s + sed -n -e '1,/@HEADER_ENDS/p' \ + -e '/@_.*_PROLOG_BEGINS/,/@_.*_PROLOG_ENDS/p' \ + -e '/@TRAILER_BEGINS/,$$p' $< > $@ + +defs.h: pt-initfini.s + sed -n -e '/@TESTS_BEGIN/,/@TESTS_END/p' $< | \ + $(AWK) -f defs.awk > $@ + +crti.o: crti.S defs.h + $(CC) -g0 $(ASFLAGS) -o $@ + +mutex.$(oext): $(srcdir)/mutex.c + $(LIB_COMPILE) $(CFLAGS_noweak) -c $< -o $@ + +specific.$(oext): $(srcdir)/specific.c + $(LIB_COMPILE) $(CFLAGS_noweak) -c $< -o $@ + +pthread.$(oext): $(srcdir)/pthread.c + $(LIB_COMPILE) $(CFLAGS_pthread) -c $< -o $@ + +ptfork.$(oext): $(srcdir)/ptfork.c + $(LIB_COMPILE) $(CFLAGS_noweak) -c $< -o $@ + +cancel.$(oext): $(srcdir)/cancel.c + $(LIB_COMPILE) $(CFLAGS_cancel) -c $< -o $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/newlib/libc/sys/linux/linuxthreads/aclocal.m4 b/newlib/libc/sys/linux/linuxthreads/aclocal.m4 new file mode 100644 index 000000000..98bba1a0b --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/aclocal.m4 @@ -0,0 +1,1191 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +dnl This provides configure definitions used by all the newlib +dnl configure.in files. + +dnl Basic newlib configury. This calls basic introductory stuff, +dnl including AM_INIT_AUTOMAKE and AC_CANONICAL_HOST. It also runs +dnl configure.host. The only argument is the relative path to the top +dnl newlib directory. + +AC_DEFUN(NEWLIB_CONFIGURE, +[ +dnl Default to --enable-multilib +AC_ARG_ENABLE(multilib, +[ --enable-multilib build many library versions (default)], +[case "${enableval}" in + yes) multilib=yes ;; + no) multilib=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for multilib option) ;; + esac], [multilib=yes])dnl + +dnl Support --enable-target-optspace +AC_ARG_ENABLE(target-optspace, +[ --enable-target-optspace optimize for space], +[case "${enableval}" in + yes) target_optspace=yes ;; + no) target_optspace=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for target-optspace option) ;; + esac], [target_optspace=])dnl + +dnl Support --enable-malloc-debugging - currently only supported for Cygwin +AC_ARG_ENABLE(malloc-debugging, +[ --enable-malloc-debugging indicate malloc debugging requested], +[case "${enableval}" in + yes) malloc_debugging=yes ;; + no) malloc_debugging=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for malloc-debugging option) ;; + esac], [malloc_debugging=])dnl + +dnl Support --enable-newlib-mb +AC_ARG_ENABLE(newlib-mb, +[ --enable-newlib-mb enable multibyte support], +[case "${enableval}" in + yes) newlib_mb=yes ;; + no) newlib_mb=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-mb option) ;; + esac], [newlib_mb=])dnl + +dnl Support --enable-newlib-multithread +AC_ARG_ENABLE(newlib-multithread, +[ --enable-newlib-multithread enable support for multiple threads], +[case "${enableval}" in + yes) newlib_multithread=yes ;; + no) newlib_multithread=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-multithread option) ;; + esac], [newlib_multithread=yes])dnl + +dnl Support --enable-newlib-elix-level +AC_ARG_ENABLE(newlib-elix-level, +[ --enable-newlib-elix-level supply desired elix library level (1-4)], +[case "${enableval}" in + 0) newlib_elix_level=0 ;; + 1) newlib_elix_level=1 ;; + 2) newlib_elix_level=2 ;; + 3) newlib_elix_level=3 ;; + 4) newlib_elix_level=4 ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-elix-level option) ;; + esac], [newlib_elix_level=0])dnl + +dnl Support --disable-newlib-io-float +AC_ARG_ENABLE(newlib-io-float, +[ --disable-newlib-io-float disable printf/scanf family float support], +[case "${enableval}" in + yes) newlib_io_float=yes ;; + no) newlib_io_float=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-io-float option) ;; + esac], [newlib_io_float=yes])dnl + +dnl Support --disable-newlib-supplied-syscalls +AC_ARG_ENABLE(newlib-supplied-syscalls, +[ --disable-newlib-supplied-syscalls disable newlib from supplying syscalls], +[case "${enableval}" in + yes) newlib_may_supply_syscalls=yes ;; + no) newlib_may_supply_syscalls=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-supplied-syscalls option) ;; + esac], [newlib_may_supply_syscalls=yes])dnl + +AM_CONDITIONAL(MAY_SUPPLY_SYSCALLS, test x[$]{newlib_may_supply_syscalls} = xyes) + +dnl We may get other options which we don't document: +dnl --with-target-subdir, --with-multisrctop, --with-multisubdir + +test -z "[$]{with_target_subdir}" && with_target_subdir=. + +if test "[$]{srcdir}" = "."; then + if test "[$]{with_target_subdir}" != "."; then + newlib_basedir="[$]{srcdir}/[$]{with_multisrctop}../$1" + else + newlib_basedir="[$]{srcdir}/[$]{with_multisrctop}$1" + fi +else + newlib_basedir="[$]{srcdir}/$1" +fi +AC_SUBST(newlib_basedir) + +AC_CANONICAL_SYSTEM + +AM_INIT_AUTOMAKE(newlib, 1.11.0) + +# FIXME: We temporarily define our own version of AC_PROG_CC. This is +# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We +# are probably using a cross compiler, which will not be able to fully +# link an executable. This should really be fixed in autoconf +# itself. + +AC_DEFUN(LIB_AC_PROG_CC, +[AC_BEFORE([$0], [AC_PROG_CPP])dnl +AC_CHECK_PROG(CC, gcc, gcc) +if test -z "$CC"; then + AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc) + test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH]) +fi + +AC_PROG_CC_GNU + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +dnl Check whether -g works, even if CFLAGS is set, in case the package +dnl plays around with CFLAGS (such as to build both debugging and +dnl normal versions of a library), tasteless as that idea is. + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + AC_PROG_CC_G + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi +]) + +LIB_AC_PROG_CC + +AC_CHECK_TOOL(AS, as) +AC_CHECK_TOOL(AR, ar) +AC_CHECK_TOOL(RANLIB, ranlib, :) + +AC_PROG_INSTALL + +AM_MAINTAINER_MODE + +# We need AC_EXEEXT to keep automake happy in cygnus mode. However, +# at least currently, we never actually build a program, so we never +# need to use $(EXEEXT). Moreover, the test for EXEEXT normally +# fails, because we are probably configuring with a cross compiler +# which can't create executables. So we include AC_EXEEXT to keep +# automake happy, but we don't execute it, since we don't care about +# the result. +if false; then + AC_EXEEXT +fi + +. [$]{newlib_basedir}/configure.host + +newlib_cflags="[$]{newlib_cflags} -fno-builtin" + +NEWLIB_CFLAGS=${newlib_cflags} +AC_SUBST(NEWLIB_CFLAGS) + +LDFLAGS=${ldflags} +AC_SUBST(LDFLAGS) + +AM_CONDITIONAL(ELIX_LEVEL_0, test x[$]{newlib_elix_level} = x0) +AM_CONDITIONAL(ELIX_LEVEL_1, test x[$]{newlib_elix_level} = x1) +AM_CONDITIONAL(ELIX_LEVEL_2, test x[$]{newlib_elix_level} = x2) +AM_CONDITIONAL(ELIX_LEVEL_3, test x[$]{newlib_elix_level} = x3) +AM_CONDITIONAL(ELIX_LEVEL_4, test x[$]{newlib_elix_level} = x4) + +AM_CONDITIONAL(USE_LIBTOOL, test x[$]{use_libtool} = xyes) + +# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we +# use oext, which is set in configure.host based on the target platform. +OBJEXT=${oext} + +AC_SUBST(OBJEXT) +AC_SUBST(oext) +AC_SUBST(aext) + +AC_SUBST(libm_machine_dir) +AC_SUBST(machine_dir) +AC_SUBST(sys_dir) +]) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Define a conditional. + +AC_DEFUN(AM_CONDITIONAL, +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN(AM_MAINTAINER_MODE, +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + + +# serial 46 AC_PROG_LIBTOOL +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ +])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ +])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ +])])])])])]) + +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# Save cache, so that ltconfig can load it +AC_CACHE_SAVE + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) + +# Reload cache, that may have been modified by ltconfig +AC_CACHE_LOAD + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], +[libtool_flags="$libtool_flags --enable-dlopen"]) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[libtool_flags="$libtool_flags --enable-win32-dll"]) +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +AC_ARG_WITH(pic, + [ --with-pic try to use only PIC/non-PIC objects [default=use both]], + pic_mode="$withval", pic_mode=default) +test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic" +test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac +]) + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + re_direlt=['/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependant libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'] + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* |pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[012]) + lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System' + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd* ) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method=['file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + case $host_cpu in + hppa*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + ia64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + esac + ;; + +irix5* | irix6*) + case $host_os in + irix5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method=["file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"] + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'] ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'] + else + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'] + fi + ;; + +newsos6) + [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +[sysv5uw[78]* | sysv4*uw2*)] + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + motorola) + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'] + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and INCLTDL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and INCLTDL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + INCLTDL= + fi +]) + +# If this macro is not defined by Autoconf, define it here. +ifdef([AC_PROVIDE_IFELSE], + [], + [define([AC_PROVIDE_IFELSE], + [ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + +# AC_LIBTOOL_CXX - enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], [AC_REQUIRE([_AC_LIBTOOL_CXX])]) + +AC_DEFUN([_AC_LIBTOOL_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_PROG_CXXCPP]) +LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-cxx.sh" +lt_save_CC="$CC" +lt_save_CFLAGS="$CFLAGS" +dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC +dnl is set to the C++ compiler. +AR="$AR" LTCC="$CC" CC="$CXX" CXX="$CXX" CFLAGS="$CXXFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" \ +file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \ +--build="$build" --add-tag=CXX $ac_aux_dir/ltcf-cxx.sh $host \ +|| AC_MSG_ERROR([libtool tag configuration failed]) +CC="$lt_save_CC" +CFLAGS="$lt_save_CFLAGS" + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +# AC_LIBTOOL_GCJ - enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ],[AC_REQUIRE([_AC_LIBTOOL_GCJ])]) + +AC_DEFUN([_AC_LIBTOOL_GCJ], +[AC_REQUIRE([AC_PROG_LIBTOOL]) +AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-gcj.sh" +lt_save_CC="$CC" +lt_save_CFLAGS="$CFLAGS" +dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC +dnl is set to the C++ compiler. +AR="$AR" LTCC="$CC" CC="$GCJ" CFLAGS="$GCJFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" \ +file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \ +--build="$build" --add-tag=GCJ $ac_aux_dir/ltcf-gcj.sh $host \ +|| AC_MSG_ERROR([libtool tag configuration failed]) +CC="$lt_save_CC" +CFLAGS="$lt_save_CFLAGS" + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +dnl old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +dnl This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL])dnl + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + diff --git a/newlib/libc/sys/linux/linuxthreads/attr.c b/newlib/libc/sys/linux/linuxthreads/attr.c new file mode 100644 index 000000000..4b3a8f434 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/attr.c @@ -0,0 +1,308 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Handling of thread attributes */ + +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/resource.h> +#include "pthread.h" +#include "internals.h" +#include <shlib-compat.h> + +int __pthread_attr_init_2_1(pthread_attr_t *attr) +{ + size_t ps = __getpagesize (); + + attr->__detachstate = PTHREAD_CREATE_JOINABLE; + attr->__schedpolicy = SCHED_OTHER; + attr->__schedparam.sched_priority = 0; + attr->__inheritsched = PTHREAD_EXPLICIT_SCHED; + attr->__scope = PTHREAD_SCOPE_SYSTEM; + attr->__guardsize = ps; + attr->__stackaddr = NULL; + attr->__stackaddr_set = 0; + attr->__stacksize = STACK_SIZE - ps; + return 0; +} + +versioned_symbol (libpthread, __pthread_attr_init_2_1, pthread_attr_init, + GLIBC_2_1); + +#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) +int __pthread_attr_init_2_0(pthread_attr_t *attr) +{ + attr->__detachstate = PTHREAD_CREATE_JOINABLE; + attr->__schedpolicy = SCHED_OTHER; + attr->__schedparam.sched_priority = 0; + attr->__inheritsched = PTHREAD_EXPLICIT_SCHED; + attr->__scope = PTHREAD_SCOPE_SYSTEM; + return 0; +} +compat_symbol (libpthread, __pthread_attr_init_2_0, pthread_attr_init, + GLIBC_2_0); +#endif + +int pthread_attr_destroy(pthread_attr_t *attr) +{ + return 0; +} + +int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) +{ + if (detachstate < PTHREAD_CREATE_JOINABLE || + detachstate > PTHREAD_CREATE_DETACHED) + return EINVAL; + attr->__detachstate = detachstate; + return 0; +} + +int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) +{ + *detachstate = attr->__detachstate; + return 0; +} + +int pthread_attr_setschedparam(pthread_attr_t *attr, + const struct sched_param *param) +{ + int max_prio = __sched_get_priority_max(attr->__schedpolicy); + int min_prio = __sched_get_priority_min(attr->__schedpolicy); + + if (param->sched_priority < min_prio || param->sched_priority > max_prio) + return EINVAL; + memcpy (&attr->__schedparam, param, sizeof (struct sched_param)); + return 0; +} + +int pthread_attr_getschedparam(const pthread_attr_t *attr, + struct sched_param *param) +{ + memcpy (param, &attr->__schedparam, sizeof (struct sched_param)); + return 0; +} + +int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) +{ + if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR) + return EINVAL; + attr->__schedpolicy = policy; + return 0; +} + +int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) +{ + *policy = attr->__schedpolicy; + return 0; +} + +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit) +{ + if (inherit != PTHREAD_INHERIT_SCHED && inherit != PTHREAD_EXPLICIT_SCHED) + return EINVAL; + attr->__inheritsched = inherit; + return 0; +} + +int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit) +{ + *inherit = attr->__inheritsched; + return 0; +} + +int pthread_attr_setscope(pthread_attr_t *attr, int scope) +{ + switch (scope) { + case PTHREAD_SCOPE_SYSTEM: + attr->__scope = scope; + return 0; + case PTHREAD_SCOPE_PROCESS: + return ENOTSUP; + default: + return EINVAL; + } +} + +int pthread_attr_getscope(const pthread_attr_t *attr, int *scope) +{ + *scope = attr->__scope; + return 0; +} + +int __pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) +{ + /* The guard size must not be larger than the stack itself */ + if (guardsize >= attr->__stacksize) return EINVAL; + + attr->__guardsize = guardsize; + + return 0; +} +weak_alias (__pthread_attr_setguardsize, pthread_attr_setguardsize) + +int __pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize) +{ + *guardsize = attr->__guardsize; + return 0; +} +weak_alias (__pthread_attr_getguardsize, pthread_attr_getguardsize) + +int __pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) +{ + attr->__stackaddr = stackaddr; + attr->__stackaddr_set = 1; + return 0; +} +weak_alias (__pthread_attr_setstackaddr, pthread_attr_setstackaddr) + +link_warning (pthread_attr_setstackaddr, + "the use of `pthread_attr_setstackaddr' is deprecated, use `pthread_attr_setstack'") + +int __pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) +{ + /* XXX This function has a stupid definition. The standard specifies + no error value but what is if no stack address was set? We simply + return the value we have in the member. */ + *stackaddr = attr->__stackaddr; + return 0; +} +weak_alias (__pthread_attr_getstackaddr, pthread_attr_getstackaddr) + +link_warning (pthread_attr_getstackaddr, + "the use of `pthread_attr_getstackaddr' is deprecated, use `pthread_attr_getstack'") + + +int __pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) +{ +#ifdef FLOATING_STACKS + /* We have to check against the maximum allowed stack size. This is no + problem if the manager is already started and we determined it. If + this hasn't happened, we have to find the limit outself. */ + if (__pthread_max_stacksize == 0) + __pthread_init_max_stacksize (); + + if (stacksize > __pthread_max_stacksize) + return EINVAL; +#else + /* We have a fixed size limit. */ + if (stacksize > STACK_SIZE) + return EINVAL; +#endif + + /* We don't accept value smaller than PTHREAD_STACK_MIN. */ + if (stacksize < PTHREAD_STACK_MIN) + return EINVAL; + + attr->__stacksize = stacksize; + return 0; +} +weak_alias (__pthread_attr_setstacksize, pthread_attr_setstacksize) + +int __pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) +{ + *stacksize = attr->__stacksize; + return 0; +} +weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize) + +int __pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, + size_t stacksize) +{ + int err; + + if ((((uintptr_t) stackaddr) + & (__alignof__ (struct _pthread_descr_struct) - 1)) != 0) + err = EINVAL; + else + err = __pthread_attr_setstacksize (attr, stacksize); + if (err == 0) + { +#ifndef _STACK_GROWS_UP + attr->__stackaddr = (char *) stackaddr + stacksize; +#else + attr->__stackaddr = stackaddr; +#endif + attr->__stackaddr_set = 1; + } + + return err; +} +weak_alias (__pthread_attr_setstack, pthread_attr_setstack) + +int __pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr, + size_t *stacksize) +{ + /* XXX This function has a stupid definition. The standard specifies + no error value but what is if no stack address was set? We simply + return the value we have in the member. */ +#ifndef _STACK_GROWS_UP + *stackaddr = (char *) attr->__stackaddr - attr->__stacksize; +#else + *stackaddr = attr->__stackaddr; +#endif + *stacksize = attr->__stacksize; + return 0; +} +weak_alias (__pthread_attr_getstack, pthread_attr_getstack) + +int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr) +{ + pthread_handle handle = thread_handle (thread); + pthread_descr descr; + + if (handle == NULL) + return ENOENT; + + descr = handle->h_descr; + + attr->__detachstate = (descr->p_detached + ? PTHREAD_CREATE_DETACHED + : PTHREAD_CREATE_JOINABLE); + + attr->__schedpolicy = __sched_getscheduler (descr->p_pid); + if (attr->__schedpolicy == -1) + return errno; + + if (__sched_getparam (descr->p_pid, + (struct sched_param *) &attr->__schedparam) != 0) + return errno; + + attr->__inheritsched = descr->p_inheritsched; + attr->__scope = PTHREAD_SCOPE_SYSTEM; +#ifdef _STACK_GROWS_DOWN + attr->__stacksize = (char *)(descr + 1) - (char *)descr->p_guardaddr + - descr->p_guardsize; +#else + attr->__stacksize = (char *)descr->p_guardaddr - (char *)descr; +#endif + attr->__guardsize = descr->p_guardsize; + attr->__stackaddr_set = descr->p_userstack; +#ifdef NEED_SEPARATE_REGISTER_STACK + if (descr->p_userstack == 0) + attr->__stacksize *= 2; + /* XXX This is awkward. The guard pages are in the middle of the + two stacks. We must count the guard size in the stack size since + otherwise the range of the stack area cannot be computed. */ + attr->__stacksize += attr->__guardsize; +#endif +#ifndef _STACK_GROWS_UP + attr->__stackaddr = (char *)(descr + 1); +#else + attr->__stackaddr = (char *)descr; +#endif + + return 0; +} diff --git a/newlib/libc/sys/linux/linuxthreads/barrier.c b/newlib/libc/sys/linux/linuxthreads/barrier.c new file mode 100644 index 000000000..1293bad85 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/barrier.c @@ -0,0 +1,125 @@ +/* POSIX barrier implementation for LinuxThreads. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kaz Kylheku <kaz@ashi.footprints.net>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include "queue.h" +#include "restart.h" + +int +pthread_barrier_wait(pthread_barrier_t *barrier) +{ + pthread_descr self = thread_self(); + pthread_descr temp_wake_queue, th; + int result = 0; + + __pthread_lock(&barrier->__ba_lock, self); + + /* If the required number of threads have achieved rendezvous... */ + if (barrier->__ba_present >= barrier->__ba_required - 1) + { + /* ... then this last caller shall be the serial thread */ + result = PTHREAD_BARRIER_SERIAL_THREAD; + /* Copy and clear wait queue and reset barrier. */ + temp_wake_queue = barrier->__ba_waiting; + barrier->__ba_waiting = NULL; + barrier->__ba_present = 0; + } + else + { + result = 0; + barrier->__ba_present++; + enqueue(&barrier->__ba_waiting, self); + } + + __pthread_unlock(&barrier->__ba_lock); + + if (result == 0) + { + /* Non-serial threads have to suspend */ + suspend(self); + /* We don't bother dealing with cancellation because the POSIX + spec for barriers doesn't mention that pthread_barrier_wait + is a cancellation point. */ + } + else + { + /* Serial thread wakes up all others. */ + while ((th = dequeue(&temp_wake_queue)) != NULL) + restart(th); + } + + return result; +} + +int +pthread_barrier_init(pthread_barrier_t *barrier, + const pthread_barrierattr_t *attr, + unsigned int count) +{ + if (count == 0) + return EINVAL; + + __pthread_init_lock(&barrier->__ba_lock); + barrier->__ba_required = count; + barrier->__ba_present = 0; + barrier->__ba_waiting = NULL; + return 0; +} + +int +pthread_barrier_destroy(pthread_barrier_t *barrier) +{ + if (barrier->__ba_waiting != NULL) return EBUSY; + return 0; +} + +int +pthread_barrierattr_init(pthread_barrierattr_t *attr) +{ + attr->__pshared = PTHREAD_PROCESS_PRIVATE; + return 0; +} + +int +pthread_barrierattr_destroy(pthread_barrierattr_t *attr) +{ + return 0; +} + +int +__pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, + int *pshared) +{ + *pshared = attr->__pshared; + return 0; +} + +int +pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared) +{ + if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED) + return EINVAL; + + attr->__pshared = pshared; + return 0; +} diff --git a/newlib/libc/sys/linux/linuxthreads/bits/initspin.h b/newlib/libc/sys/linux/linuxthreads/bits/initspin.h new file mode 100644 index 000000000..af19d44e6 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/bits/initspin.h @@ -0,0 +1,28 @@ +/* Generic definitions for spinlock initializers. + Copyright (C) 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Initial value of a spinlock. Most platforms should use zero, + unless they only implement a "test and clear" operation instead of + the usual "test and set". */ +#define __LT_SPINLOCK_INIT 0 + +/* Macros for lock initializers, using the above definition. */ +#define __LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT } +#define __ALT_LOCK_INITIALIZER { 0, __LT_SPINLOCK_INIT } +#define __ATOMIC_INITIALIZER { 0, __LT_SPINLOCK_INIT } diff --git a/newlib/libc/sys/linux/linuxthreads/bits/libc-lock.h b/newlib/libc/sys/linux/linuxthreads/bits/libc-lock.h new file mode 100644 index 000000000..2c1d16277 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/bits/libc-lock.h @@ -0,0 +1,327 @@ +/* libc-internal interface for mutex locks. LinuxThreads version. + Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _BITS_LIBC_LOCK_H +#define _BITS_LIBC_LOCK_H 1 + +#include <pthread.h> + +/* Mutex type. */ +#if defined(_LIBC) || defined(_IO_MTSAFE_IO) +typedef pthread_mutex_t __libc_lock_t; +typedef struct { pthread_mutex_t mutex; } __libc_lock_recursive_t; +# ifdef __USE_UNIX98 +typedef pthread_rwlock_t __libc_rwlock_t; +# else +typedef struct __libc_rwlock_opaque__ __libc_rwlock_t; +# endif +#else +typedef struct __libc_lock_opaque__ __libc_lock_t; +typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; +typedef struct __libc_rwlock_opaque__ __libc_rwlock_t; +#endif + +/* Type for key to thread-specific data. */ +typedef pthread_key_t __libc_key_t; + +/* Define a lock variable NAME with storage class CLASS. The lock must be + initialized with __libc_lock_init before it can be used (or define it + with __libc_lock_define_initialized, below). Use `extern' for CLASS to + declare a lock defined in another module. In public structure + definitions you must use a pointer to the lock structure (i.e., NAME + begins with a `*'), because its storage size will not be known outside + of libc. */ +#define __libc_lock_define(CLASS,NAME) \ + CLASS __libc_lock_t NAME; +#define __libc_rwlock_define(CLASS,NAME) \ + CLASS __libc_rwlock_t NAME; +#define __libc_lock_define_recursive(CLASS,NAME) \ + CLASS __libc_lock_recursive_t NAME; + +/* Define an initialized lock variable NAME with storage class CLASS. + + For the C library we take a deeper look at the initializer. For + this implementation all fields are initialized to zero. Therefore + we don't initialize the variable which allows putting it into the + BSS section. (Except on PA-RISC and other odd architectures, where + initialized locks must be set to one due to the lack of normal + atomic operations.) */ + +#if __LT_SPINLOCK_INIT == 0 +# define __libc_lock_define_initialized(CLASS,NAME) \ + CLASS __libc_lock_t NAME; +#else +# define __libc_lock_define_initialized(CLASS,NAME) \ + CLASS __libc_lock_t NAME = PTHREAD_MUTEX_INITIALIZER; +#endif + +#define __libc_rwlock_define_initialized(CLASS,NAME) \ + CLASS __libc_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER; + +/* Define an initialized recursive lock variable NAME with storage + class CLASS. */ +#define __libc_lock_define_initialized_recursive(CLASS,NAME) \ + CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER; +#define _LIBC_LOCK_RECURSIVE_INITIALIZER \ + {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP} + +/* Initialize the named lock variable, leaving it in a consistent, unlocked + state. */ +#define __libc_lock_init(NAME) \ + (__pthread_mutex_init != NULL ? __pthread_mutex_init (&(NAME), NULL) : 0); +#define __libc_rwlock_init(NAME) \ + (__pthread_rwlock_init != NULL ? __pthread_rwlock_init (&(NAME), NULL) : 0); + +/* Same as last but this time we initialize a recursive mutex. */ +#define __libc_lock_init_recursive(NAME) \ + do { \ + if (__pthread_mutex_init != NULL) \ + { \ + pthread_mutexattr_t __attr; \ + __pthread_mutexattr_init (&__attr); \ + __pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_RECURSIVE_NP); \ + __pthread_mutex_init (&(NAME).mutex, &__attr); \ + __pthread_mutexattr_destroy (&__attr); \ + } \ + } while (0); + +/* Finalize the named lock variable, which must be locked. It cannot be + used again until __libc_lock_init is called again on it. This must be + called on a lock variable before the containing storage is reused. */ +#define __libc_lock_fini(NAME) \ + (__pthread_mutex_destroy != NULL ? __pthread_mutex_destroy (&(NAME)) : 0); +#define __libc_rwlock_fini(NAME) \ + (__pthread_rwlock_destroy != NULL ? __pthread_rwlock_destroy (&(NAME)) : 0); + +/* Finalize recursive named lock. */ +#define __libc_lock_fini_recursive(NAME) __libc_lock_fini ((NAME).mutex) + +/* Lock the named lock variable. */ +#define __libc_lock_lock(NAME) \ + (__pthread_mutex_lock != NULL ? __pthread_mutex_lock (&(NAME)) : 0); +#define __libc_rwlock_rdlock(NAME) \ + (__pthread_rwlock_rdlock != NULL ? __pthread_rwlock_rdlock (&(NAME)) : 0); +#define __libc_rwlock_wrlock(NAME) \ + (__pthread_rwlock_wrlock != NULL ? __pthread_rwlock_wrlock (&(NAME)) : 0); + +/* Lock the recursive named lock variable. */ +#define __libc_lock_lock_recursive(NAME) __libc_lock_lock ((NAME).mutex) + +/* Try to lock the named lock variable. */ +#define __libc_lock_trylock(NAME) \ + (__pthread_mutex_trylock != NULL ? __pthread_mutex_trylock (&(NAME)) : 0) +#define __libc_rwlock_tryrdlock(NAME) \ + (__pthread_rwlock_tryrdlock != NULL \ + ? __pthread_rwlock_tryrdlock (&(NAME)) : 0) +#define __libc_rwlock_trywrlock(NAME) \ + (__pthread_rwlock_trywrlock != NULL \ + ? __pthread_rwlock_trywrlock (&(NAME)) : 0) + +/* Try to lock the recursive named lock variable. */ +#define __libc_lock_trylock_recursive(NAME) __libc_lock_trylock ((NAME).mutex) + +/* Unlock the named lock variable. */ +#define __libc_lock_unlock(NAME) \ + (__pthread_mutex_unlock != NULL ? __pthread_mutex_unlock (&(NAME)) : 0); +#define __libc_rwlock_unlock(NAME) \ + (__pthread_rwlock_unlock != NULL ? __pthread_rwlock_unlock (&(NAME)) : 0); + +/* Unlock the recursive named lock variable. */ +#define __libc_lock_unlock_recursive(NAME) __libc_lock_unlock ((NAME).mutex) + + +/* Define once control variable. */ +#if PTHREAD_ONCE_INIT == 0 +/* Special case for static variables where we can avoid the initialization + if it is zero. */ +# define __libc_once_define(CLASS, NAME) \ + CLASS pthread_once_t NAME +#else +# define __libc_once_define(CLASS, NAME) \ + CLASS pthread_once_t NAME = PTHREAD_ONCE_INIT +#endif + +/* Call handler iff the first call. */ +#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \ + do { \ + if (__pthread_once != NULL) \ + __pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION)); \ + else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) { \ + INIT_FUNCTION (); \ + (ONCE_CONTROL) = !PTHREAD_ONCE_INIT; \ + } \ + } while (0) + + +/* Start critical region with cleanup. */ +#define __libc_cleanup_region_start(DOIT, FCT, ARG) \ + { struct _pthread_cleanup_buffer _buffer; \ + int _avail = (DOIT) && _pthread_cleanup_push_defer != NULL; \ + if (_avail) { \ + _pthread_cleanup_push_defer (&_buffer, (FCT), (ARG)); \ + } + +/* End critical region with cleanup. */ +#define __libc_cleanup_region_end(DOIT) \ + if (_avail) { \ + _pthread_cleanup_pop_restore (&_buffer, (DOIT)); \ + } \ + } + +/* Sometimes we have to exit the block in the middle. */ +#define __libc_cleanup_end(DOIT) \ + if (_avail) { \ + _pthread_cleanup_pop_restore (&_buffer, (DOIT)); \ + } + +/* Create thread-specific key. */ +#define __libc_key_create(KEY, DESTRUCTOR) \ + (__pthread_key_create != NULL ? __pthread_key_create (KEY, DESTRUCTOR) : 1) + +/* Get thread-specific data. */ +#define __libc_getspecific(KEY) \ + (__pthread_getspecific != NULL ? __pthread_getspecific (KEY) : NULL) + +/* Set thread-specific data. */ +#define __libc_setspecific(KEY, VALUE) \ + (__pthread_setspecific != NULL ? __pthread_setspecific (KEY, VALUE) : 0) + + +/* Register handlers to execute before and after `fork'. */ +#define __libc_atfork(PREPARE, PARENT, CHILD) \ + (__pthread_atfork != NULL ? __pthread_atfork (PREPARE, PARENT, CHILD) : 0) + +/* Functions that are used by this file and are internal to the GNU C + library. */ + +extern int __pthread_mutex_init (pthread_mutex_t *__mutex, + __const pthread_mutexattr_t *__mutex_attr); + +extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex); + +extern int __pthread_mutex_trylock (pthread_mutex_t *__mutex); + +extern int __pthread_mutex_lock (pthread_mutex_t *__mutex); + +extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex); + +extern int __pthread_mutexattr_init (pthread_mutexattr_t *__attr); + +extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *__attr); + +extern int __pthread_mutexattr_settype (pthread_mutexattr_t *__attr, + int __kind); + +#ifdef __USE_UNIX98 +extern int __pthread_rwlock_init (pthread_rwlock_t *__rwlock, + __const pthread_rwlockattr_t *__attr); + +extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock); + +extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock); + +extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock); + +extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock); + +extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock); + +extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock); +#endif + +extern int __pthread_key_create (pthread_key_t *__key, + void (*__destr_function) (void *)); + +extern int __pthread_setspecific (pthread_key_t __key, + __const void *__pointer); + +extern void *__pthread_getspecific (pthread_key_t __key); + +extern int __pthread_once (pthread_once_t *__once_control, + void (*__init_routine) (void)); + +extern int __pthread_atfork (void (*__prepare) (void), + void (*__parent) (void), + void (*__child) (void)); + + + +/* Make the pthread functions weak so that we can elide them from + single-threaded processes. */ +#ifndef __NO_WEAK_PTHREAD_ALIASES +# ifdef weak_extern +# if _LIBC +# include <bp-sym.h> +# else +# define BP_SYM (sym) sym +# endif +weak_extern (BP_SYM (__pthread_mutex_init)) +weak_extern (BP_SYM (__pthread_mutex_destroy)) +weak_extern (BP_SYM (__pthread_mutex_lock)) +weak_extern (BP_SYM (__pthread_mutex_trylock)) +weak_extern (BP_SYM (__pthread_mutex_unlock)) +weak_extern (BP_SYM (__pthread_mutexattr_init)) +weak_extern (BP_SYM (__pthread_mutexattr_destroy)) +weak_extern (BP_SYM (__pthread_mutexattr_settype)) +weak_extern (BP_SYM (__pthread_rwlock_init)) +weak_extern (BP_SYM (__pthread_rwlock_destroy)) +weak_extern (BP_SYM (__pthread_rwlock_rdlock)) +weak_extern (BP_SYM (__pthread_rwlock_tryrdlock)) +weak_extern (BP_SYM (__pthread_rwlock_wrlock)) +weak_extern (BP_SYM (__pthread_rwlock_trywrlock)) +weak_extern (BP_SYM (__pthread_rwlock_unlock)) +weak_extern (BP_SYM (__pthread_key_create)) +weak_extern (BP_SYM (__pthread_setspecific)) +weak_extern (BP_SYM (__pthread_getspecific)) +weak_extern (BP_SYM (__pthread_once)) +weak_extern (__pthread_initialize) +weak_extern (__pthread_atfork) +weak_extern (BP_SYM (_pthread_cleanup_push_defer)) +weak_extern (BP_SYM (_pthread_cleanup_pop_restore)) +# else +# pragma weak __pthread_mutex_init +# pragma weak __pthread_mutex_destroy +# pragma weak __pthread_mutex_lock +# pragma weak __pthread_mutex_trylock +# pragma weak __pthread_mutex_unlock +# pragma weak __pthread_mutexattr_init +# pragma weak __pthread_mutexattr_destroy +# pragma weak __pthread_mutexattr_settype +# pragma weak __pthread_rwlock_destroy +# pragma weak __pthread_rwlock_rdlock +# pragma weak __pthread_rwlock_tryrdlock +# pragma weak __pthread_rwlock_wrlock +# pragma weak __pthread_rwlock_trywrlock +# pragma weak __pthread_rwlock_unlock +# pragma weak __pthread_key_create +# pragma weak __pthread_setspecific +# pragma weak __pthread_getspecific +# pragma weak __pthread_once +# pragma weak __pthread_initialize +# pragma weak __pthread_atfork +# pragma weak _pthread_cleanup_push_defer +# pragma weak _pthread_cleanup_pop_restore +# endif +#endif + +/* We need portable names for some functions. E.g., when they are + used as argument to __libc_cleanup_region_start. */ +#define __libc_mutex_unlock __pthread_mutex_unlock + +#endif /* bits/libc-lock.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/bits/libc-tsd.h b/newlib/libc/sys/linux/linuxthreads/bits/libc-tsd.h new file mode 100644 index 000000000..7a532ea74 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/bits/libc-tsd.h @@ -0,0 +1,44 @@ +/* libc-internal interface for thread-specific data. LinuxThreads version. + Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _BITS_LIBC_TSD_H +#define _BITS_LIBC_TSD_H 1 + + +/* Fast thread-specific data internal to libc. */ +enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0, + _LIBC_TSD_KEY_DL_ERROR, + _LIBC_TSD_KEY_RPC_VARS, + _LIBC_TSD_KEY_N }; + +extern void *(*__libc_internal_tsd_get) (enum __libc_tsd_key_t) __THROW; +extern int (*__libc_internal_tsd_set) (enum __libc_tsd_key_t, + __const void *) __THROW; + +#define __libc_tsd_define(CLASS, KEY) CLASS void *__libc_tsd_##KEY##_data; +#define __libc_tsd_get(KEY) \ + (__libc_internal_tsd_get != NULL \ + ? __libc_internal_tsd_get (_LIBC_TSD_KEY_##KEY) \ + : __libc_tsd_##KEY##_data) +#define __libc_tsd_set(KEY, VALUE) \ + (__libc_internal_tsd_set != NULL \ + ? __libc_internal_tsd_set (_LIBC_TSD_KEY_##KEY, (VALUE)) \ + : ((__libc_tsd_##KEY##_data = (VALUE)), 0)) + +#endif /* bits/libc-tsd.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/bits/local_lim.h b/newlib/libc/sys/linux/linuxthreads/bits/local_lim.h new file mode 100644 index 000000000..0a7c83706 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/bits/local_lim.h @@ -0,0 +1,77 @@ +/* Minimum guaranteed maximum values for system limits. Linux version. + Copyright (C) 1993, 94, 95, 96, 97, 98, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* The kernel header pollutes the namespace with the NR_OPEN symbol + and defines LINK_MAX although filesystems have different maxima. A + similar thing is true for OPEN_MAX: the limit can be changed at + runtime and therefore the macro must not be defined. Remove this + after including the header if necessary. */ +#ifndef NR_OPEN +# define __undef_NR_OPEN +#endif +#ifndef LINK_MAX +# define __undef_LINK_MAX +#endif +#ifndef OPEN_MAX +# define __undef_OPEN_MAX +#endif + +/* The kernel sources contain a file with all the needed information. */ +#include <linux/limits.h> + +/* Have to remove NR_OPEN? */ +#ifdef __undef_NR_OPEN +# undef NR_OPEN +# undef __undef_NR_OPEN +#endif +/* Have to remove LINK_MAX? */ +#ifdef __undef_LINK_MAX +# undef LINK_MAX +# undef __undef_LINK_MAX +#endif +/* Have to remove OPEN_MAX? */ +#ifdef __undef_OPEN_MAX +# undef OPEN_MAX +# undef __undef_OPEN_MAX +#endif + +/* The number of data keys per process. */ +#define _POSIX_THREAD_KEYS_MAX 128 +/* This is the value this implementation supports. */ +#define PTHREAD_KEYS_MAX 1024 + +/* Controlling the iterations of destructors for thread-specific data. */ +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 +/* Number of iterations this implementation does. */ +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +/* The number of threads per process. */ +#define _POSIX_THREAD_THREADS_MAX 64 +/* This is the value this implementation supports. */ +#define PTHREAD_THREADS_MAX 1024 + +/* Maximum amount by which a process can descrease its asynchronous I/O + priority level. */ +#define AIO_PRIO_DELTA_MAX 20 + +/* Minimum size for a thread. We are free to choose a reasonable value. */ +#define PTHREAD_STACK_MIN 16384 + +/* Maximum number of POSIX timers available. */ +#define TIMER_MAX 256 diff --git a/newlib/libc/sys/linux/linuxthreads/bits/posix_opt.h b/newlib/libc/sys/linux/linuxthreads/bits/posix_opt.h new file mode 100644 index 000000000..54640bb56 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/bits/posix_opt.h @@ -0,0 +1,141 @@ +/* Define POSIX options for Linux. + Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _POSIX_OPT_H +#define _POSIX_OPT_H 1 + +/* Job control is supported. */ +#define _POSIX_JOB_CONTROL 1 + +/* Processes have a saved set-user-ID and a saved set-group-ID. */ +#define _POSIX_SAVED_IDS 1 + +/* Priority scheduling is supported. */ +#define _POSIX_PRIORITY_SCHEDULING 1 + +/* Synchronizing file data is supported. */ +#define _POSIX_SYNCHRONIZED_IO 1 + +/* The fsync function is present. */ +#define _POSIX_FSYNC 1 + +/* Mapping of files to memory is supported. */ +#define _POSIX_MAPPED_FILES 1 + +/* Locking of all memory is supported. */ +#define _POSIX_MEMLOCK 1 + +/* Locking of ranges of memory is supported. */ +#define _POSIX_MEMLOCK_RANGE 1 + +/* Setting of memory protections is supported. */ +#define _POSIX_MEMORY_PROTECTION 1 + +/* Implementation supports `poll' function. */ +#define _POSIX_POLL 1 + +/* Implementation supports `select' and `pselect' functions. */ +#define _POSIX_SELECT 1 + +/* Only root can change owner of file. */ +#define _POSIX_CHOWN_RESTRICTED 1 + +/* `c_cc' member of 'struct termios' structure can be disabled by + using the value _POSIX_VDISABLE. */ +#define _POSIX_VDISABLE '\0' + +/* Filenames are not silently truncated. */ +#define _POSIX_NO_TRUNC 1 + +/* X/Open realtime support is available. */ +#define _XOPEN_REALTIME 1 + +/* X/Open realtime thread support is available. */ +#define _XOPEN_REALTIME_THREADS 1 + +/* XPG4.2 shared memory is supported. */ +#define _XOPEN_SHM 1 + +/* Tell we have POSIX threads. */ +#define _POSIX_THREADS 1 + +/* We have the reentrant functions described in POSIX. */ +#define _POSIX_REENTRANT_FUNCTIONS 1 +#define _POSIX_THREAD_SAFE_FUNCTIONS 1 + +/* We provide priority scheduling for threads. */ +#define _POSIX_THREAD_PRIORITY_SCHEDULING 1 + +/* We support user-defined stack sizes. */ +#define _POSIX_THREAD_ATTR_STACKSIZE 1 + +/* We support user-defined stacks. */ +#define _POSIX_THREAD_ATTR_STACKADDR 1 + +/* We support POSIX.1b semaphores, but only the non-shared form for now. */ +#define _POSIX_SEMAPHORES 1 + +/* Real-time signals are supported. */ +#define _POSIX_REALTIME_SIGNALS 1 + +/* We support asynchronous I/O. */ +#define _POSIX_ASYNCHRONOUS_IO 1 +#define _POSIX_ASYNC_IO 1 +/* Alternative name for Unix98. */ +#define _LFS_ASYNCHRONOUS_IO 1 + +/* The LFS support in asynchronous I/O is also available. */ +#define _LFS64_ASYNCHRONOUS_IO 1 + +/* The rest of the LFS is also available. */ +#define _LFS_LARGEFILE 1 +#define _LFS64_LARGEFILE 1 +#define _LFS64_STDIO 1 + +/* POSIX shared memory objects are implemented. */ +#define _POSIX_SHARED_MEMORY_OBJECTS 1 + +/* GNU libc provides regular expression handling. */ +#define _POSIX_REGEXP 1 + +/* Reader/Writer locks are available. */ +#define _POSIX_READER_WRITER_LOCKS 200912L + +/* We have a POSIX shell. */ +#define _POSIX_SHELL 1 + +/* We support the Timeouts option. */ +#define _POSIX_TIMEOUTS 200912L + +/* We support spinlocks. */ +#define _POSIX_SPIN_LOCKS 200912L + +/* The `spawn' function family is supported. */ +#define _POSIX_SPAWN 200912L + +/* We have POSIX timers. */ +#define _POSIX_TIMERS 1 + +/* The barrier functions are available. */ +#define _POSIX_BARRIERS 200912L + +/* POSIX message queues are not yet supported. */ +#undef _POSIX_MESSAGE_PASSING + +#endif /* posix_opt.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/bits/pthreadtypes.h b/newlib/libc/sys/linux/linuxthreads/bits/pthreadtypes.h new file mode 100644 index 000000000..3ee5c4813 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/bits/pthreadtypes.h @@ -0,0 +1,142 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +#if !defined _BITS_TYPES_H && !defined _PTHREAD_H +# error "Never include <bits/pthreadtypes.h> directly; use <sys/types.h> instead." +#endif + +#ifndef _BITS_PTHREADTYPES_H +#define _BITS_PTHREADTYPES_H 1 + +#define __need_schedparam +#include <bits/sched.h> + +/* Fast locks (not abstract because mutexes and conditions aren't abstract). */ +struct _pthread_fastlock +{ + long int __status; /* "Free" or "taken" or head of waiting list */ + int __spinlock; /* Used by compare_and_swap emulation. Also, + adaptive SMP lock stores spin count here. */ +}; + +#ifndef _PTHREAD_DESCR_DEFINED +/* Thread descriptors */ +typedef struct _pthread_descr_struct *_pthread_descr; +# define _PTHREAD_DESCR_DEFINED +#endif + + +/* Attributes for threads. */ +typedef struct __pthread_attr_s +{ + int __detachstate; + int __schedpolicy; + struct __sched_param __schedparam; + int __inheritsched; + int __scope; + size_t __guardsize; + int __stackaddr_set; + void *__stackaddr; + size_t __stacksize; +} pthread_attr_t; + + +/* Conditions (not abstract because of PTHREAD_COND_INITIALIZER */ +typedef struct +{ + struct _pthread_fastlock __c_lock; /* Protect against concurrent access */ + _pthread_descr __c_waiting; /* Threads waiting on this condition */ +} pthread_cond_t; + + +/* Attribute for conditionally variables. */ +typedef struct +{ + int __dummy; +} pthread_condattr_t; + +/* Keys for thread-specific data */ +typedef unsigned int pthread_key_t; + + +/* Mutexes (not abstract because of PTHREAD_MUTEX_INITIALIZER). */ +/* (The layout is unnatural to maintain binary compatibility + with earlier releases of LinuxThreads.) */ +typedef struct +{ + int __m_reserved; /* Reserved for future use */ + int __m_count; /* Depth of recursive locking */ + _pthread_descr __m_owner; /* Owner thread (if recursive or errcheck) */ + int __m_kind; /* Mutex kind: fast, recursive or errcheck */ + struct _pthread_fastlock __m_lock; /* Underlying fast lock */ +} pthread_mutex_t; + + +/* Attribute for mutex. */ +typedef struct +{ + int __mutexkind; +} pthread_mutexattr_t; + + +/* Once-only execution */ +typedef int pthread_once_t; + + +#ifdef __USE_UNIX98 +/* Read-write locks. */ +typedef struct _pthread_rwlock_t +{ + struct _pthread_fastlock __rw_lock; /* Lock to guarantee mutual exclusion */ + int __rw_readers; /* Number of readers */ + _pthread_descr __rw_writer; /* Identity of writer, or NULL if none */ + _pthread_descr __rw_read_waiting; /* Threads waiting for reading */ + _pthread_descr __rw_write_waiting; /* Threads waiting for writing */ + int __rw_kind; /* Reader/Writer preference selection */ + int __rw_pshared; /* Shared between processes or not */ +} pthread_rwlock_t; + + +/* Attribute for read-write locks. */ +typedef struct +{ + int __lockkind; + int __pshared; +} pthread_rwlockattr_t; +#endif + +#ifdef __USE_XOPEN2K +/* POSIX spinlock data type. */ +typedef volatile int pthread_spinlock_t; + +/* POSIX barrier. */ +typedef struct { + struct _pthread_fastlock __ba_lock; /* Lock to guarantee mutual exclusion */ + int __ba_required; /* Threads needed for completion */ + int __ba_present; /* Threads waiting */ + _pthread_descr __ba_waiting; /* Queue of waiting threads */ +} pthread_barrier_t; + +/* barrier attribute */ +typedef struct { + int __pshared; +} pthread_barrierattr_t; + +#endif + + +/* Thread identifiers */ +typedef unsigned long int pthread_t; + +#endif /* bits/pthreadtypes.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/bits/sigthread.h b/newlib/libc/sys/linux/linuxthreads/bits/sigthread.h new file mode 100644 index 000000000..1c62d8196 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/bits/sigthread.h @@ -0,0 +1,38 @@ +/* Signal handling function for threaded programs. + Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _BITS_SIGTHREAD_H +#define _BITS_SIGTHREAD_H 1 + +#if !defined _SIGNAL_H && !defined _PTHREAD_H +# error "Never include this file directly. Use <pthread.h> instead" +#endif + +/* Functions for handling signals. */ + +/* Modify the signal mask for the calling thread. The arguments have + the same meaning as for sigprocmask(2). */ +extern int pthread_sigmask (int __how, + __const sigset_t *__restrict __newmask, + sigset_t *__restrict __oldmask)__THROW; + +/* Send signal SIGNO to the given thread. */ +extern int pthread_kill (pthread_t __thread1, int __signo) __THROW; + +#endif /* bits/sigthread.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/bp-sym.h b/newlib/libc/sys/linux/linuxthreads/bp-sym.h new file mode 100644 index 000000000..1aeb2364e --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/bp-sym.h @@ -0,0 +1,26 @@ +/* Bounded-pointer symbol modifier. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Greg McGary <greg@mcgary.org> + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define BP_SYM(name) _BP_SYM (name) +#if __BOUNDED_POINTERS__ +# define _BP_SYM(name) __BP_##name +#else +# define _BP_SYM(name) name +#endif diff --git a/newlib/libc/sys/linux/linuxthreads/cancel.c b/newlib/libc/sys/linux/linuxthreads/cancel.c new file mode 100644 index 000000000..0fd6cd094 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/cancel.c @@ -0,0 +1,220 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Thread cancellation */ + +#include <errno.h> +#include <rpc/rpc.h> +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include "restart.h" + +#ifdef _STACK_GROWS_DOWN +# define FRAME_LEFT(frame, other) ((char *) frame >= (char *) other) +#elif _STACK_GROWS_UP +# define FRAME_LEFT(frame, other) ((char *) frame <= (char *) other) +#else +# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" +#endif + + +int pthread_setcancelstate(int state, int * oldstate) +{ + pthread_descr self = thread_self(); + if (state < PTHREAD_CANCEL_ENABLE || state > PTHREAD_CANCEL_DISABLE) + return EINVAL; + if (oldstate != NULL) *oldstate = THREAD_GETMEM(self, p_cancelstate); + THREAD_SETMEM(self, p_cancelstate, state); + if (THREAD_GETMEM(self, p_canceled) && + THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE && + THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS) + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + return 0; +} + +int pthread_setcanceltype(int type, int * oldtype) +{ + pthread_descr self = thread_self(); + if (type < PTHREAD_CANCEL_DEFERRED || type > PTHREAD_CANCEL_ASYNCHRONOUS) + return EINVAL; + if (oldtype != NULL) *oldtype = THREAD_GETMEM(self, p_canceltype); + THREAD_SETMEM(self, p_canceltype, type); + if (THREAD_GETMEM(self, p_canceled) && + THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE && + THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS) + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + return 0; +} + +int pthread_cancel(pthread_t thread) +{ + pthread_handle handle = thread_handle(thread); + int pid; + int dorestart = 0; + pthread_descr th; + pthread_extricate_if *pextricate; + int already_canceled; + + __pthread_lock(&handle->h_lock, NULL); + if (invalid_handle(handle, thread)) { + __pthread_unlock(&handle->h_lock); + return ESRCH; + } + + th = handle->h_descr; + + already_canceled = th->p_canceled; + th->p_canceled = 1; + + if (th->p_cancelstate == PTHREAD_CANCEL_DISABLE || already_canceled) { + __pthread_unlock(&handle->h_lock); + return 0; + } + + pextricate = th->p_extricate; + pid = th->p_pid; + + /* If the thread has registered an extrication interface, then + invoke the interface. If it returns 1, then we succeeded in + dequeuing the thread from whatever waiting object it was enqueued + with. In that case, it is our responsibility to wake it up. + And also to set the p_woken_by_cancel flag so the woken thread + can tell that it was woken by cancellation. */ + + if (pextricate != NULL) { + dorestart = pextricate->pu_extricate_func(pextricate->pu_object, th); + th->p_woken_by_cancel = dorestart; + } + + __pthread_unlock(&handle->h_lock); + + /* If the thread has suspended or is about to, then we unblock it by + issuing a restart, instead of a cancel signal. Otherwise we send + the cancel signal to unblock the thread from a cancellation point, + or to initiate asynchronous cancellation. The restart is needed so + we have proper accounting of restarts; suspend decrements the thread's + resume count, and restart() increments it. This also means that suspend's + handling of the cancel signal is obsolete. */ + + if (dorestart) + restart(th); + else + kill(pid, __pthread_sig_cancel); + + return 0; +} + +void pthread_testcancel(void) +{ + pthread_descr self = thread_self(); + if (THREAD_GETMEM(self, p_canceled) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); +} + +void _pthread_cleanup_push(struct _pthread_cleanup_buffer * buffer, + void (*routine)(void *), void * arg) +{ + pthread_descr self = thread_self(); + buffer->__routine = routine; + buffer->__arg = arg; + buffer->__prev = THREAD_GETMEM(self, p_cleanup); + if (buffer->__prev != NULL && FRAME_LEFT (buffer, buffer->__prev)) + buffer->__prev = NULL; + THREAD_SETMEM(self, p_cleanup, buffer); +} + +void _pthread_cleanup_pop(struct _pthread_cleanup_buffer * buffer, + int execute) +{ + pthread_descr self = thread_self(); + if (execute) buffer->__routine(buffer->__arg); + THREAD_SETMEM(self, p_cleanup, buffer->__prev); +} + +void _pthread_cleanup_push_defer(struct _pthread_cleanup_buffer * buffer, + void (*routine)(void *), void * arg) +{ + pthread_descr self = thread_self(); + buffer->__routine = routine; + buffer->__arg = arg; + buffer->__canceltype = THREAD_GETMEM(self, p_canceltype); + buffer->__prev = THREAD_GETMEM(self, p_cleanup); + if (buffer->__prev != NULL && FRAME_LEFT (buffer, buffer->__prev)) + buffer->__prev = NULL; + THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_DEFERRED); + THREAD_SETMEM(self, p_cleanup, buffer); +} + +void _pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer * buffer, + int execute) +{ + pthread_descr self = thread_self(); + if (execute) buffer->__routine(buffer->__arg); + THREAD_SETMEM(self, p_cleanup, buffer->__prev); + THREAD_SETMEM(self, p_canceltype, buffer->__canceltype); + if (THREAD_GETMEM(self, p_canceled) && + THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE && + THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS) + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); +} + +void __pthread_perform_cleanup(char *currentframe) +{ + pthread_descr self = thread_self(); + struct _pthread_cleanup_buffer *c = THREAD_GETMEM(self, p_cleanup); + struct _pthread_cleanup_buffer *last; + + if (c != NULL) + while (FRAME_LEFT (currentframe, c)) + { + last = c; + c = c->__prev; + + if (c == NULL || FRAME_LEFT (last, c)) + { + c = NULL; + break; + } + } + + while (c != NULL) + { + c->__routine(c->__arg); + + last = c; + c = c->__prev; + + if (FRAME_LEFT (last, c)) + break; + } + +#if 0 + /* And the TSD which needs special help. */ + if (THREAD_GETMEM(self, p_libc_specific[_LIBC_TSD_KEY_RPC_VARS]) != NULL) + __rpc_thread_destroy (); +#endif +} + +#ifndef SHARED +/* We need a hook to force the cancelation wrappers and file locking + to be linked in when static libpthread is used. */ +extern const int __pthread_provide_wrappers; +static const int *const __pthread_require_wrappers = + &__pthread_provide_wrappers; +extern const int __pthread_provide_lockfile; +static const int *const __pthread_require_lockfile = + &__pthread_provide_lockfile; +#endif diff --git a/newlib/libc/sys/linux/linuxthreads/condvar.c b/newlib/libc/sys/linux/linuxthreads/condvar.c new file mode 100644 index 000000000..a06211f58 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/condvar.c @@ -0,0 +1,301 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* and Pavel Krauz (krauz@fsid.cvut.cz). */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Condition variables */ + +#include <errno.h> +#include <sched.h> +#include <stddef.h> +#include <sys/time.h> +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include "queue.h" +#include "restart.h" + +int pthread_cond_init(pthread_cond_t *cond, + const pthread_condattr_t *cond_attr) +{ + __pthread_init_lock(&cond->__c_lock); + cond->__c_waiting = NULL; + return 0; +} + +int pthread_cond_destroy(pthread_cond_t *cond) +{ + if (cond->__c_waiting != NULL) return EBUSY; + return 0; +} + +/* Function called by pthread_cancel to remove the thread from + waiting on a condition variable queue. */ + +static int cond_extricate_func(void *obj, pthread_descr th) +{ + volatile pthread_descr self = thread_self(); + pthread_cond_t *cond = obj; + int did_remove = 0; + + __pthread_lock(&cond->__c_lock, self); + did_remove = remove_from_queue(&cond->__c_waiting, th); + __pthread_unlock(&cond->__c_lock); + + return did_remove; +} + +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + volatile pthread_descr self = thread_self(); + pthread_extricate_if extr; + int already_canceled = 0; + int spurious_wakeup_count; + + /* Check whether the mutex is locked and owned by this thread. */ + if (mutex->__m_kind != PTHREAD_MUTEX_TIMED_NP + && mutex->__m_kind != PTHREAD_MUTEX_ADAPTIVE_NP + && mutex->__m_owner != self) + return EINVAL; + + /* Set up extrication interface */ + extr.pu_object = cond; + extr.pu_extricate_func = cond_extricate_func; + + /* Register extrication interface */ + THREAD_SETMEM(self, p_condvar_avail, 0); + __pthread_set_own_extricate_if(self, &extr); + + /* Atomically enqueue thread for waiting, but only if it is not + canceled. If the thread is canceled, then it will fall through the + suspend call below, and then call pthread_exit without + having to worry about whether it is still on the condition variable queue. + This depends on pthread_cancel setting p_canceled before calling the + extricate function. */ + + __pthread_lock(&cond->__c_lock, self); + if (!(THREAD_GETMEM(self, p_canceled) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) + enqueue(&cond->__c_waiting, self); + else + already_canceled = 1; + __pthread_unlock(&cond->__c_lock); + + if (already_canceled) { + __pthread_set_own_extricate_if(self, 0); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + + pthread_mutex_unlock(mutex); + + spurious_wakeup_count = 0; + while (1) + { + suspend(self); + if (THREAD_GETMEM(self, p_condvar_avail) == 0 + && (THREAD_GETMEM(self, p_woken_by_cancel) == 0 + || THREAD_GETMEM(self, p_cancelstate) != PTHREAD_CANCEL_ENABLE)) + { + /* Count resumes that don't belong to us. */ + spurious_wakeup_count++; + continue; + } + break; + } + + __pthread_set_own_extricate_if(self, 0); + + /* Check for cancellation again, to provide correct cancellation + point behavior */ + + if (THREAD_GETMEM(self, p_woken_by_cancel) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { + THREAD_SETMEM(self, p_woken_by_cancel, 0); + pthread_mutex_lock(mutex); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + + /* Put back any resumes we caught that don't belong to us. */ + while (spurious_wakeup_count--) + restart(self); + + pthread_mutex_lock(mutex); + return 0; +} + +static int +pthread_cond_timedwait_relative(pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec * abstime) +{ + volatile pthread_descr self = thread_self(); + int already_canceled = 0; + pthread_extricate_if extr; + int spurious_wakeup_count; + + /* Check whether the mutex is locked and owned by this thread. */ + if (mutex->__m_kind != PTHREAD_MUTEX_TIMED_NP + && mutex->__m_kind != PTHREAD_MUTEX_ADAPTIVE_NP + && mutex->__m_owner != self) + return EINVAL; + + /* Set up extrication interface */ + extr.pu_object = cond; + extr.pu_extricate_func = cond_extricate_func; + + /* Register extrication interface */ + THREAD_SETMEM(self, p_condvar_avail, 0); + __pthread_set_own_extricate_if(self, &extr); + + /* Enqueue to wait on the condition and check for cancellation. */ + __pthread_lock(&cond->__c_lock, self); + if (!(THREAD_GETMEM(self, p_canceled) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) + enqueue(&cond->__c_waiting, self); + else + already_canceled = 1; + __pthread_unlock(&cond->__c_lock); + + if (already_canceled) { + __pthread_set_own_extricate_if(self, 0); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + + pthread_mutex_unlock(mutex); + + spurious_wakeup_count = 0; + while (1) + { + if (!timedsuspend(self, abstime)) { + int was_on_queue; + + /* __pthread_lock will queue back any spurious restarts that + may happen to it. */ + + __pthread_lock(&cond->__c_lock, self); + was_on_queue = remove_from_queue(&cond->__c_waiting, self); + __pthread_unlock(&cond->__c_lock); + + if (was_on_queue) { + __pthread_set_own_extricate_if(self, 0); + pthread_mutex_lock(mutex); + return ETIMEDOUT; + } + + /* Eat the outstanding restart() from the signaller */ + suspend(self); + } + + if (THREAD_GETMEM(self, p_condvar_avail) == 0 + && (THREAD_GETMEM(self, p_woken_by_cancel) == 0 + || THREAD_GETMEM(self, p_cancelstate) != PTHREAD_CANCEL_ENABLE)) + { + /* Count resumes that don't belong to us. */ + spurious_wakeup_count++; + continue; + } + break; + } + + __pthread_set_own_extricate_if(self, 0); + + /* The remaining logic is the same as in other cancellable waits, + such as pthread_join sem_wait or pthread_cond wait. */ + + if (THREAD_GETMEM(self, p_woken_by_cancel) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { + THREAD_SETMEM(self, p_woken_by_cancel, 0); + pthread_mutex_lock(mutex); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + + /* Put back any resumes we caught that don't belong to us. */ + while (spurious_wakeup_count--) + restart(self); + + pthread_mutex_lock(mutex); + return 0; +} + +int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + const struct timespec * abstime) +{ + /* Indirect call through pointer! */ + return pthread_cond_timedwait_relative(cond, mutex, abstime); +} + +int pthread_cond_signal(pthread_cond_t *cond) +{ + pthread_descr th; + + __pthread_lock(&cond->__c_lock, NULL); + th = dequeue(&cond->__c_waiting); + __pthread_unlock(&cond->__c_lock); + if (th != NULL) { + th->p_condvar_avail = 1; + WRITE_MEMORY_BARRIER(); + restart(th); + } + return 0; +} + +int pthread_cond_broadcast(pthread_cond_t *cond) +{ + pthread_descr tosignal, th; + + __pthread_lock(&cond->__c_lock, NULL); + /* Copy the current state of the waiting queue and empty it */ + tosignal = cond->__c_waiting; + cond->__c_waiting = NULL; + __pthread_unlock(&cond->__c_lock); + /* Now signal each process in the queue */ + while ((th = dequeue(&tosignal)) != NULL) { + th->p_condvar_avail = 1; + WRITE_MEMORY_BARRIER(); + restart(th); + } + return 0; +} + +int pthread_condattr_init(pthread_condattr_t *attr) +{ + return 0; +} + +int pthread_condattr_destroy(pthread_condattr_t *attr) +{ + return 0; +} + +#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 3 + +int pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared) +{ + *pshared = PTHREAD_PROCESS_PRIVATE; + return 0; +} + +int pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared) +{ + if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED) + return EINVAL; + + /* For now it is not possible to shared a conditional variable. */ + if (pshared != PTHREAD_PROCESS_PRIVATE) + return ENOSYS; + + return 0; +} + +#endif /* !_ELIX_LEVEL || _ELIX_LEVEL >= 3 */ + diff --git a/newlib/libc/sys/linux/linuxthreads/config.h b/newlib/libc/sys/linux/linuxthreads/config.h new file mode 100644 index 000000000..99b0528a6 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/config.h @@ -0,0 +1,14 @@ +#define HAVE_WEAK_SYMBOLS 1 +#define HAVE_GNU_LD 1 +#define HAVE_ELF 1 +#define __ASSUME_REALTIME_SIGNALS 1 +#define ASM_GLOBAL_DIRECTIVE .global + +#define TEMP_FAILURE_RETRY(expression) \ + (__extension__ \ + ({ long int __result; \ + do __result = (long int) (expression); \ + while (__result == -1L && errno == EINTR); \ + __result; })) + +#define UINT32_C(c) c ## U diff --git a/newlib/libc/sys/linux/linuxthreads/configure b/newlib/libc/sys/linux/linuxthreads/configure new file mode 100755 index 000000000..47404e5ea --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/configure @@ -0,0 +1,3461 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-multilib build many library versions (default)" +ac_help="$ac_help + --enable-target-optspace optimize for space" +ac_help="$ac_help + --enable-malloc-debugging indicate malloc debugging requested" +ac_help="$ac_help + --enable-newlib-mb enable multibyte support" +ac_help="$ac_help + --enable-newlib-multithread enable support for multiple threads" +ac_help="$ac_help + --enable-newlib-elix-level supply desired elix library level (1-4)" +ac_help="$ac_help + --disable-newlib-io-float disable printf/scanf family float support" +ac_help="$ac_help + --disable-newlib-supplied-syscalls disable newlib from supplying syscalls" +ac_help="$ac_help + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer" +ac_help="$ac_help + --enable-shared[=PKGS] build shared libraries [default=yes]" +ac_help="$ac_help + --enable-static[=PKGS] build static libraries [default=yes]" +ac_help="$ac_help + --enable-fast-install[=PKGS] optimize for fast installation [default=yes]" +ac_help="$ac_help + --with-gnu-ld assume the C compiler uses GNU ld [default=no]" +ac_help="$ac_help + --disable-libtool-lock avoid locking (might break parallel builds)" +ac_help="$ac_help + --with-pic try to use only PIC/non-PIC objects [default=use both]" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +sitefile= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --site-file=FILE use FILE as the site file + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -site-file | --site-file | --site-fil | --site-fi | --site-f) + ac_prev=sitefile ;; + -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*) + sitefile="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=attr.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$sitefile"; then + if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi + fi +else + CONFIG_SITE="$sitefile" +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in ../../../../.. $srcdir/../../../../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in ../../../../.. $srcdir/../../../../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:600: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:653: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:710: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +if test $host != $build; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 +echo "configure:743: checking for Cygwin environment" >&5 +if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 748 "configure" +#include "confdefs.h" + +int main() { + +#ifndef __CYGWIN__ +#define __CYGWIN__ __CYGWIN32__ +#endif +return __CYGWIN__; +; return 0; } +EOF +if { (eval echo configure:759: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_cygwin=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_cygwin=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_cygwin" 1>&6 +CYGWIN= +test "$ac_cv_cygwin" = yes && CYGWIN=yes +echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 +echo "configure:776: checking for mingw32 environment" >&5 +if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 781 "configure" +#include "confdefs.h" + +int main() { +return __MINGW32__; +; return 0; } +EOF +if { (eval echo configure:788: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_mingw32=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_mingw32=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_mingw32" 1>&6 +MINGW32= +test "$ac_cv_mingw32" = yes && MINGW32=yes + +# Check whether --enable-multilib or --disable-multilib was given. +if test "${enable_multilib+set}" = set; then + enableval="$enable_multilib" + case "${enableval}" in + yes) multilib=yes ;; + no) multilib=no ;; + *) { echo "configure: error: bad value ${enableval} for multilib option" 1>&2; exit 1; } ;; + esac +else + multilib=yes +fi + +# Check whether --enable-target-optspace or --disable-target-optspace was given. +if test "${enable_target_optspace+set}" = set; then + enableval="$enable_target_optspace" + case "${enableval}" in + yes) target_optspace=yes ;; + no) target_optspace=no ;; + *) { echo "configure: error: bad value ${enableval} for target-optspace option" 1>&2; exit 1; } ;; + esac +else + target_optspace= +fi + +# Check whether --enable-malloc-debugging or --disable-malloc-debugging was given. +if test "${enable_malloc_debugging+set}" = set; then + enableval="$enable_malloc_debugging" + case "${enableval}" in + yes) malloc_debugging=yes ;; + no) malloc_debugging=no ;; + *) { echo "configure: error: bad value ${enableval} for malloc-debugging option" 1>&2; exit 1; } ;; + esac +else + malloc_debugging= +fi + +# Check whether --enable-newlib-mb or --disable-newlib-mb was given. +if test "${enable_newlib_mb+set}" = set; then + enableval="$enable_newlib_mb" + case "${enableval}" in + yes) newlib_mb=yes ;; + no) newlib_mb=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-mb option" 1>&2; exit 1; } ;; + esac +else + newlib_mb= +fi + +# Check whether --enable-newlib-multithread or --disable-newlib-multithread was given. +if test "${enable_newlib_multithread+set}" = set; then + enableval="$enable_newlib_multithread" + case "${enableval}" in + yes) newlib_multithread=yes ;; + no) newlib_multithread=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-multithread option" 1>&2; exit 1; } ;; + esac +else + newlib_multithread=yes +fi + +# Check whether --enable-newlib-elix-level or --disable-newlib-elix-level was given. +if test "${enable_newlib_elix_level+set}" = set; then + enableval="$enable_newlib_elix_level" + case "${enableval}" in + 0) newlib_elix_level=0 ;; + 1) newlib_elix_level=1 ;; + 2) newlib_elix_level=2 ;; + 3) newlib_elix_level=3 ;; + 4) newlib_elix_level=4 ;; + *) { echo "configure: error: bad value ${enableval} for newlib-elix-level option" 1>&2; exit 1; } ;; + esac +else + newlib_elix_level=0 +fi + +# Check whether --enable-newlib-io-float or --disable-newlib-io-float was given. +if test "${enable_newlib_io_float+set}" = set; then + enableval="$enable_newlib_io_float" + case "${enableval}" in + yes) newlib_io_float=yes ;; + no) newlib_io_float=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-io-float option" 1>&2; exit 1; } ;; + esac +else + newlib_io_float=yes +fi + +# Check whether --enable-newlib-supplied-syscalls or --disable-newlib-supplied-syscalls was given. +if test "${enable_newlib_supplied_syscalls+set}" = set; then + enableval="$enable_newlib_supplied_syscalls" + case "${enableval}" in + yes) newlib_may_supply_syscalls=yes ;; + no) newlib_may_supply_syscalls=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-supplied-syscalls option" 1>&2; exit 1; } ;; + esac +else + newlib_may_supply_syscalls=yes +fi + + + +if test x${newlib_may_supply_syscalls} = xyes; then + MAY_SUPPLY_SYSCALLS_TRUE= + MAY_SUPPLY_SYSCALLS_FALSE='#' +else + MAY_SUPPLY_SYSCALLS_TRUE='#' + MAY_SUPPLY_SYSCALLS_FALSE= +fi + + +test -z "${with_target_subdir}" && with_target_subdir=. + +if test "${srcdir}" = "."; then + if test "${with_target_subdir}" != "."; then + newlib_basedir="${srcdir}/${with_multisrctop}../../../../.." + else + newlib_basedir="${srcdir}/${with_multisrctop}../../../.." + fi +else + newlib_basedir="${srcdir}/../../../.." +fi + + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:956: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:977: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:995: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + + +PACKAGE=newlib + +VERSION=1.11.0 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <<EOF +#define PACKAGE "$PACKAGE" +EOF + +cat >> confdefs.h <<EOF +#define VERSION "$VERSION" +EOF + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 +echo "configure:1038: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:1051: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:1064: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:1077: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:1090: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + + +# FIXME: We temporarily define our own version of AC_PROG_CC. This is +# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We +# are probably using a cross compiler, which will not be able to fully +# link an executable. This should really be fixed in autoconf +# itself. + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1115: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1145: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1194: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1203: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1218: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + + +# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1249: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="${ac_tool_prefix}as" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="as" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1281: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" +fi +fi +AR="$ac_cv_prog_AR" +if test -n "$AR"; then + echo "$ac_t""$AR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1313: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_RANLIB"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1345: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + RANLIB=":" +fi +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1390: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 +echo "configure:1444: checking whether to enable maintainer-specific portions of Makefiles" >&5 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + + + +# We need AC_EXEEXT to keep automake happy in cygnus mode. However, +# at least currently, we never actually build a program, so we never +# need to use $(EXEEXT). Moreover, the test for EXEEXT normally +# fails, because we are probably configuring with a cross compiler +# which can't create executables. So we include AC_EXEEXT to keep +# automake happy, but we don't execute it, since we don't care about +# the result. +if false; then + + +echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +echo "configure:1478: checking for executable suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$CYGWIN" = yes || test "$MINGW32" = yes; then + ac_cv_exeext=.exe +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.$ac_ext + ac_cv_exeext= + if { (eval echo configure:1488: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + else + { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; } + fi + rm -f conftest* + test x"${ac_cv_exeext}" = x && ac_cv_exeext=no +fi +fi + +EXEEXT="" +test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext} +echo "$ac_t""${ac_cv_exeext}" 1>&6 +ac_exeext=$EXEEXT + +fi + +. ${newlib_basedir}/configure.host + +newlib_cflags="${newlib_cflags} -fno-builtin" + +NEWLIB_CFLAGS=${newlib_cflags} + + +LDFLAGS=${ldflags} + + + + +if test x${newlib_elix_level} = x0; then + ELIX_LEVEL_0_TRUE= + ELIX_LEVEL_0_FALSE='#' +else + ELIX_LEVEL_0_TRUE='#' + ELIX_LEVEL_0_FALSE= +fi + + +if test x${newlib_elix_level} = x1; then + ELIX_LEVEL_1_TRUE= + ELIX_LEVEL_1_FALSE='#' +else + ELIX_LEVEL_1_TRUE='#' + ELIX_LEVEL_1_FALSE= +fi + + +if test x${newlib_elix_level} = x2; then + ELIX_LEVEL_2_TRUE= + ELIX_LEVEL_2_FALSE='#' +else + ELIX_LEVEL_2_TRUE='#' + ELIX_LEVEL_2_FALSE= +fi + + +if test x${newlib_elix_level} = x3; then + ELIX_LEVEL_3_TRUE= + ELIX_LEVEL_3_FALSE='#' +else + ELIX_LEVEL_3_TRUE='#' + ELIX_LEVEL_3_FALSE= +fi + + +if test x${newlib_elix_level} = x4; then + ELIX_LEVEL_4_TRUE= + ELIX_LEVEL_4_FALSE='#' +else + ELIX_LEVEL_4_TRUE='#' + ELIX_LEVEL_4_FALSE= +fi + + + +if test x${use_libtool} = xyes; then + USE_LIBTOOL_TRUE= + USE_LIBTOOL_FALSE='#' +else + USE_LIBTOOL_TRUE='#' + USE_LIBTOOL_FALSE= +fi + +# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we +# use oext, which is set in configure.host based on the target platform. +OBJEXT=${oext} + + + + + + + + + + + +if test "${use_libtool}" = "yes"; then + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=yes +fi + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=yes +fi + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1664: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1694: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1745: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1777: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 1788 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:1793: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1819: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1824: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1833: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1852: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 +echo "configure:1895: checking for ld used by GCC" >&5 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 +echo "configure:1925: checking for GNU ld" >&5 +else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 +echo "configure:1928: checking for non-GNU ld" >&5 +fi +if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } +echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 +echo "configure:1963: checking if the linker ($LD) is GNU ld" >&5 +if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi +fi + +echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6 +echo "configure:1980: checking for $LD option to reload object files" >&5 +if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + lt_cv_ld_reload_flag='-r' +fi + +echo "$ac_t""$lt_cv_ld_reload_flag" 1>&6 +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" + +echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 +echo "configure:1992: checking for BSD-compatible nm" >&5 +if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi + +NM="$lt_cv_path_NM" +echo "$ac_t""$NM" 1>&6 + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:2030: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6 +echo "configure:2051: checking how to recognise dependant libraries" >&5 +if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* |pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.012) + lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System' + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd* ) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + case $host_cpu in + hppa*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + esac + ;; + +irix5* | irix6*) + case $host_os in + irix5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$' + fi + ;; + +newsos6) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[78]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; +esac + +fi + +echo "$ac_t""$lt_cv_deplibs_check_method" 1>&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method + +echo $ac_n "checking for object suffix""... $ac_c" 1>&6 +echo "configure:2224: checking for object suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftest* +echo 'int i = 1;' > conftest.$ac_ext +if { (eval echo configure:2230: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + for ac_file in conftest.*; do + case $ac_file in + *.c) ;; + *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;; + esac + done +else + { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; } +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_objext" 1>&6 +OBJEXT=$ac_cv_objext +ac_objext=$ac_cv_objext + +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6 +echo "configure:2254: checking for ${ac_tool_prefix}file" >&5 +if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$ac_t""$MAGIC_CMD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo $ac_n "checking for file""... $ac_c" 1>&6 +echo "configure:2316: checking for file" >&5 +if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$ac_t""$MAGIC_CMD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2387: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_RANLIB"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2419: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + RANLIB=":" +fi +fi + +# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2454: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +STRIP="$ac_cv_prog_STRIP" +if test -n "$STRIP"; then + echo "$ac_t""$STRIP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_STRIP"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2486: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_STRIP="strip" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":" +fi +fi +STRIP="$ac_cv_prog_STRIP" +if test -n "$STRIP"; then + echo "$ac_t""$STRIP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + STRIP=":" +fi +fi + + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + +libtool_flags="$libtool_flags --enable-win32-dll" +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + : +fi + +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi + +test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic" +test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 2553 "configure"' > conftest.$ac_ext + if { (eval echo configure:2554: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo configure:2573: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case "`/usr/bin/file conftest.o`" in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 +echo "configure:2591: checking whether the C compiler needs -belf" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + + cat > conftest.$ac_ext <<EOF +#line 2604 "configure" +#include "confdefs.h" + +int main() { + +; return 0; } +EOF +if { (eval echo configure:2611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_needs_belf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_needs_belf=no +fi +rm -f conftest* + ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +fi + +echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +*-*-cygwin* | *-*-mingw* | *-*-pw32*) + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2641: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +DLLTOOL="$ac_cv_prog_DLLTOOL" +if test -n "$DLLTOOL"; then + echo "$ac_t""$DLLTOOL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_DLLTOOL"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2673: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_DLLTOOL="dlltool" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false" +fi +fi +DLLTOOL="$ac_cv_prog_DLLTOOL" +if test -n "$DLLTOOL"; then + echo "$ac_t""$DLLTOOL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + DLLTOOL="false" +fi +fi + + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2708: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="${ac_tool_prefix}as" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_AS"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2740: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="as" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + AS="false" +fi +fi + + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2775: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +OBJDUMP="$ac_cv_prog_OBJDUMP" +if test -n "$OBJDUMP"; then + echo "$ac_t""$OBJDUMP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_OBJDUMP"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2807: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_OBJDUMP="objdump" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_OBJDUMP" && ac_cv_prog_OBJDUMP="false" +fi +fi +OBJDUMP="$ac_cv_prog_OBJDUMP" +if test -n "$OBJDUMP"; then + echo "$ac_t""$OBJDUMP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + OBJDUMP="false" +fi +fi + + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + echo $ac_n "checking if libtool should supply DllMain function""... $ac_c" 1>&6 +echo "configure:2843: checking if libtool should supply DllMain function" >&5 +if eval "test \"`echo '$''{'lt_cv_need_dllmain'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2848 "configure" +#include "confdefs.h" + +int main() { +extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0); +; return 0; } +EOF +if { (eval echo configure:2856: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_need_dllmain=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_need_dllmain=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_need_dllmain" 1>&6 + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + echo $ac_n "checking how to link DLLs""... $ac_c" 1>&6 +echo "configure:2877: checking how to link DLLs" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_dll_switch'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2882 "configure" +#include "confdefs.h" + +int main() { + +; return 0; } +EOF +if { (eval echo configure:2889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_dll_switch=-mdll +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_dll_switch=-dll +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_cc_dll_switch" 1>&6 + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + +esac + + +# Save cache, so that ltconfig can load it +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \ +|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; } + +# Reload cache, that may have been modified by ltconfig +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log + + + + + + +for ac_prog in mawk gawk nawk awk +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3003: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AWK="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AWK="$ac_cv_prog_AWK" +if test -n "$AWK"; then + echo "$ac_t""$AWK" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$AWK" && break +done + +fi + +if test -n "${machine_dir}"; then + MACHINE_OBJLIST=machine/${machine_dir}/objectlist.awk.in + MACHINE_LIB=machine/${machine_dir}/lib.a +fi + + + +subdirs="machine" + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@MAY_SUPPLY_SYSCALLS_TRUE@%$MAY_SUPPLY_SYSCALLS_TRUE%g +s%@MAY_SUPPLY_SYSCALLS_FALSE@%$MAY_SUPPLY_SYSCALLS_FALSE%g +s%@newlib_basedir@%$newlib_basedir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@AS@%$AS%g +s%@AR@%$AR%g +s%@RANLIB@%$RANLIB%g +s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g +s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g +s%@MAINT@%$MAINT%g +s%@EXEEXT@%$EXEEXT%g +s%@NEWLIB_CFLAGS@%$NEWLIB_CFLAGS%g +s%@ELIX_LEVEL_0_TRUE@%$ELIX_LEVEL_0_TRUE%g +s%@ELIX_LEVEL_0_FALSE@%$ELIX_LEVEL_0_FALSE%g +s%@ELIX_LEVEL_1_TRUE@%$ELIX_LEVEL_1_TRUE%g +s%@ELIX_LEVEL_1_FALSE@%$ELIX_LEVEL_1_FALSE%g +s%@ELIX_LEVEL_2_TRUE@%$ELIX_LEVEL_2_TRUE%g +s%@ELIX_LEVEL_2_FALSE@%$ELIX_LEVEL_2_FALSE%g +s%@ELIX_LEVEL_3_TRUE@%$ELIX_LEVEL_3_TRUE%g +s%@ELIX_LEVEL_3_FALSE@%$ELIX_LEVEL_3_FALSE%g +s%@ELIX_LEVEL_4_TRUE@%$ELIX_LEVEL_4_TRUE%g +s%@ELIX_LEVEL_4_FALSE@%$ELIX_LEVEL_4_FALSE%g +s%@USE_LIBTOOL_TRUE@%$USE_LIBTOOL_TRUE%g +s%@USE_LIBTOOL_FALSE@%$USE_LIBTOOL_FALSE%g +s%@OBJEXT@%$OBJEXT%g +s%@oext@%$oext%g +s%@aext@%$aext%g +s%@libm_machine_dir@%$libm_machine_dir%g +s%@machine_dir@%$machine_dir%g +s%@sys_dir@%$sys_dir%g +s%@LN_S@%$LN_S%g +s%@STRIP@%$STRIP%g +s%@DLLTOOL@%$DLLTOOL%g +s%@OBJDUMP@%$OBJDUMP%g +s%@LIBTOOL@%$LIBTOOL%g +s%@AWK@%$AWK%g +s%@MACHINE_OBJLIST@%$MACHINE_OBJLIST%g +s%@MACHINE_LIB@%$MACHINE_LIB%g +s%@subdirs@%$subdirs%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + +if test "$no_recursion" != yes; then + + # Remove --cache-file and --srcdir arguments so they do not pile up. + ac_sub_configure_args= + ac_prev= + for ac_arg in $ac_configure_args; do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case "$ac_arg" in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; + esac + done + + for ac_config_dir in machine; do + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + if test ! -d $srcdir/$ac_config_dir; then + continue + fi + + echo configuring in $ac_config_dir + + case "$srcdir" in + .) ;; + *) + if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :; + else + { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; } + fi + ;; + esac + + ac_popdir=`pwd` + cd $ac_config_dir + + # A "../" for each directory in /$ac_config_dir. + ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` + + case "$srcdir" in + .) # No --srcdir option. We are building in place. + ac_sub_srcdir=$srcdir ;; + /*) # Absolute path. + ac_sub_srcdir=$srcdir/$ac_config_dir ;; + *) # Relative path. + ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;; + esac + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_sub_srcdir/configure; then + ac_sub_configure=$ac_sub_srcdir/configure + elif test -f $ac_sub_srcdir/configure.in; then + ac_sub_configure=$ac_configure + else + echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2 + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + + # Make the cache file name correct relative to the subdirectory. + case "$cache_file" in + /*) ac_sub_cache_file=$cache_file ;; + *) # Relative path. + ac_sub_cache_file="$ac_dots$cache_file" ;; + esac + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir" + # The eval makes quoting arguments work. + if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir + then : + else + { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; } + fi + fi + + cd $ac_popdir + done +fi + diff --git a/newlib/libc/sys/linux/linuxthreads/configure.in b/newlib/libc/sys/linux/linuxthreads/configure.in new file mode 100644 index 000000000..113743a87 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/configure.in @@ -0,0 +1,31 @@ +dnl This is the newlib/libc/sys/linux/linuxthreads configure.in file. +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.5) +AC_INIT(attr.c) + +dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. +AC_CONFIG_AUX_DIR(../../../../..) + +NEWLIB_CONFIGURE(../../../..) + +dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and +dnl add it into NEWLIB_CONFIGURE, executable tests are made before the first +dnl line of the macro which fail because appropriate LDFLAGS are not set. + +if test "${use_libtool}" = "yes"; then +AC_LIBTOOL_WIN32_DLL +AM_PROG_LIBTOOL +AC_PROG_AWK +fi + +if test -n "${machine_dir}"; then + MACHINE_OBJLIST=machine/${machine_dir}/objectlist.awk.in + MACHINE_LIB=machine/${machine_dir}/lib.a +fi +AC_SUBST(MACHINE_OBJLIST) +AC_SUBST(MACHINE_LIB) + +AC_CONFIG_SUBDIRS(machine) + +AC_OUTPUT(Makefile) diff --git a/newlib/libc/sys/linux/linuxthreads/defs.awk b/newlib/libc/sys/linux/linuxthreads/defs.awk new file mode 100644 index 000000000..7ca5a3364 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/defs.awk @@ -0,0 +1,27 @@ +/^[ ]*\.endp/ { need_endp = 1 } +/^[ ]*\.end/ { need_end = 1 } +/^[ ]*\.align/ { if($2 > max) max = $2; } + +END { + if(need_endp) + { + print "#define END_INIT .endp _init"; + print "#define END_FINI .endp _fini"; + } else if(need_end) + { + print "#define END_INIT .end _init"; + print "#define END_FINI .end _fini"; + } + else + { + print "#define END_INIT"; + print "#define END_FINI"; + } + if(max) + print "#define ALIGN .align", max; + else + print "#define ALIGN"; + + print "#include <libc-symbols.h>"; + print "weak_extern (__gmon_start__)"; +} diff --git a/newlib/libc/sys/linux/linuxthreads/ecmutex.c b/newlib/libc/sys/linux/linuxthreads/ecmutex.c new file mode 100644 index 000000000..ce54ddf33 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/ecmutex.c @@ -0,0 +1,157 @@ +/* Test of the error checking mutex and incidently also barriers. */ + +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + + +static pthread_mutex_t locks[] = +{ + PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, + PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, + PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, + PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, + PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP +}; +#define nlocks ((int) (sizeof (locks) / sizeof (locks[0]))) + +static pthread_barrier_t barrier; +#define SYNC pthread_barrier_wait (&barrier) + +#define NTHREADS nlocks + +#define ROUNDS 20 + + +static void * +worker (void *arg) +{ + /* We are locking the and unlocked the locks and check the errors. + Since we are using the error-checking variant the implementation + should report them. */ + int nr = (long int) arg; + int i; + void *result = NULL; + int retval; + + for (i = 0; i < ROUNDS; ++i) + { + /* Skip the rounds which would make other == own. */ + if (i % nlocks == 0) + continue; + + /* Get the "own" mutex. */ + if (pthread_mutex_trylock (&locks[nr]) != 0) + { + printf ("thread %d failed getting own mutex\n", nr); + result = (void *) 1; + } + + /* Try locking "own" mutex again. */ + retval = pthread_mutex_lock (&locks[nr]); + if (retval != EDEADLK) + { + printf ("thread %d failed getting own mutex\n", nr); + result = (void *) 1; + } + + /* Try to get a different semaphore. */ + SYNC; + retval = pthread_mutex_trylock (&locks[(nr + i) % nlocks]); + if (retval != EBUSY) + { + printf ("thread %d didn't deadlock on getting %d's lock\n", + nr, (nr + i) % nlocks); + result = (void *) 1; + } + + /* Try unlocking other's lock. */ + retval = pthread_mutex_unlock (&locks[(nr + i) % nlocks]); + if (retval != EPERM) + { + printf ("thread %d managed releasing mutex %d\n", + nr, (nr + i) % nlocks); + result = (void *) 1; + } + + /* All lock one mutex now. */ + SYNC; + retval = pthread_mutex_lock (&locks[i % nlocks]); + if (nr == (i % nlocks)) + { + if (retval != EDEADLK) + { + printf ("thread %d didn't deadlock on getting %d's lock\n", + nr, (nr + i) % nlocks); + result = (void *) 1; + } + if (pthread_mutex_unlock (&locks[i % nlocks]) != 0) + { + printf ("thread %d failed releasing own mutex\n", nr); + result = (void *) 1; + } + } + else + { + if (retval != 0) + { + printf ("thread %d failed acquiring mutex %d\n", + nr, i % nlocks); + result = (void *) 1; + } + else if (pthread_mutex_unlock (&locks[i % nlocks]) != 0) + { + printf ("thread %d failed releasing mutex %d\n", + nr, i % nlocks); + result = (void *) 1; + } + } + + /* Unlock the own lock. */ + SYNC; + if (nr != (i % nlocks) && pthread_mutex_unlock (&locks[nr]) != 0) + { + printf ("thread %d failed releasing own mutex\n", nr); + result = (void *) 1; + } + + /* Try unlocking again. */ + retval = pthread_mutex_unlock (&locks[nr]); + if (retval == 0) + { + printf ("thread %d managed releasing own mutex twice\n", nr); + result = (void *) 1; + } + } + + return result; +} + + +#define TEST_FUNCTION do_test () +static int +do_test (void) +{ + pthread_t threads[NTHREADS]; + int i; + void *res; + int result = 0; + + pthread_barrier_init (&barrier, NULL, NTHREADS); + + for (i = 0; i < NTHREADS; ++i) + if (pthread_create (&threads[i], NULL, worker, (void *) (long int) i) != 0) + { + printf ("failed to create thread %d: %m\n", i); + exit (1); + } + + for (i = 0; i < NTHREADS; ++i) + if (pthread_join (threads[i], &res) != 0 || res != NULL) + result = 1; + + return result; +} + +#include "../test-skeleton.c" diff --git a/newlib/libc/sys/linux/linuxthreads/events.c b/newlib/libc/sys/linux/linuxthreads/events.c new file mode 100644 index 000000000..c65bafc76 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/events.c @@ -0,0 +1,37 @@ +/* Event functions used while debugging. + Copyright (C) 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* The functions contained here do nothing, they just return. */ + +#include "internals.h" + +void +__linuxthreads_create_event (void) +{ +} + +void +__linuxthreads_death_event (void) +{ +} + +void +__linuxthreads_reap_event (void) +{ +} diff --git a/newlib/libc/sys/linux/linuxthreads/getcpuclockid.c b/newlib/libc/sys/linux/linuxthreads/getcpuclockid.c new file mode 100644 index 000000000..76d39a5de --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/getcpuclockid.c @@ -0,0 +1,40 @@ +/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <pthread.h> +#include <sys/time.h> +#include <internals.h> + +int +pthread_getcpuclockid (pthread_t thread_id, clockid_t *clock_id) +{ + /* We don't allow any process ID but our own. */ + if (thread_handle (thread_id)->h_descr != thread_self ()) + return EPERM; + +#ifdef CLOCK_THREAD_CPUTIME_ID + /* Store the number. */ + *clock_id = CLOCK_THREAD_CPUTIME_ID; + + return 0; +#else + /* We don't have a timer for that. */ + return ENOENT; +#endif +} diff --git a/newlib/libc/sys/linux/linuxthreads/getreent.c b/newlib/libc/sys/linux/linuxthreads/getreent.c new file mode 100644 index 000000000..e73c4a531 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/getreent.c @@ -0,0 +1,11 @@ +/* get thread-specific reentrant pointer */ + +#include <internals.h> + +struct _reent * +__getreent (void) +{ + pthread_descr self = thread_self(); + return THREAD_GETMEM(self, p_reentp); +} + diff --git a/newlib/libc/sys/linux/linuxthreads/internals.h b/newlib/libc/sys/linux/linuxthreads/internals.h new file mode 100644 index 000000000..6da0deb43 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/internals.h @@ -0,0 +1,576 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +#ifndef _INTERNALS_H +#define _INTERNALS_H 1 + +/* Internal data structures */ + +/* Includes */ + +#include <limits.h> +#include <resolv.h> +#include <setjmp.h> +#include <signal.h> +#include <unistd.h> +#include <stackinfo.h> +#include <sys/types.h> +#include <reent.h> +#include <bits/libc-tsd.h> /* for _LIBC_TSD_KEY_N */ + +extern long int testandset (int *spinlock); +extern int __compare_and_swap (long int *p, long int oldval, long int newval); + +#include "libc-symbols.h" +#include "pt-machine.h" +#include "semaphore.h" +#include "thread_dbP.h" +#include <hp-timing.h> + +#ifndef THREAD_GETMEM +# define THREAD_GETMEM(descr, member) descr->member +#endif +#ifndef THREAD_GETMEM_NC +# define THREAD_GETMEM_NC(descr, member) descr->member +#endif +#ifndef THREAD_SETMEM +# define THREAD_SETMEM(descr, member, value) descr->member = (value) +#endif +#ifndef THREAD_SETMEM_NC +# define THREAD_SETMEM_NC(descr, member, value) descr->member = (value) +#endif + +/* Arguments passed to thread creation routine */ + +struct pthread_start_args { + void * (*start_routine)(void *); /* function to run */ + void * arg; /* its argument */ + sigset_t mask; /* initial signal mask for thread */ + int schedpolicy; /* initial scheduling policy (if any) */ + struct __sched_param schedparam; /* initial scheduling parameters (if any) */ +}; + + +/* We keep thread specific data in a special data structure, a two-level + array. The top-level array contains pointers to dynamically allocated + arrays of a certain number of data pointers. So we can implement a + sparse array. Each dynamic second-level array has + PTHREAD_KEY_2NDLEVEL_SIZE + entries. This value shouldn't be too large. */ +#define PTHREAD_KEY_2NDLEVEL_SIZE 32 + +/* We need to address PTHREAD_KEYS_MAX key with PTHREAD_KEY_2NDLEVEL_SIZE + keys in each subarray. */ +#define PTHREAD_KEY_1STLEVEL_SIZE \ + ((PTHREAD_KEYS_MAX + PTHREAD_KEY_2NDLEVEL_SIZE - 1) \ + / PTHREAD_KEY_2NDLEVEL_SIZE) + +typedef void (*destr_function)(void *); + +struct pthread_key_struct { + int in_use; /* already allocated? */ + destr_function destr; /* destruction routine */ +}; + + +#define PTHREAD_START_ARGS_INITIALIZER(fct) \ + { (void *(*) (void *)) fct, NULL, {{0, }}, 0, { 0 } } + +/* The type of thread descriptors */ + +typedef struct _pthread_descr_struct * pthread_descr; + +/* Callback interface for removing the thread from waiting on an + object if it is cancelled while waiting or about to wait. + This hold a pointer to the object, and a pointer to a function + which ``extricates'' the thread from its enqueued state. + The function takes two arguments: pointer to the wait object, + and a pointer to the thread. It returns 1 if an extrication + actually occured, and hence the thread must also be signalled. + It returns 0 if the thread had already been extricated. */ + +typedef struct _pthread_extricate_struct { + void *pu_object; + int (*pu_extricate_func)(void *, pthread_descr); +} pthread_extricate_if; + +/* Atomic counter made possible by compare_and_swap */ + +struct pthread_atomic { + long p_count; + int p_spinlock; +}; + +/* Context info for read write locks. The pthread_rwlock_info structure + is information about a lock that has been read-locked by the thread + in whose list this structure appears. The pthread_rwlock_context + is embedded in the thread context and contains a pointer to the + head of the list of lock info structures, as well as a count of + read locks that are untracked, because no info structure could be + allocated for them. */ + +struct _pthread_rwlock_t; + +typedef struct _pthread_rwlock_info { + struct _pthread_rwlock_info *pr_next; + struct _pthread_rwlock_t *pr_lock; + int pr_lock_count; +} pthread_readlock_info; + +struct _pthread_descr_struct { + union { + struct { + pthread_descr self; /* Pointer to this structure */ + } data; + void *__padding[16]; + } p_header; + pthread_descr p_nextlive, p_prevlive; + /* Double chaining of active threads */ + pthread_descr p_nextwaiting; /* Next element in the queue holding the thr */ + pthread_descr p_nextlock; /* can be on a queue and waiting on a lock */ + pthread_t p_tid; /* Thread identifier */ + int p_pid; /* PID of Unix process */ + int p_priority; /* Thread priority (== 0 if not realtime) */ + struct _pthread_fastlock * p_lock; /* Spinlock for synchronized accesses */ + int p_signal; /* last signal received */ + sigjmp_buf * p_signal_jmp; /* where to siglongjmp on a signal or NULL */ + sigjmp_buf * p_cancel_jmp; /* where to siglongjmp on a cancel or NULL */ + char p_terminated; /* true if terminated e.g. by pthread_exit */ + char p_detached; /* true if detached */ + char p_exited; /* true if the assoc. process terminated */ + void * p_retval; /* placeholder for return value */ + int p_retcode; /* placeholder for return code */ + pthread_descr p_joining; /* thread joining on that thread or NULL */ + struct _pthread_cleanup_buffer * p_cleanup; /* cleanup functions */ + char p_cancelstate; /* cancellation state */ + char p_canceltype; /* cancellation type (deferred/async) */ + char p_canceled; /* cancellation request pending */ + struct _reent * p_reentp; /* pointer to reent struct */ + struct _reent p_reent; /* reentrant structure for newlib */ + int * p_h_errnop; /* pointer to used h_errno variable */ + int p_h_errno; /* error returned by last netdb function */ + char * p_in_sighandler; /* stack address of sighandler, or NULL */ + char p_sigwaiting; /* true if a sigwait() is in progress */ + struct pthread_start_args p_start_args; /* arguments for thread creation */ + void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE]; /* thread-specific data */ + void * p_libc_specific[_LIBC_TSD_KEY_N]; /* thread-specific data for libc */ + int p_userstack; /* nonzero if the user provided the stack */ + void *p_guardaddr; /* address of guard area or NULL */ + size_t p_guardsize; /* size of guard area */ + int p_nr; /* Index of descriptor in __pthread_handles */ + int p_report_events; /* Nonzero if events must be reported. */ + td_eventbuf_t p_eventbuf; /* Data for event. */ + struct pthread_atomic p_resume_count; /* number of times restart() was + called on thread */ + char p_woken_by_cancel; /* cancellation performed wakeup */ + char p_condvar_avail; /* flag if conditional variable became avail */ + char p_sem_avail; /* flag if semaphore became available */ + pthread_extricate_if *p_extricate; /* See above */ + pthread_readlock_info *p_readlock_list; /* List of readlock info structs */ + pthread_readlock_info *p_readlock_free; /* Free list of structs */ + int p_untracked_readlock_count; /* Readlocks not tracked by list */ + struct __res_state *p_resp; /* Pointer to resolver state */ + struct __res_state p_res; /* per-thread resolver state */ + int p_inheritsched; /* copied from the thread attribute */ +#if HP_TIMING_AVAIL + hp_timing_t p_cpuclock_offset; /* Initial CPU clock for thread. */ +#endif + /* New elements must be added at the end. */ +} __attribute__ ((aligned(32))); /* We need to align the structure so that + doubles are aligned properly. This is 8 + bytes on MIPS and 16 bytes on MIPS64. + 32 bytes might give better cache + utilization. */ + + +/* The type of thread handles. */ + +typedef struct pthread_handle_struct * pthread_handle; + +struct pthread_handle_struct { + struct _pthread_fastlock h_lock; /* Fast lock for sychronized access */ + pthread_descr h_descr; /* Thread descriptor or NULL if invalid */ + char * h_bottom; /* Lowest address in the stack thread */ +}; + +/* The type of messages sent to the thread manager thread */ + +struct pthread_request { + pthread_descr req_thread; /* Thread doing the request */ + enum { /* Request kind */ + REQ_CREATE, REQ_FREE, REQ_PROCESS_EXIT, REQ_MAIN_THREAD_EXIT, + REQ_POST, REQ_DEBUG, REQ_KICK, REQ_FOR_EACH_THREAD + } req_kind; + union { /* Arguments for request */ + struct { /* For REQ_CREATE: */ + const pthread_attr_t * attr; /* thread attributes */ + void * (*fn)(void *); /* start function */ + void * arg; /* argument to start function */ + sigset_t mask; /* signal mask */ + } create; + struct { /* For REQ_FREE: */ + pthread_t thread_id; /* identifier of thread to free */ + } free; + struct { /* For REQ_PROCESS_EXIT: */ + int code; /* exit status */ + } exit; + void * post; /* For REQ_POST: the semaphore */ + struct { /* For REQ_FOR_EACH_THREAD: callback */ + void (*fn)(void *, pthread_descr); + void *arg; + } for_each; + } req_args; +}; + + +/* Signals used for suspend/restart and for cancellation notification. */ + +extern int __pthread_sig_restart; +extern int __pthread_sig_cancel; + +/* Signal used for interfacing with gdb */ + +extern int __pthread_sig_debug; + +/* Global array of thread handles, used for validating a thread id + and retrieving the corresponding thread descriptor. Also used for + mapping the available stack segments. */ + +extern struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX]; + +/* Descriptor of the initial thread */ + +extern struct _pthread_descr_struct __pthread_initial_thread; + +/* Descriptor of the manager thread */ + +extern struct _pthread_descr_struct __pthread_manager_thread; + +/* Descriptor of the main thread */ + +extern pthread_descr __pthread_main_thread; + +/* Limit between the stack of the initial thread (above) and the + stacks of other threads (below). Aligned on a STACK_SIZE boundary. + Initially 0, meaning that the current thread is (by definition) + the initial thread. */ + +extern char *__pthread_initial_thread_bos; + +/* Indicate whether at least one thread has a user-defined stack (if 1), + or all threads have stacks supplied by LinuxThreads (if 0). */ + +extern int __pthread_nonstandard_stacks; + +/* File descriptor for sending requests to the thread manager. + Initially -1, meaning that __pthread_initialize_manager must be called. */ + +extern int __pthread_manager_request; + +/* Other end of the pipe for sending requests to the thread manager. */ + +extern int __pthread_manager_reader; + +/* Limits of the thread manager stack. */ + +extern char *__pthread_manager_thread_bos; +extern char *__pthread_manager_thread_tos; + +#ifdef FLOATING_STACKS +/* Maximum stack size. */ +extern size_t __pthread_max_stacksize; +#endif + +/* Pending request for a process-wide exit */ + +extern int __pthread_exit_requested, __pthread_exit_code; + +/* Set to 1 by gdb if we're debugging */ + +extern volatile int __pthread_threads_debug; + +/* Globally enabled events. */ +extern volatile td_thr_events_t __pthread_threads_events; + +/* Pointer to descriptor of thread with last event. */ +extern volatile pthread_descr __pthread_last_event; + +/* Flag which tells whether we are executing on SMP kernel. */ +extern int __pthread_smp_kernel; + +/* Return the handle corresponding to a thread id */ + +static inline pthread_handle thread_handle(pthread_t id) +{ + return &__pthread_handles[id % PTHREAD_THREADS_MAX]; +} + +/* Validate a thread handle. Must have acquired h->h_spinlock before. */ + +static inline int invalid_handle(pthread_handle h, pthread_t id) +{ + return h->h_descr == NULL || h->h_descr->p_tid != id || h->h_descr->p_terminated; +} + +static inline int nonexisting_handle(pthread_handle h, pthread_t id) +{ + return h->h_descr == NULL || h->h_descr->p_tid != id; +} + +/* Fill in defaults left unspecified by pt-machine.h. */ + +/* We round up a value with page size. */ +#ifndef page_roundup +#define page_roundup(v,p) ((((size_t) (v)) + (p) - 1) & ~((p) - 1)) +#endif + +/* The page size we can get from the system. This should likely not be + changed by the machine file but, you never know. */ +#ifndef PAGE_SIZE +#define PAGE_SIZE (sysconf (_SC_PAGE_SIZE)) +#endif + +/* The max size of the thread stack segments. If the default + THREAD_SELF implementation is used, this must be a power of two and + a multiple of PAGE_SIZE. */ +#ifndef STACK_SIZE +#define STACK_SIZE (2 * 1024 * 1024) +#endif + +/* The initial size of the thread stack. Must be a multiple of PAGE_SIZE. */ +#ifndef INITIAL_STACK_SIZE +#define INITIAL_STACK_SIZE (4 * PAGE_SIZE) +#endif + +/* Size of the thread manager stack. The "- 32" avoids wasting space + with some malloc() implementations. */ +#ifndef THREAD_MANAGER_STACK_SIZE +#define THREAD_MANAGER_STACK_SIZE (2 * PAGE_SIZE - 32) +#endif + +/* The base of the "array" of thread stacks. The array will grow down from + here. Defaults to the calculated bottom of the initial application + stack. */ +#ifndef THREAD_STACK_START_ADDRESS +#define THREAD_STACK_START_ADDRESS __pthread_initial_thread_bos +#endif + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#ifndef CURRENT_STACK_FRAME +#define CURRENT_STACK_FRAME ({ char __csf; &__csf; }) +#endif + +/* Recover thread descriptor for the current thread */ + +extern pthread_descr __pthread_find_self (void) __attribute__ ((const)); + +static inline pthread_descr thread_self (void) __attribute__ ((const)); +static inline pthread_descr thread_self (void) +{ +#ifdef THREAD_SELF + return THREAD_SELF; +#else + char *sp = CURRENT_STACK_FRAME; + if (sp >= __pthread_initial_thread_bos) + return &__pthread_initial_thread; + else if (sp >= __pthread_manager_thread_bos + && sp < __pthread_manager_thread_tos) + return &__pthread_manager_thread; + else if (__pthread_nonstandard_stacks) + return __pthread_find_self(); + else +#ifdef _STACK_GROWS_DOWN + return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1; +#else + return (pthread_descr)((unsigned long)sp &~ (STACK_SIZE-1)); +#endif +#endif +} + +/* If MEMORY_BARRIER isn't defined in pt-machine.h, assume the architecture + doesn't need a memory barrier instruction (e.g. Intel x86). Still we + need the compiler to respect the barrier and emit all outstanding + operations which modify memory. Some architectures distinguish between + full, read and write barriers. */ + +#ifndef MEMORY_BARRIER +#define MEMORY_BARRIER() asm ("" : : : "memory") +#endif +#ifndef READ_MEMORY_BARRIER +#define READ_MEMORY_BARRIER() MEMORY_BARRIER() +#endif +#ifndef WRITE_MEMORY_BARRIER +#define WRITE_MEMORY_BARRIER() MEMORY_BARRIER() +#endif + +/* Max number of times we must spin on a spinlock calling sched_yield(). + After MAX_SPIN_COUNT iterations, we put the calling thread to sleep. */ + +#ifndef MAX_SPIN_COUNT +#define MAX_SPIN_COUNT 50 +#endif + +/* Max number of times the spinlock in the adaptive mutex implementation + spins actively on SMP systems. */ + +#ifndef MAX_ADAPTIVE_SPIN_COUNT +#define MAX_ADAPTIVE_SPIN_COUNT 100 +#endif + +/* Duration of sleep (in nanoseconds) when we can't acquire a spinlock + after MAX_SPIN_COUNT iterations of sched_yield(). + With the 2.0 and 2.1 kernels, this MUST BE > 2ms. + (Otherwise the kernel does busy-waiting for realtime threads, + giving other threads no chance to run.) */ + +#ifndef SPIN_SLEEP_DURATION +#define SPIN_SLEEP_DURATION 2000001 +#endif + +/* Debugging */ + +#ifdef DEBUG +#include <assert.h> +#define ASSERT assert +#define MSG __pthread_message +#else +#define ASSERT(x) +#define MSG(msg,arg...) +#endif + +/* Internal global functions */ + +extern void __pthread_do_exit (void *retval, char *currentframe) + __attribute__ ((__noreturn__)); +extern void __pthread_destroy_specifics (void); +extern void __pthread_perform_cleanup (char *currentframe); +extern void __pthread_init_max_stacksize (void); +extern int __pthread_initialize_manager (void); +extern void __pthread_message (char * fmt, ...); +extern int __pthread_manager (void *reqfd); +extern int __pthread_manager_event (void *reqfd); +extern void __pthread_manager_sighandler (int sig); +extern void __pthread_reset_main_thread (void); +extern void __pthread_once_fork_prepare (void); +extern void __pthread_once_fork_parent (void); +extern void __pthread_once_fork_child (void); +extern void __flockfilelist (void); +extern void __funlockfilelist (void); +extern void __fresetlockfiles (void); +extern void __pthread_manager_adjust_prio (int thread_prio); +extern void __pthread_initialize_minimal (void); + +extern int __pthread_attr_setguardsize (pthread_attr_t *__attr, + size_t __guardsize); +extern int __pthread_attr_getguardsize (const pthread_attr_t *__attr, + size_t *__guardsize); +extern int __pthread_attr_setstackaddr (pthread_attr_t *__attr, + void *__stackaddr); +extern int __pthread_attr_getstackaddr (const pthread_attr_t *__attr, + void **__stackaddr); +extern int __pthread_attr_setstacksize (pthread_attr_t *__attr, + size_t __stacksize); +extern int __pthread_attr_getstacksize (const pthread_attr_t *__attr, + size_t *__stacksize); +extern int __pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr, + size_t __stacksize); +extern int __pthread_attr_getstack (const pthread_attr_t *__attr, void **__stackaddr, + size_t *__stacksize); +extern int __pthread_getconcurrency (void); +extern int __pthread_setconcurrency (int __level); +extern int __pthread_mutex_timedlock (pthread_mutex_t *__mutex, + const struct timespec *__abstime); +extern int __pthread_mutexattr_getpshared (const pthread_mutexattr_t *__attr, + int *__pshared); +extern int __pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr, + int __pshared); +extern int __pthread_mutexattr_gettype (const pthread_mutexattr_t *__attr, + int *__kind); +extern void __pthread_kill_other_threads_np (void); + +extern void __pthread_restart_old(pthread_descr th); +extern void __pthread_suspend_old(pthread_descr self); +extern int __pthread_timedsuspend_old(pthread_descr self, const struct timespec *abs); + +extern void __pthread_restart_new(pthread_descr th); +extern void __pthread_suspend_new(pthread_descr self); +extern int __pthread_timedsuspend_new(pthread_descr self, const struct timespec *abs); + +extern void __pthread_wait_for_restart_signal(pthread_descr self); + +extern int __pthread_yield (void); + +extern int __pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock, + __const struct timespec *__restrict + __abstime); +extern int __pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock, + __const struct timespec *__restrict + __abstime); +extern int __pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr); + +extern int __pthread_barrierattr_getpshared (__const pthread_barrierattr_t * + __restrict __attr, + int *__restrict __pshared); + +extern int __pthread_spin_lock (pthread_spinlock_t *__lock); +extern int __pthread_spin_trylock (pthread_spinlock_t *__lock); +extern int __pthread_spin_unlock (pthread_spinlock_t *__lock); +extern int __pthread_spin_init (pthread_spinlock_t *__lock, int __pshared); +extern int __pthread_spin_destroy (pthread_spinlock_t *__lock); + +extern int __pthread_clock_gettime (hp_timing_t freq, struct timespec *tp); +extern void __pthread_clock_settime (hp_timing_t offset); + + +/* Global pointers to old or new suspend functions */ + +extern void (*__pthread_restart)(pthread_descr); +extern void (*__pthread_suspend)(pthread_descr); +extern int (*__pthread_timedsuspend)(pthread_descr, const struct timespec *); + +/* Prototypes for the function without cancelation support when the + normal version has it. */ +extern int __libc_close (int fd); +extern int __libc_nanosleep (const struct timespec *requested_time, + struct timespec *remaining); +/* Prototypes for some of the new semaphore functions. */ +extern int __new_sem_post (sem_t * sem); +extern int __new_sem_init (sem_t *__sem, int __pshared, unsigned int __value); +extern int __new_sem_wait (sem_t *__sem); +extern int __new_sem_trywait (sem_t *__sem); +extern int __new_sem_getvalue (sem_t *__restrict __sem, int *__restrict __sval); +extern int __new_sem_destroy (sem_t *__sem); + +/* Prototypes for compatibility functions. */ +extern int __pthread_attr_init_2_1 (pthread_attr_t *__attr); +extern int __pthread_attr_init_2_0 (pthread_attr_t *__attr); +extern int __pthread_create_2_1 (pthread_t *__restrict __thread1, + const pthread_attr_t *__attr, + void *(*__start_routine) (void *), + void *__restrict __arg); +extern int __pthread_create_2_0 (pthread_t *__restrict __thread1, + const pthread_attr_t *__attr, + void *(*__start_routine) (void *), + void *__restrict arg); + +/* The functions called the signal events. */ +extern void __linuxthreads_create_event (void); +extern void __linuxthreads_death_event (void); +extern void __linuxthreads_reap_event (void); + +/* This function is called to initialize the pthread library. */ +extern void __pthread_initialize (void); + +#endif /* internals.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/join.c b/newlib/libc/sys/linux/linuxthreads/join.c new file mode 100644 index 000000000..a6ed08c97 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/join.c @@ -0,0 +1,218 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Thread termination and joining */ + +#include <errno.h> +#include <sched.h> +#include <stdlib.h> +#include <unistd.h> +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include "restart.h" + +void pthread_exit(void * retval) +{ + __pthread_do_exit (retval, CURRENT_STACK_FRAME); +} + +void __pthread_do_exit(void *retval, char *currentframe) +{ + pthread_descr self = thread_self(); + pthread_descr joining; + struct pthread_request request; + + /* Reset the cancellation flag to avoid looping if the cleanup handlers + contain cancellation points */ + THREAD_SETMEM(self, p_canceled, 0); + /* Call cleanup functions and destroy the thread-specific data */ + __pthread_perform_cleanup(currentframe); + __pthread_destroy_specifics(); + /* Store return value */ + __pthread_lock(THREAD_GETMEM(self, p_lock), self); + THREAD_SETMEM(self, p_retval, retval); + /* See whether we have to signal the death. */ + if (THREAD_GETMEM(self, p_report_events)) + { + /* See whether TD_DEATH is in any of the mask. */ + int idx = __td_eventword (TD_DEATH); + uint32_t mask = __td_eventmask (TD_DEATH); + + if ((mask & (__pthread_threads_events.event_bits[idx] + | THREAD_GETMEM_NC(self, + p_eventbuf.eventmask.event_bits[idx]))) + != 0) + { + /* Yep, we have to signal the death. */ + THREAD_SETMEM(self, p_eventbuf.eventnum, TD_DEATH); + THREAD_SETMEM(self, p_eventbuf.eventdata, self); + __pthread_last_event = self; + + /* Now call the function to signal the event. */ + __linuxthreads_death_event(); + } + } + /* Say that we've terminated */ + THREAD_SETMEM(self, p_terminated, 1); + /* See if someone is joining on us */ + joining = THREAD_GETMEM(self, p_joining); + __pthread_unlock(THREAD_GETMEM(self, p_lock)); + /* Restart joining thread if any */ + if (joining != NULL) restart(joining); + /* If this is the initial thread, block until all threads have terminated. + If another thread calls exit, we'll be terminated from our signal + handler. */ + if (self == __pthread_main_thread && __pthread_manager_request >= 0) { + request.req_thread = self; + request.req_kind = REQ_MAIN_THREAD_EXIT; + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *)&request, sizeof(request))); + suspend(self); + /* Main thread flushes stdio streams and runs atexit functions. + It also calls a handler within LinuxThreads which sends a process exit + request to the thread manager. */ + exit(0); + } + /* Threads other than the main one terminate without flushing stdio streams + or running atexit functions. */ + _exit(0); +} + +/* Function called by pthread_cancel to remove the thread from + waiting on a condition variable queue. */ + +static int join_extricate_func(void *obj, pthread_descr th) +{ + volatile pthread_descr self = thread_self(); + pthread_handle handle = obj; + pthread_descr jo; + int did_remove = 0; + + __pthread_lock(&handle->h_lock, self); + jo = handle->h_descr; + did_remove = jo->p_joining != NULL; + jo->p_joining = NULL; + __pthread_unlock(&handle->h_lock); + + return did_remove; +} + +int pthread_join(pthread_t thread_id, void ** thread_return) +{ + volatile pthread_descr self = thread_self(); + struct pthread_request request; + pthread_handle handle = thread_handle(thread_id); + pthread_descr th; + pthread_extricate_if extr; + int already_canceled = 0; + + /* Set up extrication interface */ + extr.pu_object = handle; + extr.pu_extricate_func = join_extricate_func; + + __pthread_lock(&handle->h_lock, self); + if (nonexisting_handle(handle, thread_id)) { + __pthread_unlock(&handle->h_lock); + return ESRCH; + } + th = handle->h_descr; + if (th == self) { + __pthread_unlock(&handle->h_lock); + return EDEADLK; + } + /* If detached or already joined, error */ + if (th->p_detached || th->p_joining != NULL) { + __pthread_unlock(&handle->h_lock); + return EINVAL; + } + /* If not terminated yet, suspend ourselves. */ + if (! th->p_terminated) { + /* Register extrication interface */ + __pthread_set_own_extricate_if(self, &extr); + if (!(THREAD_GETMEM(self, p_canceled) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) + th->p_joining = self; + else + already_canceled = 1; + __pthread_unlock(&handle->h_lock); + + if (already_canceled) { + __pthread_set_own_extricate_if(self, 0); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + + suspend(self); + /* Deregister extrication interface */ + __pthread_set_own_extricate_if(self, 0); + + /* This is a cancellation point */ + if (THREAD_GETMEM(self, p_woken_by_cancel) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { + THREAD_SETMEM(self, p_woken_by_cancel, 0); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + __pthread_lock(&handle->h_lock, self); + } + /* Get return value */ + if (thread_return != NULL) *thread_return = th->p_retval; + __pthread_unlock(&handle->h_lock); + /* Send notification to thread manager */ + if (__pthread_manager_request >= 0) { + request.req_thread = self; + request.req_kind = REQ_FREE; + request.req_args.free.thread_id = thread_id; + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + } + return 0; +} + +int pthread_detach(pthread_t thread_id) +{ + int terminated; + struct pthread_request request; + pthread_handle handle = thread_handle(thread_id); + pthread_descr th; + + __pthread_lock(&handle->h_lock, NULL); + if (nonexisting_handle(handle, thread_id)) { + __pthread_unlock(&handle->h_lock); + return ESRCH; + } + th = handle->h_descr; + /* If already detached, error */ + if (th->p_detached) { + __pthread_unlock(&handle->h_lock); + return EINVAL; + } + /* If already joining, don't do anything. */ + if (th->p_joining != NULL) { + __pthread_unlock(&handle->h_lock); + return 0; + } + /* Mark as detached */ + th->p_detached = 1; + terminated = th->p_terminated; + __pthread_unlock(&handle->h_lock); + /* If already terminated, notify thread manager to reclaim resources */ + if (terminated && __pthread_manager_request >= 0) { + request.req_thread = thread_self(); + request.req_kind = REQ_FREE; + request.req_args.free.thread_id = thread_id; + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + } + return 0; +} diff --git a/newlib/libc/sys/linux/linuxthreads/joinrace.c b/newlib/libc/sys/linux/linuxthreads/joinrace.c new file mode 100644 index 000000000..8e1064c98 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/joinrace.c @@ -0,0 +1,48 @@ +/* Test case by Permaine Cheung <pcheung@cygnus.com>. */ + +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +static void * +sub1 (void *arg) +{ + /* Nothing. */ + return NULL; +} + +int +main (void) +{ + int istatus; + int policy; + int cnt; + pthread_t thread1; + struct sched_param spresult1, sp1; + + for (cnt = 0; cnt < 100; ++cnt) + { + printf ("Round %d\n", cnt); + + pthread_create (&thread1, NULL, &sub1, NULL); + pthread_join (thread1, NULL); + + istatus = pthread_getschedparam (thread1, &policy, &spresult1); + if (istatus != ESRCH) + { + printf ("pthread_getschedparam returns: %d\n", istatus); + return 1; + } + + sp1.sched_priority = 0; + istatus = pthread_setschedparam (thread1, SCHED_OTHER, &sp1); + if (istatus != ESRCH) + { + printf ("pthread_setschedparam returns: %d\n", istatus); + return 2; + } + } + + return 0; +} diff --git a/newlib/libc/sys/linux/linuxthreads/kernel-features.h b/newlib/libc/sys/linux/linuxthreads/kernel-features.h new file mode 100644 index 000000000..562a6c765 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/kernel-features.h @@ -0,0 +1,193 @@ +/* Set flags signalling availability of kernel features based on given + kernel version number. + Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This file must not contain any C code. At least it must be protected + to allow using the file also in assembler files. */ + +#ifndef __LINUX_KERNEL_VERSION +/* We assume the worst; all kernels should be supported. */ +# define __LINUX_KERNEL_VERSION 0 +#endif + +/* We assume for __LINUX_KERNEL_VERSION the same encoding used in + linux/version.h. I.e., the major, minor, and subminor all get a + byte with the major number being in the highest byte. This means + we can do numeric comparisons. + + In the following we will define certain symbols depending on + whether the describes kernel feature is available in the kernel + version given by __LINUX_KERNEL_VERSION. We are not always exactly + recording the correct versions in which the features were + introduced. If somebody cares these values can afterwards be + corrected. Most of the numbers here are set corresponding to + 2.2.0. */ + +/* `getcwd' system call. */ +#if __LINUX_KERNEL_VERSION >= 131584 +# define __ASSUME_GETCWD_SYSCALL 1 +#endif + +/* Real-time signal became usable in 2.1.70. */ +#if __LINUX_KERNEL_VERSION >= 131398 +# define __ASSUME_REALTIME_SIGNALS 1 +#endif + +/* When were the `pread'/`pwrite' syscalls introduced? */ +#if __LINUX_KERNEL_VERSION >= 131584 +# define __ASSUME_PREAD_SYSCALL 1 +# define __ASSUME_PWRITE_SYSCALL 1 +#endif + +/* When was `poll' introduced? */ +#if __LINUX_KERNEL_VERSION >= 131584 +# define __ASSUME_POLL_SYSCALL 1 +#endif + +/* The `lchown' syscall was introduced in 2.1.80. */ +#if __LINUX_KERNEL_VERSION >= 131408 +# define __ASSUME_LCHOWN_SYSCALL 1 +#endif + +/* When did the `setresuid' sysall became available? */ +#if __LINUX_KERNEL_VERSION >= 131584 && !defined __sparc__ +# define __ASSUME_SETRESUID_SYSCALL 1 +#endif + +/* The SIOCGIFNAME ioctl is available starting with 2.1.50. */ +#if __LINUX_KERNEL_VERSION >= 131408 +# define __ASSUME_SIOCGIFNAME 1 +#endif + +/* On x86 another `getrlimit' syscall was added in 2.3.25. */ +#if __LINUX_KERNEL_VERSION >= 131865 && defined __i386__ +# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1 +#endif + +/* On x86 the truncate64/ftruncate64 syscalls were introduced in 2.3.31. */ +#if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__ +# define __ASSUME_TRUNCATE64_SYSCALL 1 +#endif + +/* On x86 the mmap2 syscall was introduced in 2.3.31. */ +#if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__ +# define __ASSUME_MMAP2_SYSCALL 1 +#endif + +/* On x86 the stat64/lstat64/fstat64 syscalls were introduced in 2.3.34. */ +#if __LINUX_KERNEL_VERSION >= 131874 && defined __i386__ +# define __ASSUME_STAT64_SYSCALL 1 +#endif + +/* On sparc and ARM the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64 + syscalls were introduced in 2.3.35. */ +#if __LINUX_KERNEL_VERSION >= 131875 && (defined __sparc__ || defined __arm__) +# define __ASSUME_TRUNCATE64_SYSCALL 1 +# define __ASSUME_MMAP2_SYSCALL 1 +# define __ASSUME_STAT64_SYSCALL 1 +#endif + +/* I know for sure that these are in 2.3.35 on powerpc. */ +#if __LINUX_KERNEL_VERSION >= 131875 && defined __powerpc__ +# define __ASSUME_TRUNCATE64_SYSCALL 1 +# define __ASSUME_STAT64_SYSCALL 1 +# define __ASSUME_NEW_GETRLIMIT_SYSCALL 1 +#endif + +/* Linux 2.3.39 introduced 32bit UID/GIDs and IPC64. Some platforms had 32 + bit type all along. */ +#if __LINUX_KERNEL_VERSION >= 131879 || defined __powerpc__ || defined __mips__ +# define __ASSUME_32BITUIDS 1 +# ifndef __powerpc__ +# define __ASSUME_IPC64 1 +# endif +# ifdef __sparc__ +# define __ASSUME_SETRESUID_SYSCALL 1 +# endif +#endif + +/* Linux 2.4.0 on PPC introduced a correct IPC64. */ +#if __LINUX_KERNEL_VERSION >= 132096 && defined __powerpc__ +# define __ASSUME_IPC64 1 +#endif + +/* We can use the LDTs for threading with Linux 2.3.99 and newer. */ +#if __LINUX_KERNEL_VERSION >= 131939 +# define __ASSUME_LDT_WORKS 1 +#endif + +/* The changed st_ino field appeared in 2.4.0-test6. But we cannot + distinguish this version from other 2.4.0 releases. Therefore play + save and assume it available is for 2.4.1 and up. */ +#if __LINUX_KERNEL_VERSION >= 132097 +# define __ASSUME_ST_INO_64_BIT 1 +#endif + +/* To support locking of large files a new fcntl() syscall was introduced + in 2.4.0-test7. We test for 2.4.1 for the earliest version we know + the syscall is available. */ +#if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __sparc__) +# define __ASSUME_FCNTL64 1 +#endif + +/* Arm got fcntl64 in 2.4.4, PowerPC and SH have it also in 2.4.4 (I + don't know when it got introduced). */ +#if __LINUX_KERNEL_VERSION >= 132100 \ + && (defined __arm__ || defined __powerpc__ || defined __sh__) +# define __ASSUME_FCNTL64 1 +#endif + +/* The getdents64 syscall was introduced in 2.4.0-test7. We test for + 2.4.1 for the earliest version we know the syscall is available. */ +#if __LINUX_KERNEL_VERSION >= 132097 +# define __ASSUME_GETDENTS64_SYSCALL 1 +#endif + +/* When did O_DIRECTORY became available? Early in 2.3 but when? + Be safe, use 2.3.99. */ +#if __LINUX_KERNEL_VERSION >= 131939 +# define __ASSUME_O_DIRECTORY 1 +#endif + +/* Starting with one of the 2.4.0 pre-releases the Linux kernel passes + up the page size information. */ +#if __LINUX_KERNEL_VERSION >= 132097 +# define __ASSUME_AT_PAGESIZE 1 +#endif + +/* Starting with 2.4.5 kernels PPC passes the AUXV in the standard way + and the mmap2 syscall made it into the official kernel. */ +#if __LINUX_KERNEL_VERSION >= (132096+5) && defined __powerpc__ +# define __ASSUME_STD_AUXV 1 +# define __ASSUME_MMAP2_SYSCALL 1 +#endif + +/* There are an infinite number of PA-RISC kernel versions numbered + 2.4.0. But they've not really been released as such. We require + and expect the final version here. */ +#ifdef __hppa__ +# define __ASSUME_32BITUIDS 1 +# define __ASSUME_TRUNCATE64_SYSCALL 1 +# define __ASSUME_MMAP2_SYSCALL 1 +# define __ASSUME_STAT64_SYSCALL 1 +# define __ASSUME_IPC64 1 +# define __ASSUME_ST_INO_64_BIT 1 +# define __ASSUME_FCNTL64 1 +# define __ASSUME_GETDENTS64_SYSCALL 1 +#endif diff --git a/newlib/libc/sys/linux/linuxthreads/libc-internal.h b/newlib/libc/sys/linux/linuxthreads/libc-internal.h new file mode 100644 index 000000000..8369ffec2 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/libc-internal.h @@ -0,0 +1,29 @@ +/* This file contains a number of internal prototype declarations that + don't fit anywhere else. */ + +#ifndef _LIBC_INTERNAL +# define _LIBC_INTERNAL 1 + +#include <hp-timing.h> + +/* Initialize the `__libc_enable_secure' flag. */ +extern void __libc_init_secure (void); + +/* This function will be called from _init in init-first.c. */ +extern void __libc_global_ctors (void); + +/* Discover the tick frequency of the machine if something goes wrong, + we return 0, an impossible hertz. */ +extern int __profile_frequency (void); + +/* Hooks for the instrumenting functions. */ +extern void __cyg_profile_func_enter (void *this_fn, void *call_site); +extern void __cyg_profile_func_exit (void *this_fn, void *call_site); + +/* Get frequency of the system processor. */ +extern hp_timing_t __get_clockfreq (void); + +/* Free all allocated resources. */ +extern void __libc_freeres (void); + +#endif /* _LIBC_INTERNAL */ diff --git a/newlib/libc/sys/linux/linuxthreads/libc-symbols.h b/newlib/libc/sys/linux/linuxthreads/libc-symbols.h new file mode 100644 index 000000000..97b672643 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/libc-symbols.h @@ -0,0 +1,352 @@ +/* Support macros for making weak and strong aliases for symbols, + and for using symbol sets and linker warnings with GNU ld. + Copyright (C) 1995,1996,1997,1998,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _LIBC_SYMBOLS_H +#define _LIBC_SYMBOLS_H 1 + +/* This file's macros are included implicitly in the compilation of every + file in the C library by -imacros. + + We include config.h which is generated by configure. + It should define for us the following symbols: + + * HAVE_ASM_SET_DIRECTIVE if we have `.set B, A' instead of `A = B'. + * ASM_GLOBAL_DIRECTIVE with `.globl' or `.global'. + * HAVE_GNU_LD if using GNU ld, with support for weak symbols in a.out, + and for symbol set and warning messages extensions in a.out and ELF. + * HAVE_ELF if using ELF, which supports weak symbols using `.weak'. + * HAVE_ASM_WEAK_DIRECTIVE if we have weak symbols using `.weak'. + * HAVE_ASM_WEAKEXT_DIRECTIVE if we have weak symbols using `.weakext'. + + */ + +/* This is defined for the compilation of all C library code. features.h + tests this to avoid inclusion of stubs.h while compiling the library, + before stubs.h has been generated. Some library code that is shared + with other packages also tests this symbol to see if it is being + compiled as part of the C library. We must define this before including + config.h, because it makes some definitions conditional on whether libc + itself is being compiled, or just some generator program. */ +#define _LIBC 1 + +/* Enable declarations of GNU extensions, since we are compiling them. */ +#define _GNU_SOURCE 1 +/* And we also need the data for the reentrant functions. */ +#define _REENTRANT 1 + +#include <config.h> + +/* The symbols in all the user (non-_) macros are C symbols. + HAVE_GNU_LD without HAVE_ELF implies a.out. */ + +#if defined HAVE_ASM_WEAK_DIRECTIVE || defined HAVE_ASM_WEAKEXT_DIRECTIVE +# define HAVE_WEAK_SYMBOLS +#endif + +#ifndef __SYMBOL_PREFIX +# ifdef NO_UNDERSCORES +# define __SYMBOL_PREFIX +# else +# define __SYMBOL_PREFIX "_" +# endif +#endif + +#ifndef C_SYMBOL_NAME +# ifdef NO_UNDERSCORES +# define C_SYMBOL_NAME(name) name +# else +# define C_SYMBOL_NAME(name) _##name +# endif +#endif + +#ifndef ASM_LINE_SEP +# define ASM_LINE_SEP ; +#endif + +#ifndef C_SYMBOL_DOT_NAME +# define C_SYMBOL_DOT_NAME(name) .##name +#endif + +#ifndef __ASSEMBLER__ +/* GCC understands weak symbols and aliases; use its interface where + possible, instead of embedded assembly language. */ + +/* Define ALIASNAME as a strong alias for NAME. */ +# define strong_alias(name, aliasname) _strong_alias(name, aliasname) +# define _strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))); + +/* This comes between the return type and function name in + a function definition to make that definition weak. */ +# define weak_function __attribute__ ((weak)) +# define weak_const_function __attribute__ ((weak, __const__)) + +# ifdef HAVE_WEAK_SYMBOLS + +/* Define ALIASNAME as a weak alias for NAME. + If weak aliases are not available, this defines a strong alias. */ +# define weak_alias(name, aliasname) _weak_alias (name, aliasname) +# define _weak_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); + +/* Declare SYMBOL as weak undefined symbol (resolved to 0 if not defined). */ +# define weak_extern(symbol) _weak_extern (symbol) +# ifdef HAVE_ASM_WEAKEXT_DIRECTIVE +# define _weak_extern(symbol) asm (".weakext " __SYMBOL_PREFIX #symbol); +# else +# define _weak_extern(symbol) asm (".weak " __SYMBOL_PREFIX #symbol); +# endif + +# else + +# define weak_alias(name, aliasname) strong_alias(name, aliasname) +# define weak_extern(symbol) /* Nothing. */ + +# endif + +#else /* __ASSEMBLER__ */ + +# ifdef HAVE_ASM_SET_DIRECTIVE +# define strong_alias(original, alias) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP \ + .set C_SYMBOL_NAME (alias),C_SYMBOL_NAME (original) +# else +# ifdef HAVE_ASM_GLOBAL_DOT_NAME +# define strong_alias(original, alias) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) ASM_LINE_SEP \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_DOT_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_DOT_NAME (alias) = C_SYMBOL_DOT_NAME (original) +# else +# define strong_alias(original, alias) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) +# endif +# endif + +# ifdef HAVE_WEAK_SYMBOLS +# ifdef HAVE_ASM_WEAKEXT_DIRECTIVE +# define weak_alias(original, alias) \ + .weakext C_SYMBOL_NAME (alias), C_SYMBOL_NAME (original) +# define weak_extern(symbol) \ + .weakext C_SYMBOL_NAME (symbol) + +# else /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */ + +# ifdef HAVE_ASM_GLOBAL_DOT_NAME +# define weak_alias(original, alias) \ + .weak C_SYMBOL_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) ASM_LINE_SEP \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_DOT_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_DOT_NAME (alias) = C_SYMBOL_DOT_NAME (original) +# else +# define weak_alias(original, alias) \ + .weak C_SYMBOL_NAME (alias) ASM_LINE_SEP \ + C_SYMBOL_NAME (alias) = C_SYMBOL_NAME (original) +# endif + +# define weak_extern(symbol) \ + .weak C_SYMBOL_NAME (symbol) + +# endif /* ! HAVE_ASM_WEAKEXT_DIRECTIVE */ + +# else /* ! HAVE_WEAK_SYMBOLS */ + +# define weak_alias(original, alias) strong_alias(original, alias) +# define weak_extern(symbol) /* Nothing */ +# endif /* ! HAVE_WEAK_SYMBOLS */ + +#endif /* __ASSEMBLER__ */ + +/* On some platforms we can make internal function calls (i.e., calls of + functions not exported) a bit faster by using a different calling + convention. */ +#ifndef internal_function +# define internal_function /* empty */ +#endif + +/* Prepare for the case that `__builtin_expect' is not available. */ +#ifndef HAVE_BUILTIN_EXPECT +# define __builtin_expect(expr, val) (expr) +#endif + +/* Determine the return address. */ +#define RETURN_ADDRESS(nr) \ + __builtin_extract_return_addr (__builtin_return_address (nr)) + +/* When a reference to SYMBOL is encountered, the linker will emit a + warning message MSG. */ +#ifdef HAVE_GNU_LD +# ifdef HAVE_ELF + +/* We want the .gnu.warning.SYMBOL section to be unallocated. */ +# ifdef HAVE_ASM_PREVIOUS_DIRECTIVE +# define __make_section_unallocated(section_string) \ + asm (".section " section_string "\n\t.previous"); +# elif defined HAVE_ASM_POPSECTION_DIRECTIVE +# define __make_section_unallocated(section_string) \ + asm (".pushsection " section_string "\n\t.popsection"); +# else +# define __make_section_unallocated(section_string) +# endif + +/* Tacking on "\n\t#" to the section name makes gcc put it's bogus + section attributes on what looks like a comment to the assembler. */ +# ifdef HAVE_SECTION_QUOTES +# define link_warning(symbol, msg) \ + __make_section_unallocated (".gnu.warning." #symbol) \ + static const char __evoke_link_warning_##symbol[] \ + __attribute__ ((section (".gnu.warning." #symbol "\"\n\t#\""))) = msg; +# else +# define link_warning(symbol, msg) \ + __make_section_unallocated (".gnu.warning." #symbol) \ + static const char __evoke_link_warning_##symbol[] \ + __attribute__ ((section (".gnu.warning." #symbol "\n\t#"))) = msg; +# endif +# else /* Not ELF: a.out */ +# ifdef HAVE_XCOFF +/* XCOFF does not support .stabs. + The native aix linker will remove the .stab and .stabstr sections + The gnu linker will have a fatal error if there is a relocation for + symbol in the .stab section. Silently disable this macro. */ +# define link_warning(symbol, msg) +# else +# define link_warning(symbol, msg) \ + asm (".stabs \"" msg "\",30,0,0,0\n\t" \ + ".stabs \"" __SYMBOL_PREFIX #symbol "\",1,0,0,0\n"); +# endif /* XCOFF */ +# endif +#else +/* We will never be heard; they will all die horribly. */ +# define link_warning(symbol, msg) +#endif + +/* A canned warning for sysdeps/stub functions. */ +#define stub_warning(name) \ + link_warning (name, \ + "warning: " #name " is not implemented and will always fail") + +/* + +*/ + +#ifdef HAVE_GNU_LD + +/* Symbol set support macros. */ + +# ifdef HAVE_ELF + +/* Make SYMBOL, which is in the text segment, an element of SET. */ +# define text_set_element(set, symbol) _elf_set_element(set, symbol) +/* Make SYMBOL, which is in the data segment, an element of SET. */ +# define data_set_element(set, symbol) _elf_set_element(set, symbol) +/* Make SYMBOL, which is in the bss segment, an element of SET. */ +# define bss_set_element(set, symbol) _elf_set_element(set, symbol) + +/* These are all done the same way in ELF. + There is a new section created for each set. */ +# ifdef SHARED +/* When building a shared library, make the set section writable, + because it will need to be relocated at run time anyway. */ +# define _elf_set_element(set, symbol) \ + static const void *__elf_set_##set##_element_##symbol##__ \ + __attribute__ ((unused, section (#set))) = &(symbol) +# else +# define _elf_set_element(set, symbol) \ + static const void *const __elf_set_##set##_element_##symbol##__ \ + __attribute__ ((unused, section (#set))) = &(symbol) +# endif + +/* Define SET as a symbol set. This may be required (it is in a.out) to + be able to use the set's contents. */ +# define symbol_set_define(set) symbol_set_declare(set) + +/* Declare SET for use in this module, if defined in another module. */ +# define symbol_set_declare(set) \ + extern void *const __start_##set __attribute__ ((__weak__)); \ + extern void *const __stop_##set __attribute__ ((__weak__)); \ + weak_extern (__start_##set) weak_extern (__stop_##set) + +/* Return a pointer (void *const *) to the first element of SET. */ +# define symbol_set_first_element(set) (&__start_##set) + +/* Return true iff PTR (a void *const *) has been incremented + past the last element in SET. */ +# define symbol_set_end_p(set, ptr) ((ptr) >= &__stop_##set) + +# else /* Not ELF: a.out. */ + +# ifdef HAVE_XCOFF +/* XCOFF does not support .stabs. + The native aix linker will remove the .stab and .stabstr sections + The gnu linker will have a fatal error if there is a relocation for + symbol in the .stab section. Silently disable these macros. */ +# define text_set_element(set, symbol) +# define data_set_element(set, symbol) +# define bss_set_element(set, symbol) +# else +# define text_set_element(set, symbol) \ + asm (".stabs \"" __SYMBOL_PREFIX #set "\",23,0,0," __SYMBOL_PREFIX #symbol) +# define data_set_element(set, symbol) \ + asm (".stabs \"" __SYMBOL_PREFIX #set "\",25,0,0," __SYMBOL_PREFIX #symbol) +# define bss_set_element(set, symbol) ?error Must use initialized data. +# endif /* XCOFF */ +# define symbol_set_define(set) void *const (set)[1]; +# define symbol_set_declare(set) extern void *const (set)[1]; + +# define symbol_set_first_element(set) &(set)[1] +# define symbol_set_end_p(set, ptr) (*(ptr) == 0) + +# endif /* ELF. */ +#else +/* We cannot do anything in generial. */ +# define text_set_element(set, symbol) asm ("") +# define data_set_element(set, symbol) asm ("") +# define bss_set_element(set, symbol) asm ("") +# define symbol_set_define(set) void *const (set)[1]; +# define symbol_set_declare(set) extern void *const (set)[1]; + +# define symbol_set_first_element(set) &(set)[1] +# define symbol_set_end_p(set, ptr) (*(ptr) == 0) +#endif /* Have GNU ld. */ + +#if DO_VERSIONING +# define symbol_version(real, name, version) \ + _symbol_version(real, name, version) +# define default_symbol_version(real, name, version) \ + _default_symbol_version(real, name, version) +# ifdef __ASSEMBLER__ +# define _symbol_version(real, name, version) \ + .symver real, name##@##version +# define _default_symbol_version(real, name, version) \ + .symver real, name##@##@##version +# else +# define _symbol_version(real, name, version) \ + __asm__ (".symver " #real "," #name "@" #version) +# define _default_symbol_version(real, name, version) \ + __asm__ (".symver " #real "," #name "@@" #version) +# endif +#else +# define symbol_version(real, name, version) +# define default_symbol_version(real, name, version) \ + strong_alias(real, name) +#endif + +#endif /* libc-symbols.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/linuxthreads.texi b/newlib/libc/sys/linux/linuxthreads/linuxthreads.texi new file mode 100644 index 000000000..9513a67a6 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/linuxthreads.texi @@ -0,0 +1,1630 @@ +@node POSIX Threads +@c @node POSIX Threads, , Top, Top +@chapter POSIX Threads +@c %MENU% The standard threads library + +@c This chapter needs more work bigtime. -zw + +This chapter describes the pthreads (POSIX threads) library. This +library provides support functions for multithreaded programs: thread +primitives, synchronization objects, and so forth. It also implements +POSIX 1003.1b semaphores (not to be confused with System V semaphores). + +The threads operations (@samp{pthread_*}) do not use @var{errno}. +Instead they return an error code directly. The semaphore operations do +use @var{errno}. + +@menu +* Basic Thread Operations:: Creating, terminating, and waiting for threads. +* Thread Attributes:: Tuning thread scheduling. +* Cancellation:: Stopping a thread before it's done. +* Cleanup Handlers:: Deallocating resources when a thread is + canceled. +* Mutexes:: One way to synchronize threads. +* Condition Variables:: Another way. +* POSIX Semaphores:: And a third way. +* Thread-Specific Data:: Variables with different values in + different threads. +* Threads and Signal Handling:: Why you should avoid mixing the two, and + how to do it if you must. +* Threads and Fork:: Interactions between threads and the + @code{fork} function. +* Streams and Fork:: Interactions between stdio streams and + @code{fork}. +* Miscellaneous Thread Functions:: A grab bag of utility routines. +@end menu + +@node Basic Thread Operations +@section Basic Thread Operations + +These functions are the thread equivalents of @code{fork}, @code{exit}, +and @code{wait}. + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_create (pthread_t * @var{thread}, pthread_attr_t * @var{attr}, void * (*@var{start_routine})(void *), void * @var{arg}) +@code{pthread_create} creates a new thread of control that executes +concurrently with the calling thread. The new thread calls the +function @var{start_routine}, passing it @var{arg} as first argument. The +new thread terminates either explicitly, by calling @code{pthread_exit}, +or implicitly, by returning from the @var{start_routine} function. The +latter case is equivalent to calling @code{pthread_exit} with the result +returned by @var{start_routine} as exit code. + +The @var{attr} argument specifies thread attributes to be applied to the +new thread. @xref{Thread Attributes}, for details. The @var{attr} +argument can also be @code{NULL}, in which case default attributes are +used: the created thread is joinable (not detached) and has an ordinary +(not realtime) scheduling policy. + +On success, the identifier of the newly created thread is stored in the +location pointed by the @var{thread} argument, and a 0 is returned. On +error, a non-zero error code is returned. + +This function may return the following errors: +@table @code +@item EAGAIN +Not enough system resources to create a process for the new thread, +or more than @code{PTHREAD_THREADS_MAX} threads are already active. +@end table +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun void pthread_exit (void *@var{retval}) +@code{pthread_exit} terminates the execution of the calling thread. All +cleanup handlers (@pxref{Cleanup Handlers}) that have been set for the +calling thread with @code{pthread_cleanup_push} are executed in reverse +order (the most recently pushed handler is executed first). Finalization +functions for thread-specific data are then called for all keys that +have non-@code{NULL} values associated with them in the calling thread +(@pxref{Thread-Specific Data}). Finally, execution of the calling +thread is stopped. + +The @var{retval} argument is the return value of the thread. It can be +retrieved from another thread using @code{pthread_join}. + +The @code{pthread_exit} function never returns. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_cancel (pthread_t @var{thread}) + +@code{pthread_cancel} sends a cancellation request to the thread denoted +by the @var{thread} argument. If there is no such thread, +@code{pthread_cancel} fails and returns @code{ESRCH}. Otherwise it +returns 0. @xref{Cancellation}, for details. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_join (pthread_t @var{th}, void **thread_@var{return}) +@code{pthread_join} suspends the execution of the calling thread until +the thread identified by @var{th} terminates, either by calling +@code{pthread_exit} or by being canceled. + +If @var{thread_return} is not @code{NULL}, the return value of @var{th} +is stored in the location pointed to by @var{thread_return}. The return +value of @var{th} is either the argument it gave to @code{pthread_exit}, +or @code{PTHREAD_CANCELED} if @var{th} was canceled. + +The joined thread @code{th} must be in the joinable state: it must not +have been detached using @code{pthread_detach} or the +@code{PTHREAD_CREATE_DETACHED} attribute to @code{pthread_create}. + +When a joinable thread terminates, its memory resources (thread +descriptor and stack) are not deallocated until another thread performs +@code{pthread_join} on it. Therefore, @code{pthread_join} must be called +once for each joinable thread created to avoid memory leaks. + +At most one thread can wait for the termination of a given +thread. Calling @code{pthread_join} on a thread @var{th} on which +another thread is already waiting for termination returns an error. + +@code{pthread_join} is a cancellation point. If a thread is canceled +while suspended in @code{pthread_join}, the thread execution resumes +immediately and the cancellation is executed without waiting for the +@var{th} thread to terminate. If cancellation occurs during +@code{pthread_join}, the @var{th} thread remains not joined. + +On success, the return value of @var{th} is stored in the location +pointed to by @var{thread_return}, and 0 is returned. On error, one of +the following values is returned: +@table @code +@item ESRCH +No thread could be found corresponding to that specified by @var{th}. +@item EINVAL +The @var{th} thread has been detached, or another thread is already +waiting on termination of @var{th}. +@item EDEADLK +The @var{th} argument refers to the calling thread. +@end table +@end deftypefun + +@node Thread Attributes +@section Thread Attributes + +@comment pthread.h +@comment POSIX + +Threads have a number of attributes that may be set at creation time. +This is done by filling a thread attribute object @var{attr} of type +@code{pthread_attr_t}, then passing it as second argument to +@code{pthread_create}. Passing @code{NULL} is equivalent to passing a +thread attribute object with all attributes set to their default values. + +Attribute objects are consulted only when creating a new thread. The +same attribute object can be used for creating several threads. +Modifying an attribute object after a call to @code{pthread_create} does +not change the attributes of the thread previously created. + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_attr_init (pthread_attr_t *@var{attr}) +@code{pthread_attr_init} initializes the thread attribute object +@var{attr} and fills it with default values for the attributes. (The +default values are listed below for each attribute.) + +Each attribute @var{attrname} (see below for a list of all attributes) +can be individually set using the function +@code{pthread_attr_set@var{attrname}} and retrieved using the function +@code{pthread_attr_get@var{attrname}}. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_attr_destroy (pthread_attr_t *@var{attr}) +@code{pthread_attr_destroy} destroys the attribute object pointed to by +@var{attr} releasing any resources associated with it. @var{attr} is +left in an undefined state, and you must not use it again in a call to +any pthreads function until it has been reinitialized. +@end deftypefun + +@findex pthread_attr_setdetachstate +@findex pthread_attr_setguardsize +@findex pthread_attr_setinheritsched +@findex pthread_attr_setschedparam +@findex pthread_attr_setschedpolicy +@findex pthread_attr_setscope +@findex pthread_attr_setstack +@findex pthread_attr_setstackaddr +@findex pthread_attr_setstacksize +@comment pthread.h +@comment POSIX +@deftypefun int pthread_attr_setattr (pthread_attr_t *@var{obj}, int @var{value}) +Set attribute @var{attr} to @var{value} in the attribute object pointed +to by @var{obj}. See below for a list of possible attributes and the +values they can take. + +On success, these functions return 0. If @var{value} is not meaningful +for the @var{attr} being modified, they will return the error code +@code{EINVAL}. Some of the functions have other failure modes; see +below. +@end deftypefun + +@findex pthread_attr_getdetachstate +@findex pthread_attr_getguardsize +@findex pthread_attr_getinheritsched +@findex pthread_attr_getschedparam +@findex pthread_attr_getschedpolicy +@findex pthread_attr_getscope +@findex pthread_attr_getstack +@findex pthread_attr_getstackaddr +@findex pthread_attr_getstacksize +@comment pthread.h +@comment POSIX +@deftypefun int pthread_attr_getattr (const pthread_attr_t *@var{obj}, int *@var{value}) +Store the current setting of @var{attr} in @var{obj} into the variable +pointed to by @var{value}. + +These functions always return 0. +@end deftypefun + +The following thread attributes are supported: +@table @samp +@item detachstate +Choose whether the thread is created in the joinable state (value +@code{PTHREAD_CREATE_JOINABLE}) or in the detached state +(@code{PTHREAD_CREATE_DETACHED}). The default is +@code{PTHREAD_CREATE_JOINABLE}. + +In the joinable state, another thread can synchronize on the thread +termination and recover its termination code using @code{pthread_join}, +but some of the thread resources are kept allocated after the thread +terminates, and reclaimed only when another thread performs +@code{pthread_join} on that thread. + +In the detached state, the thread resources are immediately freed when +it terminates, but @code{pthread_join} cannot be used to synchronize on +the thread termination. + +A thread created in the joinable state can later be put in the detached +thread using @code{pthread_detach}. + +@item schedpolicy +Select the scheduling policy for the thread: one of @code{SCHED_OTHER} +(regular, non-realtime scheduling), @code{SCHED_RR} (realtime, +round-robin) or @code{SCHED_FIFO} (realtime, first-in first-out). +The default is @code{SCHED_OTHER}. +@c Not doc'd in our manual: FIXME. +@c See @code{sched_setpolicy} for more information on scheduling policies. + +The realtime scheduling policies @code{SCHED_RR} and @code{SCHED_FIFO} +are available only to processes with superuser privileges. +@code{pthread_attr_setschedparam} will fail and return @code{ENOTSUP} if +you try to set a realtime policy when you are unprivileged. + +The scheduling policy of a thread can be changed after creation with +@code{pthread_setschedparam}. + +@item schedparam +Change the scheduling parameter (the scheduling priority) +for the thread. The default is 0. + +This attribute is not significant if the scheduling policy is +@code{SCHED_OTHER}; it only matters for the realtime policies +@code{SCHED_RR} and @code{SCHED_FIFO}. + +The scheduling priority of a thread can be changed after creation with +@code{pthread_setschedparam}. + +@item inheritsched +Choose whether the scheduling policy and scheduling parameter for the +newly created thread are determined by the values of the +@var{schedpolicy} and @var{schedparam} attributes (value +@code{PTHREAD_EXPLICIT_SCHED}) or are inherited from the parent thread +(value @code{PTHREAD_INHERIT_SCHED}). The default is +@code{PTHREAD_EXPLICIT_SCHED}. + +@item scope +Choose the scheduling contention scope for the created thread. The +default is @code{PTHREAD_SCOPE_SYSTEM}, meaning that the threads contend +for CPU time with all processes running on the machine. In particular, +thread priorities are interpreted relative to the priorities of all +other processes on the machine. The other possibility, +@code{PTHREAD_SCOPE_PROCESS}, means that scheduling contention occurs +only between the threads of the running process: thread priorities are +interpreted relative to the priorities of the other threads of the +process, regardless of the priorities of other processes. + +@code{PTHREAD_SCOPE_PROCESS} is not supported in LinuxThreads. If you +try to set the scope to this value, @code{pthread_attr_setscope} will +fail and return @code{ENOTSUP}. + +@item stackaddr +Provide an address for an application managed stack. The size of the +stack must be at least @code{PTHREAD_STACK_MIN}. + +@item stacksize +Change the size of the stack created for the thread. The value defines +the minimum stack size, in bytes. + +If the value exceeds the system's maximum stack size, or is smaller +than @code{PTHREAD_STACK_MIN}, @code{pthread_attr_setstacksize} will +fail and return @code{EINVAL}. + +@item stack +Provide both the address and size of an application managed stack to +use for the new thread. The base of the memory area is @var{stackaddr} +with the size of the memory area, @var{stacksize}, measured in bytes. + +If the value of @var{stacksize} is less than @code{PTHREAD_STACK_MIN}, +or greater than the system's maximum stack size, or if the value of +@var{stackaddr} lacks the proper alignment, @code{pthread_attr_setstack} +will fail and return @code{EINVAL}. + +@item guardsize +Change the minimum size in bytes of the guard area for the thread's +stack. The default size is a single page. If this value is set, it +will be rounded up to the nearest page size. If the value is set to 0, +a guard area will not be created for this thread. The space allocated +for the guard area is used to catch stack overflow. Therefore, when +allocating large structures on the stack, a larger guard area may be +required to catch a stack overflow. + +If the caller is managing their own stacks (if the @code{stackaddr} +attribute has been set), then the @code{guardsize} attribute is ignored. + +If the value exceeds the @code{stacksize}, @code{pthread_atrr_setguardsize} +will fail and return @code{EINVAL}. +@end table + +@node Cancellation +@section Cancellation + +Cancellation is the mechanism by which a thread can terminate the +execution of another thread. More precisely, a thread can send a +cancellation request to another thread. Depending on its settings, the +target thread can then either ignore the request, honor it immediately, +or defer it till it reaches a cancellation point. When threads are +first created by @code{pthread_create}, they always defer cancellation +requests. + +When a thread eventually honors a cancellation request, it behaves as if +@code{pthread_exit(PTHREAD_CANCELED)} was called. All cleanup handlers +are executed in reverse order, finalization functions for +thread-specific data are called, and finally the thread stops executing. +If the canceled thread was joinable, the return value +@code{PTHREAD_CANCELED} is provided to whichever thread calls +@var{pthread_join} on it. See @code{pthread_exit} for more information. + +Cancellation points are the points where the thread checks for pending +cancellation requests and performs them. The POSIX threads functions +@code{pthread_join}, @code{pthread_cond_wait}, +@code{pthread_cond_timedwait}, @code{pthread_testcancel}, +@code{sem_wait}, and @code{sigwait} are cancellation points. In +addition, these system calls are cancellation points: + +@multitable @columnfractions .33 .33 .33 +@item @t{accept} @tab @t{open} @tab @t{sendmsg} +@item @t{close} @tab @t{pause} @tab @t{sendto} +@item @t{connect} @tab @t{read} @tab @t{system} +@item @t{fcntl} @tab @t{recv} @tab @t{tcdrain} +@item @t{fsync} @tab @t{recvfrom} @tab @t{wait} +@item @t{lseek} @tab @t{recvmsg} @tab @t{waitpid} +@item @t{msync} @tab @t{send} @tab @t{write} +@item @t{nanosleep} +@end multitable + +@noindent +All library functions that call these functions (such as +@code{printf}) are also cancellation points. + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_setcancelstate (int @var{state}, int *@var{oldstate}) +@code{pthread_setcancelstate} changes the cancellation state for the +calling thread -- that is, whether cancellation requests are ignored or +not. The @var{state} argument is the new cancellation state: either +@code{PTHREAD_CANCEL_ENABLE} to enable cancellation, or +@code{PTHREAD_CANCEL_DISABLE} to disable cancellation (cancellation +requests are ignored). + +If @var{oldstate} is not @code{NULL}, the previous cancellation state is +stored in the location pointed to by @var{oldstate}, and can thus be +restored later by another call to @code{pthread_setcancelstate}. + +If the @var{state} argument is not @code{PTHREAD_CANCEL_ENABLE} or +@code{PTHREAD_CANCEL_DISABLE}, @code{pthread_setcancelstate} fails and +returns @code{EINVAL}. Otherwise it returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_setcanceltype (int @var{type}, int *@var{oldtype}) +@code{pthread_setcanceltype} changes the type of responses to +cancellation requests for the calling thread: asynchronous (immediate) +or deferred. The @var{type} argument is the new cancellation type: +either @code{PTHREAD_CANCEL_ASYNCHRONOUS} to cancel the calling thread +as soon as the cancellation request is received, or +@code{PTHREAD_CANCEL_DEFERRED} to keep the cancellation request pending +until the next cancellation point. If @var{oldtype} is not @code{NULL}, +the previous cancellation state is stored in the location pointed to by +@var{oldtype}, and can thus be restored later by another call to +@code{pthread_setcanceltype}. + +If the @var{type} argument is not @code{PTHREAD_CANCEL_DEFERRED} or +@code{PTHREAD_CANCEL_ASYNCHRONOUS}, @code{pthread_setcanceltype} fails +and returns @code{EINVAL}. Otherwise it returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun void pthread_testcancel (@var{void}) +@code{pthread_testcancel} does nothing except testing for pending +cancellation and executing it. Its purpose is to introduce explicit +checks for cancellation in long sequences of code that do not call +cancellation point functions otherwise. +@end deftypefun + +@node Cleanup Handlers +@section Cleanup Handlers + +Cleanup handlers are functions that get called when a thread terminates, +either by calling @code{pthread_exit} or because of +cancellation. Cleanup handlers are installed and removed following a +stack-like discipline. + +The purpose of cleanup handlers is to free the resources that a thread +may hold at the time it terminates. In particular, if a thread exits or +is canceled while it owns a locked mutex, the mutex will remain locked +forever and prevent other threads from executing normally. The best way +to avoid this is, just before locking the mutex, to install a cleanup +handler whose effect is to unlock the mutex. Cleanup handlers can be +used similarly to free blocks allocated with @code{malloc} or close file +descriptors on thread termination. + +Here is how to lock a mutex @var{mut} in such a way that it will be +unlocked if the thread is canceled while @var{mut} is locked: + +@smallexample +pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut); +pthread_mutex_lock(&mut); +/* do some work */ +pthread_mutex_unlock(&mut); +pthread_cleanup_pop(0); +@end smallexample + +Equivalently, the last two lines can be replaced by + +@smallexample +pthread_cleanup_pop(1); +@end smallexample + +Notice that the code above is safe only in deferred cancellation mode +(see @code{pthread_setcanceltype}). In asynchronous cancellation mode, a +cancellation can occur between @code{pthread_cleanup_push} and +@code{pthread_mutex_lock}, or between @code{pthread_mutex_unlock} and +@code{pthread_cleanup_pop}, resulting in both cases in the thread trying +to unlock a mutex not locked by the current thread. This is the main +reason why asynchronous cancellation is difficult to use. + +If the code above must also work in asynchronous cancellation mode, +then it must switch to deferred mode for locking and unlocking the +mutex: + +@smallexample +pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); +pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut); +pthread_mutex_lock(&mut); +/* do some work */ +pthread_cleanup_pop(1); +pthread_setcanceltype(oldtype, NULL); +@end smallexample + +The code above can be rewritten in a more compact and efficient way, +using the non-portable functions @code{pthread_cleanup_push_defer_np} +and @code{pthread_cleanup_pop_restore_np}: + +@smallexample +pthread_cleanup_push_defer_np(pthread_mutex_unlock, (void *) &mut); +pthread_mutex_lock(&mut); +/* do some work */ +pthread_cleanup_pop_restore_np(1); +@end smallexample + +@comment pthread.h +@comment POSIX +@deftypefun void pthread_cleanup_push (void (*@var{routine}) (void *), void *@var{arg}) + +@code{pthread_cleanup_push} installs the @var{routine} function with +argument @var{arg} as a cleanup handler. From this point on to the +matching @code{pthread_cleanup_pop}, the function @var{routine} will be +called with arguments @var{arg} when the thread terminates, either +through @code{pthread_exit} or by cancellation. If several cleanup +handlers are active at that point, they are called in LIFO order: the +most recently installed handler is called first. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun void pthread_cleanup_pop (int @var{execute}) +@code{pthread_cleanup_pop} removes the most recently installed cleanup +handler. If the @var{execute} argument is not 0, it also executes the +handler, by calling the @var{routine} function with arguments +@var{arg}. If the @var{execute} argument is 0, the handler is only +removed but not executed. +@end deftypefun + +Matching pairs of @code{pthread_cleanup_push} and +@code{pthread_cleanup_pop} must occur in the same function, at the same +level of block nesting. Actually, @code{pthread_cleanup_push} and +@code{pthread_cleanup_pop} are macros, and the expansion of +@code{pthread_cleanup_push} introduces an open brace @code{@{} with the +matching closing brace @code{@}} being introduced by the expansion of the +matching @code{pthread_cleanup_pop}. + +@comment pthread.h +@comment GNU +@deftypefun void pthread_cleanup_push_defer_np (void (*@var{routine}) (void *), void *@var{arg}) +@code{pthread_cleanup_push_defer_np} is a non-portable extension that +combines @code{pthread_cleanup_push} and @code{pthread_setcanceltype}. +It pushes a cleanup handler just as @code{pthread_cleanup_push} does, +but also saves the current cancellation type and sets it to deferred +cancellation. This ensures that the cleanup mechanism is effective even +if the thread was initially in asynchronous cancellation mode. +@end deftypefun + +@comment pthread.h +@comment GNU +@deftypefun void pthread_cleanup_pop_restore_np (int @var{execute}) +@code{pthread_cleanup_pop_restore_np} pops a cleanup handler introduced +by @code{pthread_cleanup_push_defer_np}, and restores the cancellation +type to its value at the time @code{pthread_cleanup_push_defer_np} was +called. +@end deftypefun + +@code{pthread_cleanup_push_defer_np} and +@code{pthread_cleanup_pop_restore_np} must occur in matching pairs, at +the same level of block nesting. + +The sequence + +@smallexample +pthread_cleanup_push_defer_np(routine, arg); +... +pthread_cleanup_pop_defer_np(execute); +@end smallexample + +@noindent +is functionally equivalent to (but more compact and efficient than) + +@smallexample +@{ + int oldtype; + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); + pthread_cleanup_push(routine, arg); + ... + pthread_cleanup_pop(execute); + pthread_setcanceltype(oldtype, NULL); +@} +@end smallexample + + +@node Mutexes +@section Mutexes + +A mutex is a MUTual EXclusion device, and is useful for protecting +shared data structures from concurrent modifications, and implementing +critical sections and monitors. + +A mutex has two possible states: unlocked (not owned by any thread), +and locked (owned by one thread). A mutex can never be owned by two +different threads simultaneously. A thread attempting to lock a mutex +that is already locked by another thread is suspended until the owning +thread unlocks the mutex first. + +None of the mutex functions is a cancellation point, not even +@code{pthread_mutex_lock}, in spite of the fact that it can suspend a +thread for arbitrary durations. This way, the status of mutexes at +cancellation points is predictable, allowing cancellation handlers to +unlock precisely those mutexes that need to be unlocked before the +thread stops executing. Consequently, threads using deferred +cancellation should never hold a mutex for extended periods of time. + +It is not safe to call mutex functions from a signal handler. In +particular, calling @code{pthread_mutex_lock} or +@code{pthread_mutex_unlock} from a signal handler may deadlock the +calling thread. + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_mutex_init (pthread_mutex_t *@var{mutex}, const pthread_mutexattr_t *@var{mutexattr}) + +@code{pthread_mutex_init} initializes the mutex object pointed to by +@var{mutex} according to the mutex attributes specified in @var{mutexattr}. +If @var{mutexattr} is @code{NULL}, default attributes are used instead. + +The LinuxThreads implementation supports only one mutex attribute, +the @var{mutex type}, which is either ``fast'', ``recursive'', or +``error checking''. The type of a mutex determines whether +it can be locked again by a thread that already owns it. +The default type is ``fast''. + +Variables of type @code{pthread_mutex_t} can also be initialized +statically, using the constants @code{PTHREAD_MUTEX_INITIALIZER} (for +timed mutexes), @code{PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP} (for +recursive mutexes), @code{PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP} +(for fast mutexes(, and @code{PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP} +(for error checking mutexes). + +@code{pthread_mutex_init} always returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_mutex_lock (pthread_mutex_t *mutex)) +@code{pthread_mutex_lock} locks the given mutex. If the mutex is +currently unlocked, it becomes locked and owned by the calling thread, +and @code{pthread_mutex_lock} returns immediately. If the mutex is +already locked by another thread, @code{pthread_mutex_lock} suspends the +calling thread until the mutex is unlocked. + +If the mutex is already locked by the calling thread, the behavior of +@code{pthread_mutex_lock} depends on the type of the mutex. If the mutex +is of the ``fast'' type, the calling thread is suspended. It will +remain suspended forever, because no other thread can unlock the mutex. +If the mutex is of the ``error checking'' type, @code{pthread_mutex_lock} +returns immediately with the error code @code{EDEADLK}. If the mutex is +of the ``recursive'' type, @code{pthread_mutex_lock} succeeds and +returns immediately, recording the number of times the calling thread +has locked the mutex. An equal number of @code{pthread_mutex_unlock} +operations must be performed before the mutex returns to the unlocked +state. +@c This doesn't discuss PTHREAD_MUTEX_TIMED_NP mutex attributes. FIXME +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_mutex_trylock (pthread_mutex_t *@var{mutex}) +@code{pthread_mutex_trylock} behaves identically to +@code{pthread_mutex_lock}, except that it does not block the calling +thread if the mutex is already locked by another thread (or by the +calling thread in the case of a ``fast'' mutex). Instead, +@code{pthread_mutex_trylock} returns immediately with the error code +@code{EBUSY}. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_mutex_timedlock (pthread_mutex_t *@var{mutex}, const struct timespec *@var{abstime}) +The @code{pthread_mutex_timedlock} is similar to the +@code{pthread_mutex_lock} function but instead of blocking for in +indefinite time if the mutex is locked by another thread, it returns +when the time specified in @var{abstime} is reached. + +This function can only be used on standard (``timed'') and ``error +checking'' mutexes. It behaves just like @code{pthread_mutex_lock} for +all other types. + +If the mutex is successfully locked, the function returns zero. If the +time specified in @var{abstime} is reached without the mutex being locked, +@code{ETIMEDOUT} is returned. + +This function was introduced in the POSIX.1d revision of the POSIX standard. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_mutex_unlock (pthread_mutex_t *@var{mutex}) +@code{pthread_mutex_unlock} unlocks the given mutex. The mutex is +assumed to be locked and owned by the calling thread on entrance to +@code{pthread_mutex_unlock}. If the mutex is of the ``fast'' type, +@code{pthread_mutex_unlock} always returns it to the unlocked state. If +it is of the ``recursive'' type, it decrements the locking count of the +mutex (number of @code{pthread_mutex_lock} operations performed on it by +the calling thread), and only when this count reaches zero is the mutex +actually unlocked. + +On ``error checking'' mutexes, @code{pthread_mutex_unlock} actually +checks at run-time that the mutex is locked on entrance, and that it was +locked by the same thread that is now calling +@code{pthread_mutex_unlock}. If these conditions are not met, +@code{pthread_mutex_unlock} returns @code{EPERM}, and the mutex remains +unchanged. ``Fast'' and ``recursive'' mutexes perform no such checks, +thus allowing a locked mutex to be unlocked by a thread other than its +owner. This is non-portable behavior and must not be relied upon. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_mutex_destroy (pthread_mutex_t *@var{mutex}) +@code{pthread_mutex_destroy} destroys a mutex object, freeing the +resources it might hold. The mutex must be unlocked on entrance. In the +LinuxThreads implementation, no resources are associated with mutex +objects, thus @code{pthread_mutex_destroy} actually does nothing except +checking that the mutex is unlocked. + +If the mutex is locked by some thread, @code{pthread_mutex_destroy} +returns @code{EBUSY}. Otherwise it returns 0. +@end deftypefun + +If any of the above functions (except @code{pthread_mutex_init}) +is applied to an uninitialized mutex, they will simply return +@code{EINVAL} and do nothing. + +A shared global variable @var{x} can be protected by a mutex as follows: + +@smallexample +int x; +pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; +@end smallexample + +All accesses and modifications to @var{x} should be bracketed by calls to +@code{pthread_mutex_lock} and @code{pthread_mutex_unlock} as follows: + +@smallexample +pthread_mutex_lock(&mut); +/* operate on x */ +pthread_mutex_unlock(&mut); +@end smallexample + +Mutex attributes can be specified at mutex creation time, by passing a +mutex attribute object as second argument to @code{pthread_mutex_init}. +Passing @code{NULL} is equivalent to passing a mutex attribute object +with all attributes set to their default values. + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_mutexattr_init (pthread_mutexattr_t *@var{attr}) +@code{pthread_mutexattr_init} initializes the mutex attribute object +@var{attr} and fills it with default values for the attributes. + +This function always returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_mutexattr_destroy (pthread_mutexattr_t *@var{attr}) +@code{pthread_mutexattr_destroy} destroys a mutex attribute object, +which must not be reused until it is +reinitialized. @code{pthread_mutexattr_destroy} does nothing in the +LinuxThreads implementation. + +This function always returns 0. +@end deftypefun + +LinuxThreads supports only one mutex attribute: the mutex type, which is +either @code{PTHREAD_MUTEX_ADAPTIVE_NP} for ``fast'' mutexes, +@code{PTHREAD_MUTEX_RECURSIVE_NP} for ``recursive'' mutexes, +@code{PTHREAD_MUTEX_TIMED_NP} for ``timed'' mutexes, or +@code{PTHREAD_MUTEX_ERRORCHECK_NP} for ``error checking'' mutexes. As +the @code{NP} suffix indicates, this is a non-portable extension to the +POSIX standard and should not be employed in portable programs. + +The mutex type determines what happens if a thread attempts to lock a +mutex it already owns with @code{pthread_mutex_lock}. If the mutex is of +the ``fast'' type, @code{pthread_mutex_lock} simply suspends the calling +thread forever. If the mutex is of the ``error checking'' type, +@code{pthread_mutex_lock} returns immediately with the error code +@code{EDEADLK}. If the mutex is of the ``recursive'' type, the call to +@code{pthread_mutex_lock} returns immediately with a success return +code. The number of times the thread owning the mutex has locked it is +recorded in the mutex. The owning thread must call +@code{pthread_mutex_unlock} the same number of times before the mutex +returns to the unlocked state. + +The default mutex type is ``timed'', that is, @code{PTHREAD_MUTEX_TIMED_NP}. +@c This doesn't describe how a ``timed'' mutex behaves. FIXME + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_mutexattr_settype (pthread_mutexattr_t *@var{attr}, int @var{type}) +@code{pthread_mutexattr_settype} sets the mutex type attribute in +@var{attr} to the value specified by @var{type}. + +If @var{type} is not @code{PTHREAD_MUTEX_ADAPTIVE_NP}, +@code{PTHREAD_MUTEX_RECURSIVE_NP}, @code{PTHREAD_MUTEX_TIMED_NP}, or +@code{PTHREAD_MUTEX_ERRORCHECK_NP}, this function will return +@code{EINVAL} and leave @var{attr} unchanged. + +The standard Unix98 identifiers @code{PTHREAD_MUTEX_DEFAULT}, +@code{PTHREAD_MUTEX_NORMAL}, @code{PTHREAD_MUTEX_RECURSIVE}, +and @code{PTHREAD_MUTEX_ERRORCHECK} are also permitted. + +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_mutexattr_gettype (const pthread_mutexattr_t *@var{attr}, int *@var{type}) +@code{pthread_mutexattr_gettype} retrieves the current value of the +mutex type attribute in @var{attr} and stores it in the location pointed +to by @var{type}. + +This function always returns 0. +@end deftypefun + +@node Condition Variables +@section Condition Variables + +A condition (short for ``condition variable'') is a synchronization +device that allows threads to suspend execution until some predicate on +shared data is satisfied. The basic operations on conditions are: signal +the condition (when the predicate becomes true), and wait for the +condition, suspending the thread execution until another thread signals +the condition. + +A condition variable must always be associated with a mutex, to avoid +the race condition where a thread prepares to wait on a condition +variable and another thread signals the condition just before the first +thread actually waits on it. + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_cond_init (pthread_cond_t *@var{cond}, pthread_condattr_t *cond_@var{attr}) + +@code{pthread_cond_init} initializes the condition variable @var{cond}, +using the condition attributes specified in @var{cond_attr}, or default +attributes if @var{cond_attr} is @code{NULL}. The LinuxThreads +implementation supports no attributes for conditions, hence the +@var{cond_attr} parameter is actually ignored. + +Variables of type @code{pthread_cond_t} can also be initialized +statically, using the constant @code{PTHREAD_COND_INITIALIZER}. + +This function always returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_cond_signal (pthread_cond_t *@var{cond}) +@code{pthread_cond_signal} restarts one of the threads that are waiting +on the condition variable @var{cond}. If no threads are waiting on +@var{cond}, nothing happens. If several threads are waiting on +@var{cond}, exactly one is restarted, but it is not specified which. + +This function always returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_cond_broadcast (pthread_cond_t *@var{cond}) +@code{pthread_cond_broadcast} restarts all the threads that are waiting +on the condition variable @var{cond}. Nothing happens if no threads are +waiting on @var{cond}. + +This function always returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_cond_wait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex}) +@code{pthread_cond_wait} atomically unlocks the @var{mutex} (as per +@code{pthread_unlock_mutex}) and waits for the condition variable +@var{cond} to be signaled. The thread execution is suspended and does +not consume any CPU time until the condition variable is signaled. The +@var{mutex} must be locked by the calling thread on entrance to +@code{pthread_cond_wait}. Before returning to the calling thread, +@code{pthread_cond_wait} re-acquires @var{mutex} (as per +@code{pthread_lock_mutex}). + +Unlocking the mutex and suspending on the condition variable is done +atomically. Thus, if all threads always acquire the mutex before +signaling the condition, this guarantees that the condition cannot be +signaled (and thus ignored) between the time a thread locks the mutex +and the time it waits on the condition variable. + +This function always returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_cond_timedwait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex}, const struct timespec *@var{abstime}) +@code{pthread_cond_timedwait} atomically unlocks @var{mutex} and waits +on @var{cond}, as @code{pthread_cond_wait} does, but it also bounds the +duration of the wait. If @var{cond} has not been signaled before time +@var{abstime}, the mutex @var{mutex} is re-acquired and +@code{pthread_cond_timedwait} returns the error code @code{ETIMEDOUT}. +The wait can also be interrupted by a signal; in that case +@code{pthread_cond_timedwait} returns @code{EINTR}. + +The @var{abstime} parameter specifies an absolute time, with the same +origin as @code{time} and @code{gettimeofday}: an @var{abstime} of 0 +corresponds to 00:00:00 GMT, January 1, 1970. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_cond_destroy (pthread_cond_t *@var{cond}) +@code{pthread_cond_destroy} destroys the condition variable @var{cond}, +freeing the resources it might hold. If any threads are waiting on the +condition variable, @code{pthread_cond_destroy} leaves @var{cond} +untouched and returns @code{EBUSY}. Otherwise it returns 0, and +@var{cond} must not be used again until it is reinitialized. + +In the LinuxThreads implementation, no resources are associated with +condition variables, so @code{pthread_cond_destroy} actually does +nothing. +@end deftypefun + +@code{pthread_cond_wait} and @code{pthread_cond_timedwait} are +cancellation points. If a thread is canceled while suspended in one of +these functions, the thread immediately resumes execution, relocks the +mutex specified by @var{mutex}, and finally executes the cancellation. +Consequently, cleanup handlers are assured that @var{mutex} is locked +when they are called. + +It is not safe to call the condition variable functions from a signal +handler. In particular, calling @code{pthread_cond_signal} or +@code{pthread_cond_broadcast} from a signal handler may deadlock the +calling thread. + +Consider two shared variables @var{x} and @var{y}, protected by the +mutex @var{mut}, and a condition variable @var{cond} that is to be +signaled whenever @var{x} becomes greater than @var{y}. + +@smallexample +int x,y; +pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +@end smallexample + +Waiting until @var{x} is greater than @var{y} is performed as follows: + +@smallexample +pthread_mutex_lock(&mut); +while (x <= y) @{ + pthread_cond_wait(&cond, &mut); +@} +/* operate on x and y */ +pthread_mutex_unlock(&mut); +@end smallexample + +Modifications on @var{x} and @var{y} that may cause @var{x} to become greater than +@var{y} should signal the condition if needed: + +@smallexample +pthread_mutex_lock(&mut); +/* modify x and y */ +if (x > y) pthread_cond_broadcast(&cond); +pthread_mutex_unlock(&mut); +@end smallexample + +If it can be proved that at most one waiting thread needs to be waken +up (for instance, if there are only two threads communicating through +@var{x} and @var{y}), @code{pthread_cond_signal} can be used as a slightly more +efficient alternative to @code{pthread_cond_broadcast}. In doubt, use +@code{pthread_cond_broadcast}. + +To wait for @var{x} to becomes greater than @var{y} with a timeout of 5 +seconds, do: + +@smallexample +struct timeval now; +struct timespec timeout; +int retcode; + +pthread_mutex_lock(&mut); +gettimeofday(&now); +timeout.tv_sec = now.tv_sec + 5; +timeout.tv_nsec = now.tv_usec * 1000; +retcode = 0; +while (x <= y && retcode != ETIMEDOUT) @{ + retcode = pthread_cond_timedwait(&cond, &mut, &timeout); +@} +if (retcode == ETIMEDOUT) @{ + /* timeout occurred */ +@} else @{ + /* operate on x and y */ +@} +pthread_mutex_unlock(&mut); +@end smallexample + +Condition attributes can be specified at condition creation time, by +passing a condition attribute object as second argument to +@code{pthread_cond_init}. Passing @code{NULL} is equivalent to passing +a condition attribute object with all attributes set to their default +values. + +The LinuxThreads implementation supports no attributes for +conditions. The functions on condition attributes are included only for +compliance with the POSIX standard. + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_condattr_init (pthread_condattr_t *@var{attr}) +@deftypefunx int pthread_condattr_destroy (pthread_condattr_t *@var{attr}) +@code{pthread_condattr_init} initializes the condition attribute object +@var{attr} and fills it with default values for the attributes. +@code{pthread_condattr_destroy} destroys the condition attribute object +@var{attr}. + +Both functions do nothing in the LinuxThreads implementation. + +@code{pthread_condattr_init} and @code{pthread_condattr_destroy} always +return 0. +@end deftypefun + +@node POSIX Semaphores +@section POSIX Semaphores + +@vindex SEM_VALUE_MAX +Semaphores are counters for resources shared between threads. The +basic operations on semaphores are: increment the counter atomically, +and wait until the counter is non-null and decrement it atomically. + +Semaphores have a maximum value past which they cannot be incremented. +The macro @code{SEM_VALUE_MAX} is defined to be this maximum value. In +the GNU C library, @code{SEM_VALUE_MAX} is equal to @code{INT_MAX} +(@pxref{Range of Type}), but it may be much smaller on other systems. + +The pthreads library implements POSIX 1003.1b semaphores. These should +not be confused with System V semaphores (@code{ipc}, @code{semctl} and +@code{semop}). +@c !!! SysV IPC is not doc'd at all in our manual + +All the semaphore functions and macros are defined in @file{semaphore.h}. + +@comment semaphore.h +@comment POSIX +@deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value}) +@code{sem_init} initializes the semaphore object pointed to by +@var{sem}. The count associated with the semaphore is set initially to +@var{value}. The @var{pshared} argument indicates whether the semaphore +is local to the current process (@var{pshared} is zero) or is to be +shared between several processes (@var{pshared} is not zero). + +On success @code{sem_init} returns 0. On failure it returns -1 and sets +@var{errno} to one of the following values: + +@table @code +@item EINVAL +@var{value} exceeds the maximal counter value @code{SEM_VALUE_MAX} + +@item ENOSYS +@var{pshared} is not zero. LinuxThreads currently does not support +process-shared semaphores. (This will eventually change.) +@end table +@end deftypefun + +@comment semaphore.h +@comment POSIX +@deftypefun int sem_destroy (sem_t * @var{sem}) +@code{sem_destroy} destroys a semaphore object, freeing the resources it +might hold. If any threads are waiting on the semaphore when +@code{sem_destroy} is called, it fails and sets @var{errno} to +@code{EBUSY}. + +In the LinuxThreads implementation, no resources are associated with +semaphore objects, thus @code{sem_destroy} actually does nothing except +checking that no thread is waiting on the semaphore. This will change +when process-shared semaphores are implemented. +@end deftypefun + +@comment semaphore.h +@comment POSIX +@deftypefun int sem_wait (sem_t * @var{sem}) +@code{sem_wait} suspends the calling thread until the semaphore pointed +to by @var{sem} has non-zero count. It then atomically decreases the +semaphore count. + +@code{sem_wait} is a cancellation point. It always returns 0. +@end deftypefun + +@comment semaphore.h +@comment POSIX +@deftypefun int sem_trywait (sem_t * @var{sem}) +@code{sem_trywait} is a non-blocking variant of @code{sem_wait}. If the +semaphore pointed to by @var{sem} has non-zero count, the count is +atomically decreased and @code{sem_trywait} immediately returns 0. If +the semaphore count is zero, @code{sem_trywait} immediately returns -1 +and sets errno to @code{EAGAIN}. +@end deftypefun + +@comment semaphore.h +@comment POSIX +@deftypefun int sem_post (sem_t * @var{sem}) +@code{sem_post} atomically increases the count of the semaphore pointed to +by @var{sem}. This function never blocks. + +@c !!! This para appears not to agree with the code. +On processors supporting atomic compare-and-swap (Intel 486, Pentium and +later, Alpha, PowerPC, MIPS II, Motorola 68k, Ultrasparc), the +@code{sem_post} function is can safely be called from signal handlers. +This is the only thread synchronization function provided by POSIX +threads that is async-signal safe. On the Intel 386 and earlier Sparc +chips, the current LinuxThreads implementation of @code{sem_post} is not +async-signal safe, because the hardware does not support the required +atomic operations. + +@code{sem_post} always succeeds and returns 0, unless the semaphore +count would exceed @code{SEM_VALUE_MAX} after being incremented. In +that case @code{sem_post} returns -1 and sets @var{errno} to +@code{EINVAL}. The semaphore count is left unchanged. +@end deftypefun + +@comment semaphore.h +@comment POSIX +@deftypefun int sem_getvalue (sem_t * @var{sem}, int * @var{sval}) +@code{sem_getvalue} stores in the location pointed to by @var{sval} the +current count of the semaphore @var{sem}. It always returns 0. +@end deftypefun + +@node Thread-Specific Data +@section Thread-Specific Data + +Programs often need global or static variables that have different +values in different threads. Since threads share one memory space, this +cannot be achieved with regular variables. Thread-specific data is the +POSIX threads answer to this need. + +Each thread possesses a private memory block, the thread-specific data +area, or TSD area for short. This area is indexed by TSD keys. The TSD +area associates values of type @code{void *} to TSD keys. TSD keys are +common to all threads, but the value associated with a given TSD key can +be different in each thread. + +For concreteness, the TSD areas can be viewed as arrays of @code{void *} +pointers, TSD keys as integer indices into these arrays, and the value +of a TSD key as the value of the corresponding array element in the +calling thread. + +When a thread is created, its TSD area initially associates @code{NULL} +with all keys. + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_key_create (pthread_key_t *@var{key}, void (*destr_function) (void *)) +@code{pthread_key_create} allocates a new TSD key. The key is stored in +the location pointed to by @var{key}. There is a limit of +@code{PTHREAD_KEYS_MAX} on the number of keys allocated at a given +time. The value initially associated with the returned key is +@code{NULL} in all currently executing threads. + +The @var{destr_function} argument, if not @code{NULL}, specifies a +destructor function associated with the key. When a thread terminates +via @code{pthread_exit} or by cancellation, @var{destr_function} is +called on the value associated with the key in that thread. The +@var{destr_function} is not called if a key is deleted with +@code{pthread_key_delete} or a value is changed with +@code{pthread_setspecific}. The order in which destructor functions are +called at thread termination time is unspecified. + +Before the destructor function is called, the @code{NULL} value is +associated with the key in the current thread. A destructor function +might, however, re-associate non-@code{NULL} values to that key or some +other key. To deal with this, if after all the destructors have been +called for all non-@code{NULL} values, there are still some +non-@code{NULL} values with associated destructors, then the process is +repeated. The LinuxThreads implementation stops the process after +@code{PTHREAD_DESTRUCTOR_ITERATIONS} iterations, even if some +non-@code{NULL} values with associated descriptors remain. Other +implementations may loop indefinitely. + +@code{pthread_key_create} returns 0 unless @code{PTHREAD_KEYS_MAX} keys +have already been allocated, in which case it fails and returns +@code{EAGAIN}. +@end deftypefun + + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_key_delete (pthread_key_t @var{key}) +@code{pthread_key_delete} deallocates a TSD key. It does not check +whether non-@code{NULL} values are associated with that key in the +currently executing threads, nor call the destructor function associated +with the key. + +If there is no such key @var{key}, it returns @code{EINVAL}. Otherwise +it returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_setspecific (pthread_key_t @var{key}, const void *@var{pointer}) +@code{pthread_setspecific} changes the value associated with @var{key} +in the calling thread, storing the given @var{pointer} instead. + +If there is no such key @var{key}, it returns @code{EINVAL}. Otherwise +it returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun {void *} pthread_getspecific (pthread_key_t @var{key}) +@code{pthread_getspecific} returns the value currently associated with +@var{key} in the calling thread. + +If there is no such key @var{key}, it returns @code{NULL}. +@end deftypefun + +The following code fragment allocates a thread-specific array of 100 +characters, with automatic reclaimation at thread exit: + +@smallexample +/* Key for the thread-specific buffer */ +static pthread_key_t buffer_key; + +/* Once-only initialisation of the key */ +static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT; + +/* Allocate the thread-specific buffer */ +void buffer_alloc(void) +@{ + pthread_once(&buffer_key_once, buffer_key_alloc); + pthread_setspecific(buffer_key, malloc(100)); +@} + +/* Return the thread-specific buffer */ +char * get_buffer(void) +@{ + return (char *) pthread_getspecific(buffer_key); +@} + +/* Allocate the key */ +static void buffer_key_alloc() +@{ + pthread_key_create(&buffer_key, buffer_destroy); +@} + +/* Free the thread-specific buffer */ +static void buffer_destroy(void * buf) +@{ + free(buf); +@} +@end smallexample + +@node Threads and Signal Handling +@section Threads and Signal Handling + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_sigmask (int @var{how}, const sigset_t *@var{newmask}, sigset_t *@var{oldmask}) +@code{pthread_sigmask} changes the signal mask for the calling thread as +described by the @var{how} and @var{newmask} arguments. If @var{oldmask} +is not @code{NULL}, the previous signal mask is stored in the location +pointed to by @var{oldmask}. + +The meaning of the @var{how} and @var{newmask} arguments is the same as +for @code{sigprocmask}. If @var{how} is @code{SIG_SETMASK}, the signal +mask is set to @var{newmask}. If @var{how} is @code{SIG_BLOCK}, the +signals specified to @var{newmask} are added to the current signal mask. +If @var{how} is @code{SIG_UNBLOCK}, the signals specified to +@var{newmask} are removed from the current signal mask. + +Recall that signal masks are set on a per-thread basis, but signal +actions and signal handlers, as set with @code{sigaction}, are shared +between all threads. + +The @code{pthread_sigmask} function returns 0 on success, and one of the +following error codes on error: +@table @code +@item EINVAL +@var{how} is not one of @code{SIG_SETMASK}, @code{SIG_BLOCK}, or @code{SIG_UNBLOCK} + +@item EFAULT +@var{newmask} or @var{oldmask} point to invalid addresses +@end table +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_kill (pthread_t @var{thread}, int @var{signo}) +@code{pthread_kill} sends signal number @var{signo} to the thread +@var{thread}. The signal is delivered and handled as described in +@ref{Signal Handling}. + +@code{pthread_kill} returns 0 on success, one of the following error codes +on error: +@table @code +@item EINVAL +@var{signo} is not a valid signal number + +@item ESRCH +The thread @var{thread} does not exist (e.g. it has already terminated) +@end table +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int sigwait (const sigset_t *@var{set}, int *@var{sig}) +@code{sigwait} suspends the calling thread until one of the signals in +@var{set} is delivered to the calling thread. It then stores the number +of the signal received in the location pointed to by @var{sig} and +returns. The signals in @var{set} must be blocked and not ignored on +entrance to @code{sigwait}. If the delivered signal has a signal handler +function attached, that function is @emph{not} called. + +@code{sigwait} is a cancellation point. It always returns 0. +@end deftypefun + +For @code{sigwait} to work reliably, the signals being waited for must be +blocked in all threads, not only in the calling thread, since +otherwise the POSIX semantics for signal delivery do not guarantee +that it's the thread doing the @code{sigwait} that will receive the signal. +The best way to achieve this is block those signals before any threads +are created, and never unblock them in the program other than by +calling @code{sigwait}. + +Signal handling in LinuxThreads departs significantly from the POSIX +standard. According to the standard, ``asynchronous'' (external) signals +are addressed to the whole process (the collection of all threads), +which then delivers them to one particular thread. The thread that +actually receives the signal is any thread that does not currently block +the signal. + +In LinuxThreads, each thread is actually a kernel process with its own +PID, so external signals are always directed to one particular thread. +If, for instance, another thread is blocked in @code{sigwait} on that +signal, it will not be restarted. + +The LinuxThreads implementation of @code{sigwait} installs dummy signal +handlers for the signals in @var{set} for the duration of the +wait. Since signal handlers are shared between all threads, other +threads must not attach their own signal handlers to these signals, or +alternatively they should all block these signals (which is recommended +anyway). + +@node Threads and Fork +@section Threads and Fork + +It's not intuitively obvious what should happen when a multi-threaded POSIX +process calls @code{fork}. Not only are the semantics tricky, but you may +need to write code that does the right thing at fork time even if that code +doesn't use the @code{fork} function. Moreover, you need to be aware of +interaction between @code{fork} and some library features like +@code{pthread_once} and stdio streams. + +When @code{fork} is called by one of the threads of a process, it creates a new +process which is copy of the calling process. Effectively, in addition to +copying certain system objects, the function takes a snapshot of the memory +areas of the parent process, and creates identical areas in the child. +To make matters more complicated, with threads it's possible for two or more +threads to concurrently call fork to create two or more child processes. + +The child process has a copy of the address space of the parent, but it does +not inherit any of its threads. Execution of the child process is carried out +by a new thread which returns from @code{fork} function with a return value of +zero; it is the only thread in the child process. Because threads are not +inherited across fork, issues arise. At the time of the call to @code{fork}, +threads in the parent process other than the one calling @code{fork} may have +been executing critical regions of code. As a result, the child process may +get a copy of objects that are not in a well-defined state. This potential +problem affects all components of the program. + +Any program component which will continue being used in a child process must +correctly handle its state during @code{fork}. For this purpose, the POSIX +interface provides the special function @code{pthread_atfork} for installing +pointers to handler functions which are called from within @code{fork}. + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_atfork (void (*@var{prepare})(void), void (*@var{parent})(void), void (*@var{child})(void)) + +@code{pthread_atfork} registers handler functions to be called just +before and just after a new process is created with @code{fork}. The +@var{prepare} handler will be called from the parent process, just +before the new process is created. The @var{parent} handler will be +called from the parent process, just before @code{fork} returns. The +@var{child} handler will be called from the child process, just before +@code{fork} returns. + +@code{pthread_atfork} returns 0 on success and a non-zero error code on +error. + +One or more of the three handlers @var{prepare}, @var{parent} and +@var{child} can be given as @code{NULL}, meaning that no handler needs +to be called at the corresponding point. + +@code{pthread_atfork} can be called several times to install several +sets of handlers. At @code{fork} time, the @var{prepare} handlers are +called in LIFO order (last added with @code{pthread_atfork}, first +called before @code{fork}), while the @var{parent} and @var{child} +handlers are called in FIFO order (first added, first called). + +If there is insufficient memory available to register the handlers, +@code{pthread_atfork} fails and returns @code{ENOMEM}. Otherwise it +returns 0. + +The functions @code{fork} and @code{pthread_atfork} must not be regarded as +reentrant from the context of the handlers. That is to say, if a +@code{pthread_atfork} handler invoked from within @code{fork} calls +@code{pthread_atfork} or @code{fork}, the behavior is undefined. + +Registering a triplet of handlers is an atomic operation with respect to fork. +If new handlers are registered at about the same time as a fork occurs, either +all three handlers will be called, or none of them will be called. + +The handlers are inherited by the child process, and there is no +way to remove them, short of using @code{exec} to load a new +pocess image. + +@end deftypefun + +To understand the purpose of @code{pthread_atfork}, recall that +@code{fork} duplicates the whole memory space, including mutexes in +their current locking state, but only the calling thread: other threads +are not running in the child process. Thus, if a mutex is locked by a +thread other than the thread calling @code{fork}, that mutex will remain +locked forever in the child process, possibly blocking the execution of +the child process. Or if some shared data, such as a linked list, was in the +middle of being updated by a thread in the parent process, the child +will get a copy of the incompletely updated data which it cannot use. + +To avoid this, install handlers with @code{pthread_atfork} as follows: have the +@var{prepare} handler lock the mutexes (in locking order), and the +@var{parent} handler unlock the mutexes. The @var{child} handler should reset +the mutexes using @code{pthread_mutex_init}, as well as any other +synchronization objects such as condition variables. + +Locking the global mutexes before the fork ensures that all other threads are +locked out of the critical regions of code protected by those mutexes. Thus +when @code{fork} takes a snapshot of the parent's address space, that snapshot +will copy valid, stable data. Resetting the synchronization objects in the +child process will ensure they are properly cleansed of any artifacts from the +threading subsystem of the parent process. For example, a mutex may inherit +a wait queue of threads waiting for the lock; this wait queue makes no sense +in the child process. Initializing the mutex takes care of this. + +@node Streams and Fork +@section Streams and Fork + +The GNU standard I/O library has an internal mutex which guards the internal +linked list of all standard C FILE objects. This mutex is properly taken care +of during @code{fork} so that the child receives an intact copy of the list. +This allows the @code{fopen} function, and related stream-creating functions, +to work correctly in the child process, since these functions need to insert +into the list. + +However, the individual stream locks are not completely taken care of. Thus +unless the multithreaded application takes special precautions in its use of +@code{fork}, the child process might not be able to safely use the streams that +it inherited from the parent. In general, for any given open stream in the +parent that is to be used by the child process, the application must ensure +that that stream is not in use by another thread when @code{fork} is called. +Otherwise an inconsistent copy of the stream object be produced. An easy way to +ensure this is to use @code{flockfile} to lock the stream prior to calling +@code{fork} and then unlock it with @code{funlockfile} inside the parent +process, provided that the parent's threads properly honor these locks. +Nothing special needs to be done in the child process, since the library +internally resets all stream locks. + +Note that the stream locks are not shared between the parent and child. +For example, even if you ensure that, say, the stream @code{stdout} is properly +treated and can be safely used in the child, the stream locks do not provide +an exclusion mechanism between the parent and child. If both processes write +to @code{stdout}, strangely interleaved output may result regardless of +the explicit use of @code{flockfile} or implicit locks. + +Also note that these provisions are a GNU extension; other systems might not +provide any way for streams to be used in the child of a multithreaded process. +POSIX requires that such a child process confines itself to calling only +asynchronous safe functions, which excludes much of the library, including +standard I/O. + +@node Miscellaneous Thread Functions +@section Miscellaneous Thread Functions + +@comment pthread.h +@comment POSIX +@deftypefun {pthread_t} pthread_self (@var{void}) +@code{pthread_self} returns the thread identifier for the calling thread. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_equal (pthread_t thread1, pthread_t thread2) +@code{pthread_equal} determines if two thread identifiers refer to the same +thread. + +A non-zero value is returned if @var{thread1} and @var{thread2} refer to +the same thread. Otherwise, 0 is returned. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_detach (pthread_t @var{th}) +@code{pthread_detach} puts the thread @var{th} in the detached +state. This guarantees that the memory resources consumed by @var{th} +will be freed immediately when @var{th} terminates. However, this +prevents other threads from synchronizing on the termination of @var{th} +using @code{pthread_join}. + +A thread can be created initially in the detached state, using the +@code{detachstate} attribute to @code{pthread_create}. In contrast, +@code{pthread_detach} applies to threads created in the joinable state, +and which need to be put in the detached state later. + +After @code{pthread_detach} completes, subsequent attempts to perform +@code{pthread_join} on @var{th} will fail. If another thread is already +joining the thread @var{th} at the time @code{pthread_detach} is called, +@code{pthread_detach} does nothing and leaves @var{th} in the joinable +state. + +On success, 0 is returned. On error, one of the following codes is +returned: +@table @code +@item ESRCH +No thread could be found corresponding to that specified by @var{th} +@item EINVAL +The thread @var{th} is already in the detached state +@end table +@end deftypefun + +@comment pthread.h +@comment GNU +@deftypefun void pthread_kill_other_threads_np (@var{void}) +@code{pthread_kill_other_threads_np} is a non-portable LinuxThreads extension. +It causes all threads in the program to terminate immediately, except +the calling thread which proceeds normally. It is intended to be +called just before a thread calls one of the @code{exec} functions, +e.g. @code{execve}. + +Termination of the other threads is not performed through +@code{pthread_cancel} and completely bypasses the cancellation +mechanism. Hence, the current settings for cancellation state and +cancellation type are ignored, and the cleanup handlers are not +executed in the terminated threads. + +According to POSIX 1003.1c, a successful @code{exec*} in one of the +threads should automatically terminate all other threads in the program. +This behavior is not yet implemented in LinuxThreads. Calling +@code{pthread_kill_other_threads_np} before @code{exec*} achieves much +of the same behavior, except that if @code{exec*} ultimately fails, then +all other threads are already killed. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_once (pthread_once_t *once_@var{control}, void (*@var{init_routine}) (void)) + +The purpose of @code{pthread_once} is to ensure that a piece of +initialization code is executed at most once. The @var{once_control} +argument points to a static or extern variable statically initialized +to @code{PTHREAD_ONCE_INIT}. + +The first time @code{pthread_once} is called with a given +@var{once_control} argument, it calls @var{init_routine} with no +argument and changes the value of the @var{once_control} variable to +record that initialization has been performed. Subsequent calls to +@code{pthread_once} with the same @code{once_control} argument do +nothing. + +If a thread is cancelled while executing @var{init_routine} +the state of the @var{once_control} variable is reset so that +a future call to @code{pthread_once} will call the routine again. + +If the process forks while one or more threads are executing +@code{pthread_once} initialization routines, the states of their respective +@var{once_control} variables will appear to be reset in the child process so +that if the child calls @code{pthread_once}, the routines will be executed. + +@code{pthread_once} always returns 0. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_setschedparam (pthread_t target_@var{thread}, int @var{policy}, const struct sched_param *@var{param}) + +@code{pthread_setschedparam} sets the scheduling parameters for the +thread @var{target_thread} as indicated by @var{policy} and +@var{param}. @var{policy} can be either @code{SCHED_OTHER} (regular, +non-realtime scheduling), @code{SCHED_RR} (realtime, round-robin) or +@code{SCHED_FIFO} (realtime, first-in first-out). @var{param} specifies +the scheduling priority for the two realtime policies. See +@code{sched_setpolicy} for more information on scheduling policies. + +The realtime scheduling policies @code{SCHED_RR} and @code{SCHED_FIFO} +are available only to processes with superuser privileges. + +On success, @code{pthread_setschedparam} returns 0. On error it returns +one of the following codes: +@table @code +@item EINVAL +@var{policy} is not one of @code{SCHED_OTHER}, @code{SCHED_RR}, +@code{SCHED_FIFO}, or the priority value specified by @var{param} is not +valid for the specified policy + +@item EPERM +Realtime scheduling was requested but the calling process does not have +sufficient privileges. + +@item ESRCH +The @var{target_thread} is invalid or has already terminated + +@item EFAULT +@var{param} points outside the process memory space +@end table +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_getschedparam (pthread_t target_@var{thread}, int *@var{policy}, struct sched_param *@var{param}) + +@code{pthread_getschedparam} retrieves the scheduling policy and +scheduling parameters for the thread @var{target_thread} and stores them +in the locations pointed to by @var{policy} and @var{param}, +respectively. + +@code{pthread_getschedparam} returns 0 on success, or one of the +following error codes on failure: +@table @code +@item ESRCH +The @var{target_thread} is invalid or has already terminated. + +@item EFAULT +@var{policy} or @var{param} point outside the process memory space. + +@end table +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_setconcurrency (int @var{level}) +@code{pthread_setconcurrency} is unused in LinuxThreads due to the lack +of a mapping of user threads to kernel threads. It exists for source +compatibility. It does store the value @var{level} so that it can be +returned by a subsequent call to @code{pthread_getconcurrency}. It takes +no other action however. +@end deftypefun + +@comment pthread.h +@comment POSIX +@deftypefun int pthread_getconcurrency () +@code{pthread_getconcurrency} is unused in LinuxThreads due to the lack +of a mapping of user threads to kernel threads. It exists for source +compatibility. However, it will return the value that was set by the +last call to @code{pthread_setconcurrency}. +@end deftypefun + diff --git a/newlib/libc/sys/linux/linuxthreads/lockfile.c b/newlib/libc/sys/linux/linuxthreads/lockfile.c new file mode 100644 index 000000000..0aeb15086 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/lockfile.c @@ -0,0 +1,97 @@ +/* lockfile - Handle locking and unlocking of stream. + Copyright (C) 1996, 1998, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <sys/lock.h> +#include <stdio.h> +#include <pthread.h> +#include "internals.h" + +#ifdef USE_IN_LIBIO +#include "../libio/libioP.h" +#endif + +#ifndef SHARED +/* We need a hook to force this file to be linked in when static + libpthread is used. */ +const int __pthread_provide_lockfile = 0; +#endif + +void +__flockfile (FILE *stream) +{ + __lock_acquire_recursive (*(_LOCK_RECURSIVE_T *)&stream->_lock); +} +#undef _IO_flockfile +strong_alias (__flockfile, _IO_flockfile) +weak_alias (__flockfile, flockfile); + + +void +__funlockfile (FILE *stream) +{ + __lock_release_recursive (*(_LOCK_RECURSIVE_T *)&stream->_lock); +} +#undef _IO_funlockfile +strong_alias (__funlockfile, _IO_funlockfile) +weak_alias (__funlockfile, funlockfile); + + +int +__ftrylockfile (FILE *stream) +{ + return __lock_try_acquire_recursive (*(_LOCK_RECURSIVE_T *)&stream->_lock); +} +strong_alias (__ftrylockfile, _IO_ftrylockfile) +weak_alias (__ftrylockfile, ftrylockfile); + +void +__flockfilelist(void) +{ +#ifdef USE_IN_LIBIO + _IO_list_lock(); +#endif +} + +void +__funlockfilelist(void) +{ +#ifdef USE_IN_LIBIO + _IO_list_unlock(); +#endif +} + +void +__fresetlockfiles (void) +{ +#ifdef USE_IN_LIBIO + _IO_ITER i; + + pthread_mutexattr_t attr; + + __pthread_mutexattr_init (&attr); + __pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE_NP); + + for (i = _IO_iter_begin(); i != _IO_iter_end(); i = _IO_iter_next(i)) + __pthread_mutex_init (_IO_iter_file(i)->_lock, &attr); + + __pthread_mutexattr_destroy (&attr); + + _IO_list_resetlock(); +#endif +} diff --git a/newlib/libc/sys/linux/linuxthreads/machine/Makefile.am b/newlib/libc/sys/linux/linuxthreads/machine/Makefile.am new file mode 100644 index 000000000..27c348c3b --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/Makefile.am @@ -0,0 +1,10 @@ +## Process this file with automake to generate Makefile.in + +AUTOMAKE_OPTIONS = cygnus + +SUBDIRS = $(machine_dir) . + +doc: + +ACLOCAL_AMFLAGS = -I ../../../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host diff --git a/newlib/libc/sys/linux/linuxthreads/machine/Makefile.in b/newlib/libc/sys/linux/linuxthreads/machine/Makefile.in new file mode 100644 index 000000000..52a2b60ea --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/Makefile.in @@ -0,0 +1,356 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AR = @AR@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DLLTOOL = @DLLTOOL@ +EXEEXT = @EXEEXT@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ +aext = @aext@ +libm_machine_dir = @libm_machine_dir@ +machine_dir = @machine_dir@ +newlib_basedir = @newlib_basedir@ +oext = @oext@ +sys_dir = @sys_dir@ + +AUTOMAKE_OPTIONS = cygnus + +SUBDIRS = $(machine_dir) . + +ACLOCAL_AMFLAGS = -I ../../../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../../../mkinstalldirs +CONFIG_CLEAN_FILES = +DIST_COMMON = Makefile.am Makefile.in aclocal.m4 configure configure.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in \ + ../../../../../acinclude.m4 ../../../../../aclocal.m4 \ + ../../../../../libtool.m4 + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive install-info-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-info-am: +install-info: install-info-recursive +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: +uninstall: uninstall-recursive +all-am: Makefile +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-info-am \ +install-info install-exec-am install-exec install-data-am install-data \ +install-am install uninstall-am uninstall all-redirect all-am all \ +installdirs-am installdirs mostlyclean-generic distclean-generic \ +clean-generic maintainer-clean-generic clean mostlyclean distclean \ +maintainer-clean + + +doc: + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/newlib/libc/sys/linux/linuxthreads/machine/aclocal.m4 b/newlib/libc/sys/linux/linuxthreads/machine/aclocal.m4 new file mode 100644 index 000000000..98bba1a0b --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/aclocal.m4 @@ -0,0 +1,1191 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +dnl This provides configure definitions used by all the newlib +dnl configure.in files. + +dnl Basic newlib configury. This calls basic introductory stuff, +dnl including AM_INIT_AUTOMAKE and AC_CANONICAL_HOST. It also runs +dnl configure.host. The only argument is the relative path to the top +dnl newlib directory. + +AC_DEFUN(NEWLIB_CONFIGURE, +[ +dnl Default to --enable-multilib +AC_ARG_ENABLE(multilib, +[ --enable-multilib build many library versions (default)], +[case "${enableval}" in + yes) multilib=yes ;; + no) multilib=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for multilib option) ;; + esac], [multilib=yes])dnl + +dnl Support --enable-target-optspace +AC_ARG_ENABLE(target-optspace, +[ --enable-target-optspace optimize for space], +[case "${enableval}" in + yes) target_optspace=yes ;; + no) target_optspace=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for target-optspace option) ;; + esac], [target_optspace=])dnl + +dnl Support --enable-malloc-debugging - currently only supported for Cygwin +AC_ARG_ENABLE(malloc-debugging, +[ --enable-malloc-debugging indicate malloc debugging requested], +[case "${enableval}" in + yes) malloc_debugging=yes ;; + no) malloc_debugging=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for malloc-debugging option) ;; + esac], [malloc_debugging=])dnl + +dnl Support --enable-newlib-mb +AC_ARG_ENABLE(newlib-mb, +[ --enable-newlib-mb enable multibyte support], +[case "${enableval}" in + yes) newlib_mb=yes ;; + no) newlib_mb=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-mb option) ;; + esac], [newlib_mb=])dnl + +dnl Support --enable-newlib-multithread +AC_ARG_ENABLE(newlib-multithread, +[ --enable-newlib-multithread enable support for multiple threads], +[case "${enableval}" in + yes) newlib_multithread=yes ;; + no) newlib_multithread=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-multithread option) ;; + esac], [newlib_multithread=yes])dnl + +dnl Support --enable-newlib-elix-level +AC_ARG_ENABLE(newlib-elix-level, +[ --enable-newlib-elix-level supply desired elix library level (1-4)], +[case "${enableval}" in + 0) newlib_elix_level=0 ;; + 1) newlib_elix_level=1 ;; + 2) newlib_elix_level=2 ;; + 3) newlib_elix_level=3 ;; + 4) newlib_elix_level=4 ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-elix-level option) ;; + esac], [newlib_elix_level=0])dnl + +dnl Support --disable-newlib-io-float +AC_ARG_ENABLE(newlib-io-float, +[ --disable-newlib-io-float disable printf/scanf family float support], +[case "${enableval}" in + yes) newlib_io_float=yes ;; + no) newlib_io_float=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-io-float option) ;; + esac], [newlib_io_float=yes])dnl + +dnl Support --disable-newlib-supplied-syscalls +AC_ARG_ENABLE(newlib-supplied-syscalls, +[ --disable-newlib-supplied-syscalls disable newlib from supplying syscalls], +[case "${enableval}" in + yes) newlib_may_supply_syscalls=yes ;; + no) newlib_may_supply_syscalls=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-supplied-syscalls option) ;; + esac], [newlib_may_supply_syscalls=yes])dnl + +AM_CONDITIONAL(MAY_SUPPLY_SYSCALLS, test x[$]{newlib_may_supply_syscalls} = xyes) + +dnl We may get other options which we don't document: +dnl --with-target-subdir, --with-multisrctop, --with-multisubdir + +test -z "[$]{with_target_subdir}" && with_target_subdir=. + +if test "[$]{srcdir}" = "."; then + if test "[$]{with_target_subdir}" != "."; then + newlib_basedir="[$]{srcdir}/[$]{with_multisrctop}../$1" + else + newlib_basedir="[$]{srcdir}/[$]{with_multisrctop}$1" + fi +else + newlib_basedir="[$]{srcdir}/$1" +fi +AC_SUBST(newlib_basedir) + +AC_CANONICAL_SYSTEM + +AM_INIT_AUTOMAKE(newlib, 1.11.0) + +# FIXME: We temporarily define our own version of AC_PROG_CC. This is +# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We +# are probably using a cross compiler, which will not be able to fully +# link an executable. This should really be fixed in autoconf +# itself. + +AC_DEFUN(LIB_AC_PROG_CC, +[AC_BEFORE([$0], [AC_PROG_CPP])dnl +AC_CHECK_PROG(CC, gcc, gcc) +if test -z "$CC"; then + AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc) + test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH]) +fi + +AC_PROG_CC_GNU + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +dnl Check whether -g works, even if CFLAGS is set, in case the package +dnl plays around with CFLAGS (such as to build both debugging and +dnl normal versions of a library), tasteless as that idea is. + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + AC_PROG_CC_G + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi +]) + +LIB_AC_PROG_CC + +AC_CHECK_TOOL(AS, as) +AC_CHECK_TOOL(AR, ar) +AC_CHECK_TOOL(RANLIB, ranlib, :) + +AC_PROG_INSTALL + +AM_MAINTAINER_MODE + +# We need AC_EXEEXT to keep automake happy in cygnus mode. However, +# at least currently, we never actually build a program, so we never +# need to use $(EXEEXT). Moreover, the test for EXEEXT normally +# fails, because we are probably configuring with a cross compiler +# which can't create executables. So we include AC_EXEEXT to keep +# automake happy, but we don't execute it, since we don't care about +# the result. +if false; then + AC_EXEEXT +fi + +. [$]{newlib_basedir}/configure.host + +newlib_cflags="[$]{newlib_cflags} -fno-builtin" + +NEWLIB_CFLAGS=${newlib_cflags} +AC_SUBST(NEWLIB_CFLAGS) + +LDFLAGS=${ldflags} +AC_SUBST(LDFLAGS) + +AM_CONDITIONAL(ELIX_LEVEL_0, test x[$]{newlib_elix_level} = x0) +AM_CONDITIONAL(ELIX_LEVEL_1, test x[$]{newlib_elix_level} = x1) +AM_CONDITIONAL(ELIX_LEVEL_2, test x[$]{newlib_elix_level} = x2) +AM_CONDITIONAL(ELIX_LEVEL_3, test x[$]{newlib_elix_level} = x3) +AM_CONDITIONAL(ELIX_LEVEL_4, test x[$]{newlib_elix_level} = x4) + +AM_CONDITIONAL(USE_LIBTOOL, test x[$]{use_libtool} = xyes) + +# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we +# use oext, which is set in configure.host based on the target platform. +OBJEXT=${oext} + +AC_SUBST(OBJEXT) +AC_SUBST(oext) +AC_SUBST(aext) + +AC_SUBST(libm_machine_dir) +AC_SUBST(machine_dir) +AC_SUBST(sys_dir) +]) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Define a conditional. + +AC_DEFUN(AM_CONDITIONAL, +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN(AM_MAINTAINER_MODE, +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + + +# serial 46 AC_PROG_LIBTOOL +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ +])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ +])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ +])])])])])]) + +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# Save cache, so that ltconfig can load it +AC_CACHE_SAVE + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) + +# Reload cache, that may have been modified by ltconfig +AC_CACHE_LOAD + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], +[libtool_flags="$libtool_flags --enable-dlopen"]) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[libtool_flags="$libtool_flags --enable-win32-dll"]) +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +AC_ARG_WITH(pic, + [ --with-pic try to use only PIC/non-PIC objects [default=use both]], + pic_mode="$withval", pic_mode=default) +test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic" +test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac +]) + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + re_direlt=['/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependant libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'] + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* |pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[012]) + lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System' + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd* ) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method=['file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + case $host_cpu in + hppa*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + ia64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + esac + ;; + +irix5* | irix6*) + case $host_os in + irix5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method=["file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"] + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'] ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'] + else + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'] + fi + ;; + +newsos6) + [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +[sysv5uw[78]* | sysv4*uw2*)] + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + motorola) + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'] + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and INCLTDL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and INCLTDL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + INCLTDL= + fi +]) + +# If this macro is not defined by Autoconf, define it here. +ifdef([AC_PROVIDE_IFELSE], + [], + [define([AC_PROVIDE_IFELSE], + [ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + +# AC_LIBTOOL_CXX - enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], [AC_REQUIRE([_AC_LIBTOOL_CXX])]) + +AC_DEFUN([_AC_LIBTOOL_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_PROG_CXXCPP]) +LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-cxx.sh" +lt_save_CC="$CC" +lt_save_CFLAGS="$CFLAGS" +dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC +dnl is set to the C++ compiler. +AR="$AR" LTCC="$CC" CC="$CXX" CXX="$CXX" CFLAGS="$CXXFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" \ +file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \ +--build="$build" --add-tag=CXX $ac_aux_dir/ltcf-cxx.sh $host \ +|| AC_MSG_ERROR([libtool tag configuration failed]) +CC="$lt_save_CC" +CFLAGS="$lt_save_CFLAGS" + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +# AC_LIBTOOL_GCJ - enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ],[AC_REQUIRE([_AC_LIBTOOL_GCJ])]) + +AC_DEFUN([_AC_LIBTOOL_GCJ], +[AC_REQUIRE([AC_PROG_LIBTOOL]) +AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-gcj.sh" +lt_save_CC="$CC" +lt_save_CFLAGS="$CFLAGS" +dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC +dnl is set to the C++ compiler. +AR="$AR" LTCC="$CC" CC="$GCJ" CFLAGS="$GCJFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" \ +file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \ +--build="$build" --add-tag=GCJ $ac_aux_dir/ltcf-gcj.sh $host \ +|| AC_MSG_ERROR([libtool tag configuration failed]) +CC="$lt_save_CC" +CFLAGS="$lt_save_CFLAGS" + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +dnl old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +dnl This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL])dnl + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + diff --git a/newlib/libc/sys/linux/linuxthreads/machine/configure b/newlib/libc/sys/linux/linuxthreads/machine/configure new file mode 100755 index 000000000..5dd19e50e --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/configure @@ -0,0 +1,3430 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-multilib build many library versions (default)" +ac_help="$ac_help + --enable-target-optspace optimize for space" +ac_help="$ac_help + --enable-malloc-debugging indicate malloc debugging requested" +ac_help="$ac_help + --enable-newlib-mb enable multibyte support" +ac_help="$ac_help + --enable-newlib-multithread enable support for multiple threads" +ac_help="$ac_help + --enable-newlib-elix-level supply desired elix library level (1-4)" +ac_help="$ac_help + --disable-newlib-io-float disable printf/scanf family float support" +ac_help="$ac_help + --disable-newlib-supplied-syscalls disable newlib from supplying syscalls" +ac_help="$ac_help + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer" +ac_help="$ac_help + --enable-shared[=PKGS] build shared libraries [default=yes]" +ac_help="$ac_help + --enable-static[=PKGS] build static libraries [default=yes]" +ac_help="$ac_help + --enable-fast-install[=PKGS] optimize for fast installation [default=yes]" +ac_help="$ac_help + --with-gnu-ld assume the C compiler uses GNU ld [default=no]" +ac_help="$ac_help + --disable-libtool-lock avoid locking (might break parallel builds)" +ac_help="$ac_help + --with-pic try to use only PIC/non-PIC objects [default=use both]" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +sitefile= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --site-file=FILE use FILE as the site file + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -site-file | --site-file | --site-fil | --site-fi | --site-f) + ac_prev=sitefile ;; + -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*) + sitefile="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=i386 + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$sitefile"; then + if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi + fi +else + CONFIG_SITE="$sitefile" +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in ../../../../../.. $srcdir/../../../../../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in ../../../../../.. $srcdir/../../../../../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:600: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:653: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:710: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +if test $host != $build; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 +echo "configure:743: checking for Cygwin environment" >&5 +if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 748 "configure" +#include "confdefs.h" + +int main() { + +#ifndef __CYGWIN__ +#define __CYGWIN__ __CYGWIN32__ +#endif +return __CYGWIN__; +; return 0; } +EOF +if { (eval echo configure:759: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_cygwin=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_cygwin=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_cygwin" 1>&6 +CYGWIN= +test "$ac_cv_cygwin" = yes && CYGWIN=yes +echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 +echo "configure:776: checking for mingw32 environment" >&5 +if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 781 "configure" +#include "confdefs.h" + +int main() { +return __MINGW32__; +; return 0; } +EOF +if { (eval echo configure:788: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_mingw32=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_mingw32=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_mingw32" 1>&6 +MINGW32= +test "$ac_cv_mingw32" = yes && MINGW32=yes + +# Check whether --enable-multilib or --disable-multilib was given. +if test "${enable_multilib+set}" = set; then + enableval="$enable_multilib" + case "${enableval}" in + yes) multilib=yes ;; + no) multilib=no ;; + *) { echo "configure: error: bad value ${enableval} for multilib option" 1>&2; exit 1; } ;; + esac +else + multilib=yes +fi + +# Check whether --enable-target-optspace or --disable-target-optspace was given. +if test "${enable_target_optspace+set}" = set; then + enableval="$enable_target_optspace" + case "${enableval}" in + yes) target_optspace=yes ;; + no) target_optspace=no ;; + *) { echo "configure: error: bad value ${enableval} for target-optspace option" 1>&2; exit 1; } ;; + esac +else + target_optspace= +fi + +# Check whether --enable-malloc-debugging or --disable-malloc-debugging was given. +if test "${enable_malloc_debugging+set}" = set; then + enableval="$enable_malloc_debugging" + case "${enableval}" in + yes) malloc_debugging=yes ;; + no) malloc_debugging=no ;; + *) { echo "configure: error: bad value ${enableval} for malloc-debugging option" 1>&2; exit 1; } ;; + esac +else + malloc_debugging= +fi + +# Check whether --enable-newlib-mb or --disable-newlib-mb was given. +if test "${enable_newlib_mb+set}" = set; then + enableval="$enable_newlib_mb" + case "${enableval}" in + yes) newlib_mb=yes ;; + no) newlib_mb=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-mb option" 1>&2; exit 1; } ;; + esac +else + newlib_mb= +fi + +# Check whether --enable-newlib-multithread or --disable-newlib-multithread was given. +if test "${enable_newlib_multithread+set}" = set; then + enableval="$enable_newlib_multithread" + case "${enableval}" in + yes) newlib_multithread=yes ;; + no) newlib_multithread=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-multithread option" 1>&2; exit 1; } ;; + esac +else + newlib_multithread=yes +fi + +# Check whether --enable-newlib-elix-level or --disable-newlib-elix-level was given. +if test "${enable_newlib_elix_level+set}" = set; then + enableval="$enable_newlib_elix_level" + case "${enableval}" in + 0) newlib_elix_level=0 ;; + 1) newlib_elix_level=1 ;; + 2) newlib_elix_level=2 ;; + 3) newlib_elix_level=3 ;; + 4) newlib_elix_level=4 ;; + *) { echo "configure: error: bad value ${enableval} for newlib-elix-level option" 1>&2; exit 1; } ;; + esac +else + newlib_elix_level=0 +fi + +# Check whether --enable-newlib-io-float or --disable-newlib-io-float was given. +if test "${enable_newlib_io_float+set}" = set; then + enableval="$enable_newlib_io_float" + case "${enableval}" in + yes) newlib_io_float=yes ;; + no) newlib_io_float=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-io-float option" 1>&2; exit 1; } ;; + esac +else + newlib_io_float=yes +fi + +# Check whether --enable-newlib-supplied-syscalls or --disable-newlib-supplied-syscalls was given. +if test "${enable_newlib_supplied_syscalls+set}" = set; then + enableval="$enable_newlib_supplied_syscalls" + case "${enableval}" in + yes) newlib_may_supply_syscalls=yes ;; + no) newlib_may_supply_syscalls=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-supplied-syscalls option" 1>&2; exit 1; } ;; + esac +else + newlib_may_supply_syscalls=yes +fi + + + +if test x${newlib_may_supply_syscalls} = xyes; then + MAY_SUPPLY_SYSCALLS_TRUE= + MAY_SUPPLY_SYSCALLS_FALSE='#' +else + MAY_SUPPLY_SYSCALLS_TRUE='#' + MAY_SUPPLY_SYSCALLS_FALSE= +fi + + +test -z "${with_target_subdir}" && with_target_subdir=. + +if test "${srcdir}" = "."; then + if test "${with_target_subdir}" != "."; then + newlib_basedir="${srcdir}/${with_multisrctop}../../../../../.." + else + newlib_basedir="${srcdir}/${with_multisrctop}../../../../.." + fi +else + newlib_basedir="${srcdir}/../../../../.." +fi + + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:956: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:977: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:995: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + + +PACKAGE=newlib + +VERSION=1.11.0 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <<EOF +#define PACKAGE "$PACKAGE" +EOF + +cat >> confdefs.h <<EOF +#define VERSION "$VERSION" +EOF + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 +echo "configure:1038: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:1051: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:1064: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:1077: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:1090: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + + +# FIXME: We temporarily define our own version of AC_PROG_CC. This is +# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We +# are probably using a cross compiler, which will not be able to fully +# link an executable. This should really be fixed in autoconf +# itself. + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1115: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1145: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1194: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1203: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1218: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + + +# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1249: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="${ac_tool_prefix}as" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="as" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1281: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" +fi +fi +AR="$ac_cv_prog_AR" +if test -n "$AR"; then + echo "$ac_t""$AR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1313: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_RANLIB"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1345: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + RANLIB=":" +fi +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1390: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 +echo "configure:1444: checking whether to enable maintainer-specific portions of Makefiles" >&5 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + + + +# We need AC_EXEEXT to keep automake happy in cygnus mode. However, +# at least currently, we never actually build a program, so we never +# need to use $(EXEEXT). Moreover, the test for EXEEXT normally +# fails, because we are probably configuring with a cross compiler +# which can't create executables. So we include AC_EXEEXT to keep +# automake happy, but we don't execute it, since we don't care about +# the result. +if false; then + + +echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +echo "configure:1478: checking for executable suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$CYGWIN" = yes || test "$MINGW32" = yes; then + ac_cv_exeext=.exe +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.$ac_ext + ac_cv_exeext= + if { (eval echo configure:1488: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + else + { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; } + fi + rm -f conftest* + test x"${ac_cv_exeext}" = x && ac_cv_exeext=no +fi +fi + +EXEEXT="" +test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext} +echo "$ac_t""${ac_cv_exeext}" 1>&6 +ac_exeext=$EXEEXT + +fi + +. ${newlib_basedir}/configure.host + +newlib_cflags="${newlib_cflags} -fno-builtin" + +NEWLIB_CFLAGS=${newlib_cflags} + + +LDFLAGS=${ldflags} + + + + +if test x${newlib_elix_level} = x0; then + ELIX_LEVEL_0_TRUE= + ELIX_LEVEL_0_FALSE='#' +else + ELIX_LEVEL_0_TRUE='#' + ELIX_LEVEL_0_FALSE= +fi + + +if test x${newlib_elix_level} = x1; then + ELIX_LEVEL_1_TRUE= + ELIX_LEVEL_1_FALSE='#' +else + ELIX_LEVEL_1_TRUE='#' + ELIX_LEVEL_1_FALSE= +fi + + +if test x${newlib_elix_level} = x2; then + ELIX_LEVEL_2_TRUE= + ELIX_LEVEL_2_FALSE='#' +else + ELIX_LEVEL_2_TRUE='#' + ELIX_LEVEL_2_FALSE= +fi + + +if test x${newlib_elix_level} = x3; then + ELIX_LEVEL_3_TRUE= + ELIX_LEVEL_3_FALSE='#' +else + ELIX_LEVEL_3_TRUE='#' + ELIX_LEVEL_3_FALSE= +fi + + +if test x${newlib_elix_level} = x4; then + ELIX_LEVEL_4_TRUE= + ELIX_LEVEL_4_FALSE='#' +else + ELIX_LEVEL_4_TRUE='#' + ELIX_LEVEL_4_FALSE= +fi + + + +if test x${use_libtool} = xyes; then + USE_LIBTOOL_TRUE= + USE_LIBTOOL_FALSE='#' +else + USE_LIBTOOL_TRUE='#' + USE_LIBTOOL_FALSE= +fi + +# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we +# use oext, which is set in configure.host based on the target platform. +OBJEXT=${oext} + + + + + + + + + + +if test "${use_libtool}" = "yes"; then + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=yes +fi + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=yes +fi + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1663: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1693: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1744: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1776: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 1787 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:1792: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1818: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1823: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1832: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1851: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 +echo "configure:1894: checking for ld used by GCC" >&5 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 +echo "configure:1924: checking for GNU ld" >&5 +else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 +echo "configure:1927: checking for non-GNU ld" >&5 +fi +if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } +echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 +echo "configure:1962: checking if the linker ($LD) is GNU ld" >&5 +if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi +fi + +echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6 +echo "configure:1979: checking for $LD option to reload object files" >&5 +if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + lt_cv_ld_reload_flag='-r' +fi + +echo "$ac_t""$lt_cv_ld_reload_flag" 1>&6 +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" + +echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 +echo "configure:1991: checking for BSD-compatible nm" >&5 +if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi + +NM="$lt_cv_path_NM" +echo "$ac_t""$NM" 1>&6 + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:2029: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6 +echo "configure:2050: checking how to recognise dependant libraries" >&5 +if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* |pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.012) + lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System' + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd* ) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + case $host_cpu in + hppa*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + esac + ;; + +irix5* | irix6*) + case $host_os in + irix5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$' + fi + ;; + +newsos6) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[78]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; +esac + +fi + +echo "$ac_t""$lt_cv_deplibs_check_method" 1>&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method + +echo $ac_n "checking for object suffix""... $ac_c" 1>&6 +echo "configure:2223: checking for object suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftest* +echo 'int i = 1;' > conftest.$ac_ext +if { (eval echo configure:2229: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + for ac_file in conftest.*; do + case $ac_file in + *.c) ;; + *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;; + esac + done +else + { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; } +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_objext" 1>&6 +OBJEXT=$ac_cv_objext +ac_objext=$ac_cv_objext + +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6 +echo "configure:2253: checking for ${ac_tool_prefix}file" >&5 +if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$ac_t""$MAGIC_CMD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo $ac_n "checking for file""... $ac_c" 1>&6 +echo "configure:2315: checking for file" >&5 +if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$ac_t""$MAGIC_CMD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2386: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_RANLIB"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2418: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + RANLIB=":" +fi +fi + +# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2453: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +STRIP="$ac_cv_prog_STRIP" +if test -n "$STRIP"; then + echo "$ac_t""$STRIP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_STRIP"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2485: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_STRIP="strip" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":" +fi +fi +STRIP="$ac_cv_prog_STRIP" +if test -n "$STRIP"; then + echo "$ac_t""$STRIP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + STRIP=":" +fi +fi + + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + +libtool_flags="$libtool_flags --enable-win32-dll" +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + : +fi + +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi + +test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic" +test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 2552 "configure"' > conftest.$ac_ext + if { (eval echo configure:2553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo configure:2572: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case "`/usr/bin/file conftest.o`" in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 +echo "configure:2590: checking whether the C compiler needs -belf" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + + cat > conftest.$ac_ext <<EOF +#line 2603 "configure" +#include "confdefs.h" + +int main() { + +; return 0; } +EOF +if { (eval echo configure:2610: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_needs_belf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_needs_belf=no +fi +rm -f conftest* + ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +fi + +echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +*-*-cygwin* | *-*-mingw* | *-*-pw32*) + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2640: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +DLLTOOL="$ac_cv_prog_DLLTOOL" +if test -n "$DLLTOOL"; then + echo "$ac_t""$DLLTOOL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_DLLTOOL"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2672: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_DLLTOOL="dlltool" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false" +fi +fi +DLLTOOL="$ac_cv_prog_DLLTOOL" +if test -n "$DLLTOOL"; then + echo "$ac_t""$DLLTOOL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + DLLTOOL="false" +fi +fi + + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2707: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="${ac_tool_prefix}as" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_AS"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2739: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="as" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + AS="false" +fi +fi + + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2774: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +OBJDUMP="$ac_cv_prog_OBJDUMP" +if test -n "$OBJDUMP"; then + echo "$ac_t""$OBJDUMP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_OBJDUMP"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2806: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_OBJDUMP="objdump" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_OBJDUMP" && ac_cv_prog_OBJDUMP="false" +fi +fi +OBJDUMP="$ac_cv_prog_OBJDUMP" +if test -n "$OBJDUMP"; then + echo "$ac_t""$OBJDUMP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + OBJDUMP="false" +fi +fi + + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + echo $ac_n "checking if libtool should supply DllMain function""... $ac_c" 1>&6 +echo "configure:2842: checking if libtool should supply DllMain function" >&5 +if eval "test \"`echo '$''{'lt_cv_need_dllmain'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2847 "configure" +#include "confdefs.h" + +int main() { +extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0); +; return 0; } +EOF +if { (eval echo configure:2855: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_need_dllmain=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_need_dllmain=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_need_dllmain" 1>&6 + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + echo $ac_n "checking how to link DLLs""... $ac_c" 1>&6 +echo "configure:2876: checking how to link DLLs" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_dll_switch'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2881 "configure" +#include "confdefs.h" + +int main() { + +; return 0; } +EOF +if { (eval echo configure:2888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_dll_switch=-mdll +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_dll_switch=-dll +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_cc_dll_switch" 1>&6 + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + +esac + + +# Save cache, so that ltconfig can load it +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \ +|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; } + +# Reload cache, that may have been modified by ltconfig +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log + + + + + + +fi + +if test -n "${machine_dir}"; then + subdirs="${machine_dir}" + +fi + + + +if test x${machine_dir} != x; then + HAVE_MACHINE_DIR_TRUE= + HAVE_MACHINE_DIR_FALSE='#' +else + HAVE_MACHINE_DIR_TRUE='#' + HAVE_MACHINE_DIR_FALSE= +fi + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@MAY_SUPPLY_SYSCALLS_TRUE@%$MAY_SUPPLY_SYSCALLS_TRUE%g +s%@MAY_SUPPLY_SYSCALLS_FALSE@%$MAY_SUPPLY_SYSCALLS_FALSE%g +s%@newlib_basedir@%$newlib_basedir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@AS@%$AS%g +s%@AR@%$AR%g +s%@RANLIB@%$RANLIB%g +s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g +s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g +s%@MAINT@%$MAINT%g +s%@EXEEXT@%$EXEEXT%g +s%@NEWLIB_CFLAGS@%$NEWLIB_CFLAGS%g +s%@ELIX_LEVEL_0_TRUE@%$ELIX_LEVEL_0_TRUE%g +s%@ELIX_LEVEL_0_FALSE@%$ELIX_LEVEL_0_FALSE%g +s%@ELIX_LEVEL_1_TRUE@%$ELIX_LEVEL_1_TRUE%g +s%@ELIX_LEVEL_1_FALSE@%$ELIX_LEVEL_1_FALSE%g +s%@ELIX_LEVEL_2_TRUE@%$ELIX_LEVEL_2_TRUE%g +s%@ELIX_LEVEL_2_FALSE@%$ELIX_LEVEL_2_FALSE%g +s%@ELIX_LEVEL_3_TRUE@%$ELIX_LEVEL_3_TRUE%g +s%@ELIX_LEVEL_3_FALSE@%$ELIX_LEVEL_3_FALSE%g +s%@ELIX_LEVEL_4_TRUE@%$ELIX_LEVEL_4_TRUE%g +s%@ELIX_LEVEL_4_FALSE@%$ELIX_LEVEL_4_FALSE%g +s%@USE_LIBTOOL_TRUE@%$USE_LIBTOOL_TRUE%g +s%@USE_LIBTOOL_FALSE@%$USE_LIBTOOL_FALSE%g +s%@OBJEXT@%$OBJEXT%g +s%@oext@%$oext%g +s%@aext@%$aext%g +s%@libm_machine_dir@%$libm_machine_dir%g +s%@machine_dir@%$machine_dir%g +s%@sys_dir@%$sys_dir%g +s%@LN_S@%$LN_S%g +s%@STRIP@%$STRIP%g +s%@DLLTOOL@%$DLLTOOL%g +s%@OBJDUMP@%$OBJDUMP%g +s%@LIBTOOL@%$LIBTOOL%g +s%@subdirs@%$subdirs%g +s%@HAVE_MACHINE_DIR_TRUE@%$HAVE_MACHINE_DIR_TRUE%g +s%@HAVE_MACHINE_DIR_FALSE@%$HAVE_MACHINE_DIR_FALSE%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + +if test "$no_recursion" != yes; then + + # Remove --cache-file and --srcdir arguments so they do not pile up. + ac_sub_configure_args= + ac_prev= + for ac_arg in $ac_configure_args; do + if test -n "$ac_prev"; then + ac_prev= + continue + fi + case "$ac_arg" in + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + ;; + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + ;; + *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; + esac + done + + for ac_config_dir in ${machine_dir}; do + + # Do not complain, so a configure script can configure whichever + # parts of a large source tree are present. + if test ! -d $srcdir/$ac_config_dir; then + continue + fi + + echo configuring in $ac_config_dir + + case "$srcdir" in + .) ;; + *) + if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :; + else + { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; } + fi + ;; + esac + + ac_popdir=`pwd` + cd $ac_config_dir + + # A "../" for each directory in /$ac_config_dir. + ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` + + case "$srcdir" in + .) # No --srcdir option. We are building in place. + ac_sub_srcdir=$srcdir ;; + /*) # Absolute path. + ac_sub_srcdir=$srcdir/$ac_config_dir ;; + *) # Relative path. + ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;; + esac + + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_sub_srcdir/configure; then + ac_sub_configure=$ac_sub_srcdir/configure + elif test -f $ac_sub_srcdir/configure.in; then + ac_sub_configure=$ac_configure + else + echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2 + ac_sub_configure= + fi + + # The recursion is here. + if test -n "$ac_sub_configure"; then + + # Make the cache file name correct relative to the subdirectory. + case "$cache_file" in + /*) ac_sub_cache_file=$cache_file ;; + *) # Relative path. + ac_sub_cache_file="$ac_dots$cache_file" ;; + esac + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir" + # The eval makes quoting arguments work. + if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir + then : + else + { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; } + fi + fi + + cd $ac_popdir + done +fi + diff --git a/newlib/libc/sys/linux/linuxthreads/machine/configure.in b/newlib/libc/sys/linux/linuxthreads/machine/configure.in new file mode 100644 index 000000000..b2a205ed7 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/configure.in @@ -0,0 +1,26 @@ +dnl This is the newlib/libc/sys configure.in file. +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.5) +AC_INIT(i386) + +dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. +AC_CONFIG_AUX_DIR(../../../../../..) + +NEWLIB_CONFIGURE(../../../../..) + +dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and +dnl add it into NEWLIB_CONFIGURE, executable tests are made before the first +dnl line of the macro which fail because appropriate LDFLAGS are not set. +if test "${use_libtool}" = "yes"; then +AC_LIBTOOL_WIN32_DLL +AM_PROG_LIBTOOL +fi + +if test -n "${machine_dir}"; then + AC_CONFIG_SUBDIRS(${machine_dir}) +fi + +AM_CONDITIONAL(HAVE_MACHINE_DIR, test x${machine_dir} != x) + +AC_OUTPUT(Makefile) diff --git a/newlib/libc/sys/linux/linuxthreads/machine/generic/generic-sysdep.h b/newlib/libc/sys/linux/linuxthreads/machine/generic/generic-sysdep.h new file mode 100644 index 000000000..27f5b6988 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/generic/generic-sysdep.h @@ -0,0 +1,46 @@ +/* Generic asm macros used on many machines. + Copyright (C) 1991, 92, 93, 96, 98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <config.h> +#include <libc-symbols.h> + +#ifndef C_LABEL + +/* Define a macro we can use to construct the asm name for a C symbol. */ +#ifdef NO_UNDERSCORES +#ifdef __STDC__ +#define C_LABEL(name) name##: +#else +#define C_LABEL(name) name/**/: +#endif +#else +#ifdef __STDC__ +#define C_LABEL(name) _##name##: +#else +#define C_LABEL(name) _/**/name/**/: +#endif +#endif + +#endif + +/* Mark the end of function named SYM. This is used on some platforms + to generate correct debugging information. */ +#ifndef END +#define END(sym) +#endif diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/Makefile.am b/newlib/libc/sys/linux/linuxthreads/machine/i386/Makefile.am new file mode 100644 index 000000000..d7271e5a6 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/Makefile.am @@ -0,0 +1,26 @@ +## Process this file with automake to generate Makefile.in + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = -I$(srcdir)/../../../include -I$(srcdir)/../.. -I$(srcdir)/../generic -I$(srcdir)/../../.. $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) + +LIB_SOURCES = clone.S i386-sysdep.S pspinlock.c sysdep.S + +liblinuxthreadsi386_la_LDFLAGS = -Xcompiler -nostdlib + +if USE_LIBTOOL +noinst_LTLIBRARIES = liblinuxthreadsi386.la +liblinuxthreadsi386_la_SOURCES = $(LIB_SOURCES) +noinst_DATA = objectlist.awk.in +else +noinst_LIBRARIES = lib.a +lib_a_SOURCES = $(LIB_SOURCES) +noinst_DATA = +endif # USE_LIBTOOL + +include $(srcdir)/../../../../../../Makefile.shared + +AM_CFLAGS = -D_XOPEN_SOURCE=600 -D_GNU_SOURCE=1 + +ACLOCAL_AMFLAGS = -I ../../../../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/Makefile.in b/newlib/libc/sys/linux/linuxthreads/machine/i386/Makefile.in new file mode 100644 index 000000000..0485e6bc8 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/Makefile.in @@ -0,0 +1,411 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AR = @AR@ +AS = @AS@ +AWK = @AWK@ +CC = @CC@ +CPP = @CPP@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DLLTOOL = @DLLTOOL@ +EXEEXT = @EXEEXT@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ +aext = @aext@ +libm_machine_dir = @libm_machine_dir@ +machine_dir = @machine_dir@ +newlib_basedir = @newlib_basedir@ +oext = @oext@ +sys_dir = @sys_dir@ + +AUTOMAKE_OPTIONS = cygnus + +INCLUDES = -I$(srcdir)/../../../include -I$(srcdir)/../.. -I$(srcdir)/../generic -I$(srcdir)/../../.. $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) + +LIB_SOURCES = clone.S i386-sysdep.S pspinlock.c sysdep.S + +liblinuxthreadsi386_la_LDFLAGS = -Xcompiler -nostdlib + +@USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = @USE_LIBTOOL_TRUE@liblinuxthreadsi386.la +@USE_LIBTOOL_TRUE@liblinuxthreadsi386_la_SOURCES = @USE_LIBTOOL_TRUE@$(LIB_SOURCES) +@USE_LIBTOOL_TRUE@noinst_DATA = @USE_LIBTOOL_TRUE@objectlist.awk.in +@USE_LIBTOOL_FALSE@noinst_DATA = +@USE_LIBTOOL_FALSE@noinst_LIBRARIES = @USE_LIBTOOL_FALSE@lib.a +@USE_LIBTOOL_FALSE@lib_a_SOURCES = @USE_LIBTOOL_FALSE@$(LIB_SOURCES) + +AM_CFLAGS = -D_XOPEN_SOURCE=600 -D_GNU_SOURCE=1 + +ACLOCAL_AMFLAGS = -I ../../../../../.. +CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../../../../mkinstalldirs +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LIBS = @LIBS@ +lib_a_LIBADD = +@USE_LIBTOOL_FALSE@lib_a_OBJECTS = clone.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@i386-sysdep.$(OBJEXT) pspinlock.$(OBJEXT) \ +@USE_LIBTOOL_FALSE@sysdep.$(OBJEXT) +LTLIBRARIES = $(noinst_LTLIBRARIES) + +liblinuxthreadsi386_la_LIBADD = +@USE_LIBTOOL_TRUE@liblinuxthreadsi386_la_OBJECTS = clone.lo \ +@USE_LIBTOOL_TRUE@i386-sysdep.lo pspinlock.lo sysdep.lo +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DATA = $(noinst_DATA) + +DIST_COMMON = Makefile.am Makefile.in aclocal.m4 configure configure.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(lib_a_SOURCES) $(liblinuxthreadsi386_la_SOURCES) +OBJECTS = $(lib_a_OBJECTS) $(liblinuxthreadsi386_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../../../../../Makefile.shared + cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in \ + ../../../../../../acinclude.m4 \ + ../../../../../../aclocal.m4 \ + ../../../../../../libtool.m4 + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +mostlyclean-noinstLIBRARIES: + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +distclean-noinstLIBRARIES: + +maintainer-clean-noinstLIBRARIES: + +.c.o: + $(COMPILE) -c $< + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) + -rm -f lib.a + $(AR) cru lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD) + $(RANLIB) lib.a + +mostlyclean-noinstLTLIBRARIES: + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + +distclean-noinstLTLIBRARIES: + +maintainer-clean-noinstLTLIBRARIES: + +liblinuxthreadsi386.la: $(liblinuxthreadsi386_la_OBJECTS) $(liblinuxthreadsi386_la_DEPENDENCIES) + $(LINK) $(liblinuxthreadsi386_la_LDFLAGS) $(liblinuxthreadsi386_la_OBJECTS) $(liblinuxthreadsi386_la_LIBADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: +check: check-am +installcheck-am: +installcheck: installcheck-am +install-info-am: +install-info: install-info-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(DATA) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-noinstLTLIBRARIES \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLIBRARIES clean-compile clean-libtool \ + clean-noinstLTLIBRARIES clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstLIBRARIES distclean-compile \ + distclean-libtool distclean-noinstLTLIBRARIES \ + distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + -rm -f config.status + +maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-noinstLTLIBRARIES \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + -rm -f config.status + +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool mostlyclean-noinstLTLIBRARIES \ +distclean-noinstLTLIBRARIES clean-noinstLTLIBRARIES \ +maintainer-clean-noinstLTLIBRARIES tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-info-am install-info \ +install-exec-am install-exec install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +objectlist.awk.in: $(noinst_LTLIBRARIES) + -rm -f objectlist.awk.in + for i in `ls *.lo` ; \ + do \ + echo $$i `pwd`/$$i >> objectlist.awk.in ; \ + done + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/aclocal.m4 b/newlib/libc/sys/linux/linuxthreads/machine/i386/aclocal.m4 new file mode 100644 index 000000000..98bba1a0b --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/aclocal.m4 @@ -0,0 +1,1191 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +dnl This provides configure definitions used by all the newlib +dnl configure.in files. + +dnl Basic newlib configury. This calls basic introductory stuff, +dnl including AM_INIT_AUTOMAKE and AC_CANONICAL_HOST. It also runs +dnl configure.host. The only argument is the relative path to the top +dnl newlib directory. + +AC_DEFUN(NEWLIB_CONFIGURE, +[ +dnl Default to --enable-multilib +AC_ARG_ENABLE(multilib, +[ --enable-multilib build many library versions (default)], +[case "${enableval}" in + yes) multilib=yes ;; + no) multilib=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for multilib option) ;; + esac], [multilib=yes])dnl + +dnl Support --enable-target-optspace +AC_ARG_ENABLE(target-optspace, +[ --enable-target-optspace optimize for space], +[case "${enableval}" in + yes) target_optspace=yes ;; + no) target_optspace=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for target-optspace option) ;; + esac], [target_optspace=])dnl + +dnl Support --enable-malloc-debugging - currently only supported for Cygwin +AC_ARG_ENABLE(malloc-debugging, +[ --enable-malloc-debugging indicate malloc debugging requested], +[case "${enableval}" in + yes) malloc_debugging=yes ;; + no) malloc_debugging=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for malloc-debugging option) ;; + esac], [malloc_debugging=])dnl + +dnl Support --enable-newlib-mb +AC_ARG_ENABLE(newlib-mb, +[ --enable-newlib-mb enable multibyte support], +[case "${enableval}" in + yes) newlib_mb=yes ;; + no) newlib_mb=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-mb option) ;; + esac], [newlib_mb=])dnl + +dnl Support --enable-newlib-multithread +AC_ARG_ENABLE(newlib-multithread, +[ --enable-newlib-multithread enable support for multiple threads], +[case "${enableval}" in + yes) newlib_multithread=yes ;; + no) newlib_multithread=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-multithread option) ;; + esac], [newlib_multithread=yes])dnl + +dnl Support --enable-newlib-elix-level +AC_ARG_ENABLE(newlib-elix-level, +[ --enable-newlib-elix-level supply desired elix library level (1-4)], +[case "${enableval}" in + 0) newlib_elix_level=0 ;; + 1) newlib_elix_level=1 ;; + 2) newlib_elix_level=2 ;; + 3) newlib_elix_level=3 ;; + 4) newlib_elix_level=4 ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-elix-level option) ;; + esac], [newlib_elix_level=0])dnl + +dnl Support --disable-newlib-io-float +AC_ARG_ENABLE(newlib-io-float, +[ --disable-newlib-io-float disable printf/scanf family float support], +[case "${enableval}" in + yes) newlib_io_float=yes ;; + no) newlib_io_float=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-io-float option) ;; + esac], [newlib_io_float=yes])dnl + +dnl Support --disable-newlib-supplied-syscalls +AC_ARG_ENABLE(newlib-supplied-syscalls, +[ --disable-newlib-supplied-syscalls disable newlib from supplying syscalls], +[case "${enableval}" in + yes) newlib_may_supply_syscalls=yes ;; + no) newlib_may_supply_syscalls=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for newlib-supplied-syscalls option) ;; + esac], [newlib_may_supply_syscalls=yes])dnl + +AM_CONDITIONAL(MAY_SUPPLY_SYSCALLS, test x[$]{newlib_may_supply_syscalls} = xyes) + +dnl We may get other options which we don't document: +dnl --with-target-subdir, --with-multisrctop, --with-multisubdir + +test -z "[$]{with_target_subdir}" && with_target_subdir=. + +if test "[$]{srcdir}" = "."; then + if test "[$]{with_target_subdir}" != "."; then + newlib_basedir="[$]{srcdir}/[$]{with_multisrctop}../$1" + else + newlib_basedir="[$]{srcdir}/[$]{with_multisrctop}$1" + fi +else + newlib_basedir="[$]{srcdir}/$1" +fi +AC_SUBST(newlib_basedir) + +AC_CANONICAL_SYSTEM + +AM_INIT_AUTOMAKE(newlib, 1.11.0) + +# FIXME: We temporarily define our own version of AC_PROG_CC. This is +# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We +# are probably using a cross compiler, which will not be able to fully +# link an executable. This should really be fixed in autoconf +# itself. + +AC_DEFUN(LIB_AC_PROG_CC, +[AC_BEFORE([$0], [AC_PROG_CPP])dnl +AC_CHECK_PROG(CC, gcc, gcc) +if test -z "$CC"; then + AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc) + test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH]) +fi + +AC_PROG_CC_GNU + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +dnl Check whether -g works, even if CFLAGS is set, in case the package +dnl plays around with CFLAGS (such as to build both debugging and +dnl normal versions of a library), tasteless as that idea is. + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + AC_PROG_CC_G + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi +]) + +LIB_AC_PROG_CC + +AC_CHECK_TOOL(AS, as) +AC_CHECK_TOOL(AR, ar) +AC_CHECK_TOOL(RANLIB, ranlib, :) + +AC_PROG_INSTALL + +AM_MAINTAINER_MODE + +# We need AC_EXEEXT to keep automake happy in cygnus mode. However, +# at least currently, we never actually build a program, so we never +# need to use $(EXEEXT). Moreover, the test for EXEEXT normally +# fails, because we are probably configuring with a cross compiler +# which can't create executables. So we include AC_EXEEXT to keep +# automake happy, but we don't execute it, since we don't care about +# the result. +if false; then + AC_EXEEXT +fi + +. [$]{newlib_basedir}/configure.host + +newlib_cflags="[$]{newlib_cflags} -fno-builtin" + +NEWLIB_CFLAGS=${newlib_cflags} +AC_SUBST(NEWLIB_CFLAGS) + +LDFLAGS=${ldflags} +AC_SUBST(LDFLAGS) + +AM_CONDITIONAL(ELIX_LEVEL_0, test x[$]{newlib_elix_level} = x0) +AM_CONDITIONAL(ELIX_LEVEL_1, test x[$]{newlib_elix_level} = x1) +AM_CONDITIONAL(ELIX_LEVEL_2, test x[$]{newlib_elix_level} = x2) +AM_CONDITIONAL(ELIX_LEVEL_3, test x[$]{newlib_elix_level} = x3) +AM_CONDITIONAL(ELIX_LEVEL_4, test x[$]{newlib_elix_level} = x4) + +AM_CONDITIONAL(USE_LIBTOOL, test x[$]{use_libtool} = xyes) + +# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we +# use oext, which is set in configure.host based on the target platform. +OBJEXT=${oext} + +AC_SUBST(OBJEXT) +AC_SUBST(oext) +AC_SUBST(aext) + +AC_SUBST(libm_machine_dir) +AC_SUBST(machine_dir) +AC_SUBST(sys_dir) +]) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + +# Define a conditional. + +AC_DEFUN(AM_CONDITIONAL, +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# serial 1 + +AC_DEFUN(AM_MAINTAINER_MODE, +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT($USE_MAINTAINER_MODE) + AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + + +# serial 46 AC_PROG_LIBTOOL +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ +])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ +])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ +])])])])])]) + +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# Save cache, so that ltconfig can load it +AC_CACHE_SAVE + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \ +|| AC_MSG_ERROR([libtool configure failed]) + +# Reload cache, that may have been modified by ltconfig +AC_CACHE_LOAD + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], +[libtool_flags="$libtool_flags --enable-dlopen"]) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[libtool_flags="$libtool_flags --enable-win32-dll"]) +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +AC_ARG_WITH(pic, + [ --with-pic try to use only PIC/non-PIC objects [default=use both]], + pic_mode="$withval", pic_mode=default) +test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic" +test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac +]) + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + re_direlt=['/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependant libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'] + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* |pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[012]) + lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System' + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd* ) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method=['file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + case $host_cpu in + hppa*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + ia64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + esac + ;; + +irix5* | irix6*) + case $host_os in + irix5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method=["file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"] + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'] ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'] + else + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'] + fi + ;; + +newsos6) + [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +[sysv5uw[78]* | sysv4*uw2*)] + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + motorola) + lt_cv_deplibs_check_method=['file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'] + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and INCLTDL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and INCLTDL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + INCLTDL= + fi +]) + +# If this macro is not defined by Autoconf, define it here. +ifdef([AC_PROVIDE_IFELSE], + [], + [define([AC_PROVIDE_IFELSE], + [ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + +# AC_LIBTOOL_CXX - enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], [AC_REQUIRE([_AC_LIBTOOL_CXX])]) + +AC_DEFUN([_AC_LIBTOOL_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([AC_PROG_CXXCPP]) +LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-cxx.sh" +lt_save_CC="$CC" +lt_save_CFLAGS="$CFLAGS" +dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC +dnl is set to the C++ compiler. +AR="$AR" LTCC="$CC" CC="$CXX" CXX="$CXX" CFLAGS="$CXXFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" \ +file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \ +--build="$build" --add-tag=CXX $ac_aux_dir/ltcf-cxx.sh $host \ +|| AC_MSG_ERROR([libtool tag configuration failed]) +CC="$lt_save_CC" +CFLAGS="$lt_save_CFLAGS" + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +# AC_LIBTOOL_GCJ - enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ],[AC_REQUIRE([_AC_LIBTOOL_GCJ])]) + +AC_DEFUN([_AC_LIBTOOL_GCJ], +[AC_REQUIRE([AC_PROG_LIBTOOL]) +AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-gcj.sh" +lt_save_CC="$CC" +lt_save_CFLAGS="$CFLAGS" +dnl Make sure LTCC is set to the C compiler, i.e. set LTCC before CC +dnl is set to the C++ compiler. +AR="$AR" LTCC="$CC" CC="$GCJ" CFLAGS="$GCJFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" \ +file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \ +--build="$build" --add-tag=GCJ $ac_aux_dir/ltcf-gcj.sh $host \ +|| AC_MSG_ERROR([libtool tag configuration failed]) +CC="$lt_save_CC" +CFLAGS="$lt_save_CFLAGS" + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +dnl old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +dnl This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL])dnl + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/bp-asm.h b/newlib/libc/sys/linux/linuxthreads/machine/i386/bp-asm.h new file mode 100644 index 000000000..34d5227a6 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/bp-asm.h @@ -0,0 +1,144 @@ +/* Bounded-pointer definitions for x86 assembler. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Greg McGary <greg@mcgary.org> + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in the GNU MP Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _bp_asm_h_ +# define _bp_asm_h_ 1 + +# if __ASSEMBLER__ + +# if __BOUNDED_POINTERS__ + +/* Bounded pointers occupy three words. */ +# define PTR_SIZE 12 +/* Bounded pointer return values are passed back through a hidden + argument that points to caller-allocate space. The hidden arg + occupies one word on the stack. */ +# define RTN_SIZE 4 +/* Although the caller pushes the hidden arg, the callee is + responsible for popping it. */ +# define RET_PTR ret $RTN_SIZE +/* Maintain frame pointer chain in leaf assembler functions for the benefit + of debugging stack traces when bounds violations occur. */ +# define ENTER pushl %ebp; movl %esp, %ebp +# define LEAVE movl %ebp, %esp; popl %ebp +/* Stack space overhead of procedure-call linkage: return address and + frame pointer. */ +# define LINKAGE 8 +/* Stack offset of return address after calling ENTER. */ +# define PCOFF 4 + +/* Int 5 is the "bound range" exception also raised by the "bound" + instruction. */ +# define BOUNDS_VIOLATED int $5 + +# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM) \ + cmpl 4+BP_MEM, VAL_REG; \ + jae 0f; /* continue if value >= low */ \ + BOUNDS_VIOLATED; \ + 0: + +# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc) \ + cmpl 8+BP_MEM, VAL_REG; \ + Jcc 0f; /* continue if value < high */ \ + BOUNDS_VIOLATED; \ + 0: + +# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM) \ + cmpl 4+BP_MEM, VAL_REG; \ + jb 1f; /* die if value < low */ \ + cmpl 8+BP_MEM, VAL_REG; \ + jb 0f; /* continue if value < high */ \ + 1: BOUNDS_VIOLATED; \ + 0: + +# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) \ + CHECK_BOUNDS_LOW(VAL_REG, BP_MEM); \ + addl LENGTH, VAL_REG; \ + cmpl 8+BP_MEM, VAL_REG; \ + jbe 0f; /* continue if value <= high */ \ + BOUNDS_VIOLATED; \ + 0: subl LENGTH, VAL_REG /* restore value */ + +/* Take bounds from BP_MEM and affix them to the pointer + value in %eax, stuffing all into memory at RTN(%esp). + Use %edx as a scratch register. */ + +# define RETURN_BOUNDED_POINTER(BP_MEM) \ + movl RTN(%esp), %edx; \ + movl %eax, 0(%edx); \ + movl 4+BP_MEM, %eax; \ + movl %eax, 4(%edx); \ + movl 8+BP_MEM, %eax; \ + movl %eax, 8(%edx) + +# define RETURN_NULL_BOUNDED_POINTER \ + movl RTN(%esp), %edx; \ + movl %eax, 0(%edx); \ + movl %eax, 4(%edx); \ + movl %eax, 8(%edx) + +/* The caller of __errno_location is responsible for allocating space + for the three-word BP return-value and passing pushing its address + as an implicit first argument. */ +# define PUSH_ERRNO_LOCATION_RETURN \ + subl $8, %esp; \ + subl $4, %esp; \ + pushl %esp + +/* __errno_location is responsible for popping the implicit first + argument, but we must pop the space for the BP itself. We also + dereference the return value in order to dig out the pointer value. */ +# define POP_ERRNO_LOCATION_RETURN \ + popl %eax; \ + addl $8, %esp + +# else /* !__BOUNDED_POINTERS__ */ + +/* Unbounded pointers occupy one word. */ +# define PTR_SIZE 4 +/* Unbounded pointer return values are passed back in the register %eax. */ +# define RTN_SIZE 0 +/* Use simple return instruction for unbounded pointer values. */ +# define RET_PTR ret +/* Don't maintain frame pointer chain for leaf assembler functions. */ +# define ENTER +# define LEAVE +/* Stack space overhead of procedure-call linkage: return address only. */ +# define LINKAGE 4 +/* Stack offset of return address after calling ENTER. */ +# define PCOFF 0 + +# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM) +# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc) +# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM) +# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) +# define RETURN_BOUNDED_POINTER(BP_MEM) + +# define RETURN_NULL_BOUNDED_POINTER + +# define PUSH_ERRNO_LOCATION_RETURN +# define POP_ERRNO_LOCATION_RETURN + +# endif /* !__BOUNDED_POINTERS__ */ + +# endif /* __ASSEMBLER__ */ + +#endif /* _bp_asm_h_ */ diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/clone.S b/newlib/libc/sys/linux/linuxthreads/machine/i386/clone.S new file mode 100644 index 000000000..dd00c2fb5 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/clone.S @@ -0,0 +1,95 @@ +/* Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson (rth@tamu.edu) + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* clone() is even more special than fork() as it mucks with stacks + and invokes a function in the right context after its all over. */ + +#include <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> +#include <asm/unistd.h> +#include <bp-sym.h> +#include <bp-asm.h> + +/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */ + +#define PARMS LINKAGE /* no space for saved regs */ +#define FUNC PARMS +#define STACK FUNC+4 +#define FLAGS STACK+PTR_SIZE +#define ARG FLAGS+4 + + .text +ENTRY (BP_SYM (__clone)) + /* Sanity check arguments. */ + movl $-EINVAL,%eax + movl FUNC(%esp),%ecx /* no NULL function pointers */ +#ifdef PIC + jecxz SYSCALL_ERROR_LABEL +#else + testl %ecx,%ecx + jz SYSCALL_ERROR_LABEL +#endif + movl STACK(%esp),%ecx /* no NULL stack pointers */ +#ifdef PIC + jecxz SYSCALL_ERROR_LABEL +#else + testl %ecx,%ecx + jz SYSCALL_ERROR_LABEL +#endif + + /* Insert the argument onto the new stack. */ + subl $8,%ecx + movl ARG(%esp),%eax /* no negative argument counts */ + movl %eax,4(%ecx) + + /* Save the function pointer as the zeroth argument. + It will be popped off in the child in the ebx frobbing below. */ + movl FUNC(%esp),%eax + movl %eax,0(%ecx) + + /* Do the system call */ + pushl %ebx + movl FLAGS+4(%esp),%ebx + movl $SYS_ify(clone),%eax + int $0x80 + popl %ebx + + test %eax,%eax + jl SYSCALL_ERROR_LABEL + jz thread_start + +L(pseudo_end): + ret + +thread_start: + subl %ebp,%ebp /* terminate the stack frame */ + call *%ebx +#ifdef PIC + call L(here) +L(here): + popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebx +#endif + pushl %eax + call JUMPTARGET (_exit) + +PSEUDO_END (BP_SYM (__clone)) + +weak_alias (BP_SYM (__clone), BP_SYM (clone)) diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/configure b/newlib/libc/sys/linux/linuxthreads/machine/i386/configure new file mode 100755 index 000000000..310e8b3aa --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/configure @@ -0,0 +1,3351 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --enable-multilib build many library versions (default)" +ac_help="$ac_help + --enable-target-optspace optimize for space" +ac_help="$ac_help + --enable-malloc-debugging indicate malloc debugging requested" +ac_help="$ac_help + --enable-newlib-mb enable multibyte support" +ac_help="$ac_help + --enable-newlib-multithread enable support for multiple threads" +ac_help="$ac_help + --enable-newlib-elix-level supply desired elix library level (1-4)" +ac_help="$ac_help + --disable-newlib-io-float disable printf/scanf family float support" +ac_help="$ac_help + --disable-newlib-supplied-syscalls disable newlib from supplying syscalls" +ac_help="$ac_help + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer" +ac_help="$ac_help + --enable-shared[=PKGS] build shared libraries [default=yes]" +ac_help="$ac_help + --enable-static[=PKGS] build static libraries [default=yes]" +ac_help="$ac_help + --enable-fast-install[=PKGS] optimize for fast installation [default=yes]" +ac_help="$ac_help + --with-gnu-ld assume the C compiler uses GNU ld [default=no]" +ac_help="$ac_help + --disable-libtool-lock avoid locking (might break parallel builds)" +ac_help="$ac_help + --with-pic try to use only PIC/non-PIC objects [default=use both]" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +sitefile= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --site-file=FILE use FILE as the site file + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -site-file | --site-file | --site-fil | --site-fi | --site-f) + ac_prev=sitefile ;; + -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*) + sitefile="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=pspinlock.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$sitefile"; then + if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi + fi +else + CONFIG_SITE="$sitefile" +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in ../../../../../../.. $srcdir/../../../../../../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in ../../../../../../.. $srcdir/../../../../../../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:600: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:653: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:710: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +if test $host != $build; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 +echo "configure:743: checking for Cygwin environment" >&5 +if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 748 "configure" +#include "confdefs.h" + +int main() { + +#ifndef __CYGWIN__ +#define __CYGWIN__ __CYGWIN32__ +#endif +return __CYGWIN__; +; return 0; } +EOF +if { (eval echo configure:759: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_cygwin=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_cygwin=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_cygwin" 1>&6 +CYGWIN= +test "$ac_cv_cygwin" = yes && CYGWIN=yes +echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 +echo "configure:776: checking for mingw32 environment" >&5 +if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 781 "configure" +#include "confdefs.h" + +int main() { +return __MINGW32__; +; return 0; } +EOF +if { (eval echo configure:788: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_mingw32=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_mingw32=no +fi +rm -f conftest* +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_mingw32" 1>&6 +MINGW32= +test "$ac_cv_mingw32" = yes && MINGW32=yes + +# Check whether --enable-multilib or --disable-multilib was given. +if test "${enable_multilib+set}" = set; then + enableval="$enable_multilib" + case "${enableval}" in + yes) multilib=yes ;; + no) multilib=no ;; + *) { echo "configure: error: bad value ${enableval} for multilib option" 1>&2; exit 1; } ;; + esac +else + multilib=yes +fi + +# Check whether --enable-target-optspace or --disable-target-optspace was given. +if test "${enable_target_optspace+set}" = set; then + enableval="$enable_target_optspace" + case "${enableval}" in + yes) target_optspace=yes ;; + no) target_optspace=no ;; + *) { echo "configure: error: bad value ${enableval} for target-optspace option" 1>&2; exit 1; } ;; + esac +else + target_optspace= +fi + +# Check whether --enable-malloc-debugging or --disable-malloc-debugging was given. +if test "${enable_malloc_debugging+set}" = set; then + enableval="$enable_malloc_debugging" + case "${enableval}" in + yes) malloc_debugging=yes ;; + no) malloc_debugging=no ;; + *) { echo "configure: error: bad value ${enableval} for malloc-debugging option" 1>&2; exit 1; } ;; + esac +else + malloc_debugging= +fi + +# Check whether --enable-newlib-mb or --disable-newlib-mb was given. +if test "${enable_newlib_mb+set}" = set; then + enableval="$enable_newlib_mb" + case "${enableval}" in + yes) newlib_mb=yes ;; + no) newlib_mb=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-mb option" 1>&2; exit 1; } ;; + esac +else + newlib_mb= +fi + +# Check whether --enable-newlib-multithread or --disable-newlib-multithread was given. +if test "${enable_newlib_multithread+set}" = set; then + enableval="$enable_newlib_multithread" + case "${enableval}" in + yes) newlib_multithread=yes ;; + no) newlib_multithread=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-multithread option" 1>&2; exit 1; } ;; + esac +else + newlib_multithread=yes +fi + +# Check whether --enable-newlib-elix-level or --disable-newlib-elix-level was given. +if test "${enable_newlib_elix_level+set}" = set; then + enableval="$enable_newlib_elix_level" + case "${enableval}" in + 0) newlib_elix_level=0 ;; + 1) newlib_elix_level=1 ;; + 2) newlib_elix_level=2 ;; + 3) newlib_elix_level=3 ;; + 4) newlib_elix_level=4 ;; + *) { echo "configure: error: bad value ${enableval} for newlib-elix-level option" 1>&2; exit 1; } ;; + esac +else + newlib_elix_level=0 +fi + +# Check whether --enable-newlib-io-float or --disable-newlib-io-float was given. +if test "${enable_newlib_io_float+set}" = set; then + enableval="$enable_newlib_io_float" + case "${enableval}" in + yes) newlib_io_float=yes ;; + no) newlib_io_float=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-io-float option" 1>&2; exit 1; } ;; + esac +else + newlib_io_float=yes +fi + +# Check whether --enable-newlib-supplied-syscalls or --disable-newlib-supplied-syscalls was given. +if test "${enable_newlib_supplied_syscalls+set}" = set; then + enableval="$enable_newlib_supplied_syscalls" + case "${enableval}" in + yes) newlib_may_supply_syscalls=yes ;; + no) newlib_may_supply_syscalls=no ;; + *) { echo "configure: error: bad value ${enableval} for newlib-supplied-syscalls option" 1>&2; exit 1; } ;; + esac +else + newlib_may_supply_syscalls=yes +fi + + + +if test x${newlib_may_supply_syscalls} = xyes; then + MAY_SUPPLY_SYSCALLS_TRUE= + MAY_SUPPLY_SYSCALLS_FALSE='#' +else + MAY_SUPPLY_SYSCALLS_TRUE='#' + MAY_SUPPLY_SYSCALLS_FALSE= +fi + + +test -z "${with_target_subdir}" && with_target_subdir=. + +if test "${srcdir}" = "."; then + if test "${with_target_subdir}" != "."; then + newlib_basedir="${srcdir}/${with_multisrctop}../../../../../../.." + else + newlib_basedir="${srcdir}/${with_multisrctop}../../../../../.." + fi +else + newlib_basedir="${srcdir}/../../../../../.." +fi + + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:956: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:977: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:995: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + + +PACKAGE=newlib + +VERSION=1.11.0 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <<EOF +#define PACKAGE "$PACKAGE" +EOF + +cat >> confdefs.h <<EOF +#define VERSION "$VERSION" +EOF + + + +missing_dir=`cd $ac_aux_dir && pwd` +echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 +echo "configure:1038: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:1051: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:1064: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:1077: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:1090: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + + +# FIXME: We temporarily define our own version of AC_PROG_CC. This is +# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We +# are probably using a cross compiler, which will not be able to fully +# link an executable. This should really be fixed in autoconf +# itself. + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1115: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1145: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1194: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1203: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes + ac_test_CFLAGS="${CFLAGS+set}" + ac_save_CFLAGS="$CFLAGS" + CFLAGS= + echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1218: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 + if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" + elif test $ac_cv_prog_cc_g = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-O2" + fi +else + GCC= + test "${CFLAGS+set}" = set || CFLAGS="-g" +fi + + +# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1249: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="${ac_tool_prefix}as" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="as" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1281: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" +fi +fi +AR="$ac_cv_prog_AR" +if test -n "$AR"; then + echo "$ac_t""$AR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + +# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1313: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_RANLIB"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1345: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + RANLIB=":" +fi +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1390: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 +echo "configure:1444: checking whether to enable maintainer-specific portions of Makefiles" >&5 + # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval="$enable_maintainer_mode" + USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + MAINT=$MAINTAINER_MODE_TRUE + + + +# We need AC_EXEEXT to keep automake happy in cygnus mode. However, +# at least currently, we never actually build a program, so we never +# need to use $(EXEEXT). Moreover, the test for EXEEXT normally +# fails, because we are probably configuring with a cross compiler +# which can't create executables. So we include AC_EXEEXT to keep +# automake happy, but we don't execute it, since we don't care about +# the result. +if false; then + + +echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 +echo "configure:1478: checking for executable suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$CYGWIN" = yes || test "$MINGW32" = yes; then + ac_cv_exeext=.exe +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.$ac_ext + ac_cv_exeext= + if { (eval echo configure:1488: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + else + { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; } + fi + rm -f conftest* + test x"${ac_cv_exeext}" = x && ac_cv_exeext=no +fi +fi + +EXEEXT="" +test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext} +echo "$ac_t""${ac_cv_exeext}" 1>&6 +ac_exeext=$EXEEXT + +fi + +. ${newlib_basedir}/configure.host + +newlib_cflags="${newlib_cflags} -fno-builtin" + +NEWLIB_CFLAGS=${newlib_cflags} + + +LDFLAGS=${ldflags} + + + + +if test x${newlib_elix_level} = x0; then + ELIX_LEVEL_0_TRUE= + ELIX_LEVEL_0_FALSE='#' +else + ELIX_LEVEL_0_TRUE='#' + ELIX_LEVEL_0_FALSE= +fi + + +if test x${newlib_elix_level} = x1; then + ELIX_LEVEL_1_TRUE= + ELIX_LEVEL_1_FALSE='#' +else + ELIX_LEVEL_1_TRUE='#' + ELIX_LEVEL_1_FALSE= +fi + + +if test x${newlib_elix_level} = x2; then + ELIX_LEVEL_2_TRUE= + ELIX_LEVEL_2_FALSE='#' +else + ELIX_LEVEL_2_TRUE='#' + ELIX_LEVEL_2_FALSE= +fi + + +if test x${newlib_elix_level} = x3; then + ELIX_LEVEL_3_TRUE= + ELIX_LEVEL_3_FALSE='#' +else + ELIX_LEVEL_3_TRUE='#' + ELIX_LEVEL_3_FALSE= +fi + + +if test x${newlib_elix_level} = x4; then + ELIX_LEVEL_4_TRUE= + ELIX_LEVEL_4_FALSE='#' +else + ELIX_LEVEL_4_TRUE='#' + ELIX_LEVEL_4_FALSE= +fi + + + +if test x${use_libtool} = xyes; then + USE_LIBTOOL_TRUE= + USE_LIBTOOL_FALSE='#' +else + USE_LIBTOOL_TRUE='#' + USE_LIBTOOL_FALSE= +fi + +# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we +# use oext, which is set in configure.host based on the target platform. +OBJEXT=${oext} + + + + + + + + + + + +if test "${use_libtool}" = "yes"; then + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case $enableval in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=yes +fi + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case $enableval in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=yes +fi + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case $enableval in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1664: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1694: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1745: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1777: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 1788 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:1793: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1819: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1824: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<EOF +#ifdef __GNUC__ + yes; +#endif +EOF +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1833: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1852: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 +echo "configure:1895: checking for ld used by GCC" >&5 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 +echo "configure:1925: checking for GNU ld" >&5 +else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 +echo "configure:1928: checking for non-GNU ld" >&5 +fi +if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$lt_cv_path_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } +echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 +echo "configure:1963: checking if the linker ($LD) is GNU ld" >&5 +if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi +fi + +echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6 +with_gnu_ld=$lt_cv_prog_gnu_ld + + +echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6 +echo "configure:1980: checking for $LD option to reload object files" >&5 +if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + lt_cv_ld_reload_flag='-r' +fi + +echo "$ac_t""$lt_cv_ld_reload_flag" 1>&6 +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" + +echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 +echo "configure:1992: checking for BSD-compatible nm" >&5 +if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi +fi + +NM="$lt_cv_path_NM" +echo "$ac_t""$NM" 1>&6 + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:2030: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6 +echo "configure:2051: checking how to recognise dependant libraries" >&5 +if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* |pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.012) + lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System' + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd* ) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + case $host_cpu in + hppa*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + esac + ;; + +irix5* | irix6*) + case $host_os in + irix5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$' + fi + ;; + +newsos6) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +sysv5uw[78]* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; +esac + +fi + +echo "$ac_t""$lt_cv_deplibs_check_method" 1>&6 +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method + +echo $ac_n "checking for object suffix""... $ac_c" 1>&6 +echo "configure:2224: checking for object suffix" >&5 +if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftest* +echo 'int i = 1;' > conftest.$ac_ext +if { (eval echo configure:2230: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + for ac_file in conftest.*; do + case $ac_file in + *.c) ;; + *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;; + esac + done +else + { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; } +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_objext" 1>&6 +OBJEXT=$ac_cv_objext +ac_objext=$ac_cv_objext + +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6 +echo "configure:2254: checking for ${ac_tool_prefix}file" >&5 +if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$ac_t""$MAGIC_CMD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + echo $ac_n "checking for file""... $ac_c" 1>&6 +echo "configure:2316: checking for file" >&5 +if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="/usr/bin:$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + echo "$ac_t""$MAGIC_CMD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2387: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_RANLIB"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2419: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + RANLIB=":" +fi +fi + +# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2454: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +STRIP="$ac_cv_prog_STRIP" +if test -n "$STRIP"; then + echo "$ac_t""$STRIP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_STRIP"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2486: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_STRIP="strip" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":" +fi +fi +STRIP="$ac_cv_prog_STRIP" +if test -n "$STRIP"; then + echo "$ac_t""$STRIP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + STRIP=":" +fi +fi + + +# Check for any special flags to pass to ltconfig. +libtool_flags="--cache-file=$cache_file" +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + +libtool_flags="$libtool_flags --enable-win32-dll" +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + : +fi + +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Check whether --with-pic or --without-pic was given. +if test "${with_pic+set}" = set; then + withval="$with_pic" + pic_mode="$withval" +else + pic_mode=default +fi + +test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic" +test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 2553 "configure"' > conftest.$ac_ext + if { (eval echo configure:2554: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo configure:2573: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case "`/usr/bin/file conftest.o`" in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 +echo "configure:2591: checking whether the C compiler needs -belf" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + + ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + + cat > conftest.$ac_ext <<EOF +#line 2604 "configure" +#include "confdefs.h" + +int main() { + +; return 0; } +EOF +if { (eval echo configure:2611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_needs_belf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_needs_belf=no +fi +rm -f conftest* + ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +fi + +echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +*-*-cygwin* | *-*-mingw* | *-*-pw32*) + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2641: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +DLLTOOL="$ac_cv_prog_DLLTOOL" +if test -n "$DLLTOOL"; then + echo "$ac_t""$DLLTOOL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_DLLTOOL"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2673: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_DLLTOOL="dlltool" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_DLLTOOL" && ac_cv_prog_DLLTOOL="false" +fi +fi +DLLTOOL="$ac_cv_prog_DLLTOOL" +if test -n "$DLLTOOL"; then + echo "$ac_t""$DLLTOOL" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + DLLTOOL="false" +fi +fi + + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2708: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="${ac_tool_prefix}as" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_AS"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2740: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AS="as" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="false" +fi +fi +AS="$ac_cv_prog_AS" +if test -n "$AS"; then + echo "$ac_t""$AS" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + AS="false" +fi +fi + + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2775: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +OBJDUMP="$ac_cv_prog_OBJDUMP" +if test -n "$OBJDUMP"; then + echo "$ac_t""$OBJDUMP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_OBJDUMP"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:2807: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_OBJDUMP="objdump" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_OBJDUMP" && ac_cv_prog_OBJDUMP="false" +fi +fi +OBJDUMP="$ac_cv_prog_OBJDUMP" +if test -n "$OBJDUMP"; then + echo "$ac_t""$OBJDUMP" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + OBJDUMP="false" +fi +fi + + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + echo $ac_n "checking if libtool should supply DllMain function""... $ac_c" 1>&6 +echo "configure:2843: checking if libtool should supply DllMain function" >&5 +if eval "test \"`echo '$''{'lt_cv_need_dllmain'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2848 "configure" +#include "confdefs.h" + +int main() { +extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0); +; return 0; } +EOF +if { (eval echo configure:2856: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_need_dllmain=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_need_dllmain=yes +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_need_dllmain" 1>&6 + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + echo $ac_n "checking how to link DLLs""... $ac_c" 1>&6 +echo "configure:2877: checking how to link DLLs" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_dll_switch'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 2882 "configure" +#include "confdefs.h" + +int main() { + +; return 0; } +EOF +if { (eval echo configure:2889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_dll_switch=-mdll +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_dll_switch=-dll +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_cc_dll_switch" 1>&6 + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + +esac + + +# Save cache, so that ltconfig can load it +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \ +AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \ +objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \ +deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \ +|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; } + +# Reload cache, that may have been modified by ltconfig +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log + + + + + + +for ac_prog in mawk gawk nawk awk +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:3003: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AWK="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AWK="$ac_cv_prog_AWK" +if test -n "$AWK"; then + echo "$ac_t""$AWK" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$AWK" && break +done + +fi + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS <<EOF +#! /bin/sh +# Generated automatically by configure. +# Run this file to recreate the current configuration. +# This directory was configured as follows, +# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS <<EOF + +# Protect against being on the right side of a sed subst in config.status. +sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; + s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@MAY_SUPPLY_SYSCALLS_TRUE@%$MAY_SUPPLY_SYSCALLS_TRUE%g +s%@MAY_SUPPLY_SYSCALLS_FALSE@%$MAY_SUPPLY_SYSCALLS_FALSE%g +s%@newlib_basedir@%$newlib_basedir%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@AS@%$AS%g +s%@AR@%$AR%g +s%@RANLIB@%$RANLIB%g +s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g +s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g +s%@MAINT@%$MAINT%g +s%@EXEEXT@%$EXEEXT%g +s%@NEWLIB_CFLAGS@%$NEWLIB_CFLAGS%g +s%@ELIX_LEVEL_0_TRUE@%$ELIX_LEVEL_0_TRUE%g +s%@ELIX_LEVEL_0_FALSE@%$ELIX_LEVEL_0_FALSE%g +s%@ELIX_LEVEL_1_TRUE@%$ELIX_LEVEL_1_TRUE%g +s%@ELIX_LEVEL_1_FALSE@%$ELIX_LEVEL_1_FALSE%g +s%@ELIX_LEVEL_2_TRUE@%$ELIX_LEVEL_2_TRUE%g +s%@ELIX_LEVEL_2_FALSE@%$ELIX_LEVEL_2_FALSE%g +s%@ELIX_LEVEL_3_TRUE@%$ELIX_LEVEL_3_TRUE%g +s%@ELIX_LEVEL_3_FALSE@%$ELIX_LEVEL_3_FALSE%g +s%@ELIX_LEVEL_4_TRUE@%$ELIX_LEVEL_4_TRUE%g +s%@ELIX_LEVEL_4_FALSE@%$ELIX_LEVEL_4_FALSE%g +s%@USE_LIBTOOL_TRUE@%$USE_LIBTOOL_TRUE%g +s%@USE_LIBTOOL_FALSE@%$USE_LIBTOOL_FALSE%g +s%@OBJEXT@%$OBJEXT%g +s%@oext@%$oext%g +s%@aext@%$aext%g +s%@libm_machine_dir@%$libm_machine_dir%g +s%@machine_dir@%$machine_dir%g +s%@sys_dir@%$sys_dir%g +s%@LN_S@%$LN_S%g +s%@STRIP@%$STRIP%g +s%@DLLTOOL@%$DLLTOOL%g +s%@OBJDUMP@%$OBJDUMP%g +s%@LIBTOOL@%$LIBTOOL%g +s%@AWK@%$AWK%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <<EOF + +CONFIG_FILES=\${CONFIG_FILES-"Makefile"} +EOF +cat >> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <<EOF + +EOF +cat >> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/configure.in b/newlib/libc/sys/linux/linuxthreads/machine/i386/configure.in new file mode 100644 index 000000000..bdf1a587f --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/configure.in @@ -0,0 +1,22 @@ +dnl This is the newlib/libc/sys/linux/linuxthreads/machine/i386 configure file. +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.5) +AC_INIT(pspinlock.c) + +dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake. +AC_CONFIG_AUX_DIR(../../../../../../..) + +NEWLIB_CONFIGURE(../../../../../..) + +dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and +dnl add it into NEWLIB_CONFIGURE, executable tests are made before the first +dnl line of the macro which fail because appropriate LDFLAGS are not set. + +if test "${use_libtool}" = "yes"; then +AC_LIBTOOL_WIN32_DLL +AM_PROG_LIBTOOL +AC_PROG_AWK +fi + +AC_OUTPUT(Makefile) diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.S b/newlib/libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.S new file mode 100644 index 000000000..aec21c0f5 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.S @@ -0,0 +1,60 @@ +/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 2000 Free Software Foundation, Inc. + This file has been modified from the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#define _ERRNO_H +#include <bits/errno.h> +#include <bp-asm.h> +#include <bp-sym.h> + +.globl __syscall_error + +__syscall_error: +#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN + /* We translate the system's EWOULDBLOCK error into EAGAIN. + The GNU C library always defines EWOULDBLOCK==EAGAIN. + EWOULDBLOCK_sys is the original number. */ + cmpl $EWOULDBLOCK_sys, %eax /* Is it the old EWOULDBLOCK? */ + jne notb /* Branch if not. */ + movl $EAGAIN, %eax /* Yes; translate it to EAGAIN. */ +notb: +#endif +#ifndef PIC + pushl %eax + PUSH_ERRNO_LOCATION_RETURN + call BP_SYM (__errno) + POP_ERRNO_LOCATION_RETURN + popl %ecx + movl %ecx, (%eax) +#else + /* The caller has pushed %ebx and then set it up to + point to the GOT before calling us through the PLT. */ + pushl %eax + PUSH_ERRNO_LOCATION_RETURN + call C_SYMBOL_NAME (BP_SYM (__errno)@PLT) + POP_ERRNO_LOCATION_RETURN + popl %ecx + /* Pop %ebx value saved before jumping here. */ + popl %ebx + movl %ecx, (%eax) +#endif + movl $-1, %eax + ret + +#undef __syscall_error +END (__syscall_error) diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.h b/newlib/libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.h new file mode 100644 index 000000000..02b4c19af --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.h @@ -0,0 +1,130 @@ +/* Assembler macros for i386. + Copyright (C) 1991, 92, 93, 95, 96, 98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define NO_UNDERSCORES + +#include <generic-sysdep.h> + +#ifdef __ASSEMBLER__ + +/* Syntactic details of assembler. */ + +#ifdef HAVE_ELF + +/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ +#define ALIGNARG(log2) 1<<log2 +/* For ELF we need the `.type' directive to make shared libs work right. */ +#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg; +#define ASM_SIZE_DIRECTIVE(name) .size name,.-name; + +/* In ELF C symbols are asm symbols. */ +#undef NO_UNDERSCORES +#define NO_UNDERSCORES + +#else + +#define ALIGNARG(log2) log2 +#define ASM_TYPE_DIRECTIVE(name,type) /* Nothing is specified. */ +#define ASM_SIZE_DIRECTIVE(name) /* Nothing is specified. */ + +#endif + + +/* Define an entry point visible from C. + + There is currently a bug in gdb which prevents us from specifying + incomplete stabs information. Fake some entries here which specify + the current source file. */ +#define ENTRY(name) \ + STABS_CURRENT_FILE1("") \ + STABS_CURRENT_FILE(name) \ + ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ + .align ALIGNARG(4); \ + STABS_FUN(name) \ + C_LABEL(name) \ + CALL_MCOUNT + +#undef END +#define END(name) \ + ASM_SIZE_DIRECTIVE(name) \ + STABS_FUN_END(name) + +/* Remove the following two lines once the gdb bug is fixed. */ +#define STABS_CURRENT_FILE(name) \ + STABS_CURRENT_FILE1 (#name) +#define STABS_CURRENT_FILE1(name) \ + 1: .stabs name,100,0,0,1b; +/* Emit stabs definition lines. We use F(0,1) and define t(0,1) as `int', + the same way gcc does it. */ +#define STABS_FUN(name) STABS_FUN2(name, name##:F(0,1)) +#define STABS_FUN2(name, namestr) \ + .stabs "int:t(0,1)=r(0,1);-2147483648;2147483647;",128,0,0,0; \ + .stabs #namestr,36,0,0,name; +#define STABS_FUN_END(name) \ + 1: .stabs "",36,0,0,1b-name; + +/* If compiled for profiling, call `mcount' at the start of each function. */ +#ifdef PROF +/* The mcount code relies on a normal frame pointer being on the stack + to locate our caller, so push one just for its benefit. */ +#define CALL_MCOUNT \ + pushl %ebp; movl %esp, %ebp; call JUMPTARGET(mcount); popl %ebp; +#else +#define CALL_MCOUNT /* Do nothing. */ +#endif + +#ifdef NO_UNDERSCORES +/* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +#define syscall_error __syscall_error +#define mcount _mcount +#endif + +#define PSEUDO(name, syscall_name, args) \ +lose: SYSCALL_PIC_SETUP \ + jmp JUMPTARGET(syscall_error) \ + .globl syscall_error; \ + ENTRY (name) \ + DO_CALL (syscall_name, args); \ + jb lose + +#undef PSEUDO_END +#define PSEUDO_END(name) \ + END (name) + +#ifdef PIC +#define JUMPTARGET(name) name##@PLT +#define SYSCALL_PIC_SETUP \ + pushl %ebx; \ + call 0f; \ +0: popl %ebx; \ + addl $_GLOBAL_OFFSET_TABLE+[.-0b], %ebx; +#else +#define JUMPTARGET(name) name +#define SYSCALL_PIC_SETUP /* Nothing. */ +#endif + +/* Local label name for asm code. */ +#ifndef L +#define L(name) name +#endif + +#endif /* __ASSEMBLER__ */ diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/pspinlock.c b/newlib/libc/sys/linux/linuxthreads/machine/i386/pspinlock.c new file mode 100644 index 000000000..5d242388a --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/pspinlock.c @@ -0,0 +1,97 @@ +/* POSIX spinlock implementation. x86 version. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <pthread.h> +#include "internals.h" + +/* This implementation is similar to the one used in the Linux kernel. + But the kernel is byte instructions for the memory access. This is + faster but unusable here. The problem is that only 128 + threads/processes could use the spinlock at the same time. If (by + a design error in the program) a thread/process would hold the + spinlock for a time long enough to accumulate 128 waiting + processes, the next one will find a positive value in the spinlock + and assume it is unlocked. We cannot accept that. */ + +int +__pthread_spin_lock (pthread_spinlock_t *lock) +{ + asm volatile + ("\n" + "1:\n\t" + "lock; decl %0\n\t" + "js 2f\n\t" + ".section .text.spinlock,\"ax\"\n" + "2:\n\t" + "cmpl $0,%0\n\t" + "rep; nop\n\t" + "jle 2b\n\t" + "jmp 1b\n\t" + ".previous" + : "=m" (*lock)); + return 0; +} +weak_alias (__pthread_spin_lock, pthread_spin_lock) + + +int +__pthread_spin_trylock (pthread_spinlock_t *lock) +{ + int oldval; + + asm volatile + ("xchgl %0,%1" + : "=r" (oldval), "=m" (*lock) + : "0" (0)); + return oldval > 0 ? 0 : EBUSY; +} +weak_alias (__pthread_spin_trylock, pthread_spin_trylock) + + +int +__pthread_spin_unlock (pthread_spinlock_t *lock) +{ + asm volatile + ("movl $1,%0" + : "=m" (*lock)); + return 0; +} +weak_alias (__pthread_spin_unlock, pthread_spin_unlock) + + +int +__pthread_spin_init (pthread_spinlock_t *lock, int pshared) +{ + /* We can ignore the `pshared' parameter. Since we are busy-waiting + all processes which can access the memory location `lock' points + to can use the spinlock. */ + *lock = 1; + return 0; +} +weak_alias (__pthread_spin_init, pthread_spin_init) + + +int +__pthread_spin_destroy (pthread_spinlock_t *lock) +{ + /* Nothing to do. */ + return 0; +} +weak_alias (__pthread_spin_destroy, pthread_spin_destroy) diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/pt-machine.h b/newlib/libc/sys/linux/linuxthreads/machine/i386/pt-machine.h new file mode 100644 index 000000000..3346bcc34 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/pt-machine.h @@ -0,0 +1,98 @@ +/* Machine-dependent pthreads configuration and inline functions. + i386 version. + Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson <rth@tamu.edu>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef PT_EI +# define PT_EI extern inline +#endif + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#define CURRENT_STACK_FRAME __builtin_frame_address (0) + + +/* Spinlock implementation; required. */ +PT_EI long int +testandset (int *spinlock) +{ + long int ret; + + __asm__ __volatile__( + "xchgl %0, %1" + : "=r"(ret), "=m"(*spinlock) + : "0"(1), "m"(*spinlock) + : "memory"); + + return ret; +} + + +/* Compare-and-swap for semaphores. + Available on the 486 and above, but not on the 386. + We test dynamically whether it's available or not. */ + +#define HAS_COMPARE_AND_SWAP +#define TEST_FOR_COMPARE_AND_SWAP + +PT_EI int +__compare_and_swap (long int *p, long int oldval, long int newval) +{ + char ret; + long int readval; + + __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0" + : "=q" (ret), "=m" (*p), "=a" (readval) + : "r" (newval), "m" (*p), "a" (oldval) + : "memory"); + return ret; +} + + +PT_EI int +get_eflags (void) +{ + int res; + __asm__ __volatile__ ("pushfl; popl %0" : "=r" (res) : ); + return res; +} + + +PT_EI void +set_eflags (int newflags) +{ + __asm__ __volatile__ ("pushl %0; popfl" : : "r" (newflags) : "cc"); +} + + +PT_EI int +compare_and_swap_is_available (void) +{ + int oldflags = get_eflags (); + int changed; + /* Flip AC bit in EFLAGS. */ + set_eflags (oldflags ^ 0x40000); + /* See if bit changed. */ + changed = (get_eflags () ^ oldflags) & 0x40000; + /* Restore EFLAGS. */ + set_eflags (oldflags); + /* If the AC flag did not change, it's a 386 and it lacks cmpxchg. + Otherwise, it's a 486 or above and it has cmpxchg. */ + return changed != 0; +} diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/sigcontextinfo.h b/newlib/libc/sys/linux/linuxthreads/machine/i386/sigcontextinfo.h new file mode 100644 index 000000000..6530ba6f3 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/sigcontextinfo.h @@ -0,0 +1,51 @@ +/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define SIGCONTEXT struct sigcontext +#define SIGCONTEXT_EXTRA_ARGS +#define GET_PC(ctx) ((void *) ctx.eip) +#define GET_FRAME(ctx) ((void *) ctx.ebp) +#define GET_STACK(ctx) ((void *) ctx.esp_at_signal) +#define CALL_SIGHANDLER(handler, signo, ctx) \ +do { \ + int __tmp1, __tmp2, __tmp3, __tmp4; \ + __asm __volatile ("movl\t%%esp, %%edi\n\t" \ + "andl\t$-16, %%esp\n\t" \ + "subl\t%8, %%esp\n\t" \ + "movl\t%%edi, %c8-4(%%esp)\n\t" \ + "movl\t%1, 0(%%esp)\n\t" \ + "leal\t4(%%esp), %%edi\n\t" \ + "cld\n\t" \ + "rep\tmovsl\n\t" \ + "call\t*%0\n\t" \ + "cld\n\t" \ + "movl\t%9, %%ecx\n\t" \ + "subl\t%%edi, %%esi\n\t" \ + "leal\t4(%%esp,%%esi,1), %%edi\n\t" \ + "leal\t4(%%esp), %%esi\n\t" \ + "rep\tmovsl\n\t" \ + "movl\t%c8-4(%%esp), %%esp\n\t" \ + : "=a" (__tmp1), "=d" (__tmp2), "=S" (__tmp3), \ + "=c" (__tmp4) \ + : "0" (handler), "1" (signo), "2" (&ctx), \ + "3" (sizeof (struct sigcontext) / 4), \ + "n" ((sizeof (struct sigcontext) + 19) & ~15), \ + "i" (sizeof (struct sigcontext) / 4) \ + : "cc", "edi"); \ +} while (0) diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/stackinfo.h b/newlib/libc/sys/linux/linuxthreads/machine/i386/stackinfo.h new file mode 100644 index 000000000..a9a6745aa --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/stackinfo.h @@ -0,0 +1,28 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* This file contains a bit of information about the stack allocation + of the processor. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +/* On x86 the stack grows down. */ +#define _STACK_GROWS_DOWN 1 + +#endif /* stackinfo.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/sysdep.S b/newlib/libc/sys/linux/linuxthreads/machine/i386/sysdep.S new file mode 100644 index 000000000..f219805a8 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/sysdep.S @@ -0,0 +1,41 @@ +/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +/* The following code is only used in the shared library when we + compile the reentrant version. Otherwise each system call defines + each own version. */ + +#ifndef PIC + +/* The syscall stubs jump here when they detect an error. + The code for Linux is almost identical to the canonical Unix/i386 + code, except that the error number in %eax is negated. */ + +#undef CALL_MCOUNT +#define CALL_MCOUNT /* Don't insert the profiling call, it clobbers %eax. */ + + .text +ENTRY (__syscall_error) + negl %eax + +#define __syscall_error __syscall_error_1 +#include <i386-sysdep.S> + +#endif /* !PIC */ diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/sysdep.h b/newlib/libc/sys/linux/linuxthreads/machine/i386/sysdep.h new file mode 100644 index 000000000..48aeab195 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/sysdep.h @@ -0,0 +1,291 @@ +/* Copyright (C) 1992, 93, 95, 96, 97, 98, 99, 00 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _LINUX_I386_SYSDEP_H +#define _LINUX_I386_SYSDEP_H 1 + +#include "i386-sysdep.h" + +/* For Linux we can use the system call table in the header file + /usr/include/asm/unistd.h + of the kernel. But these symbols do not follow the SYS_* syntax + so we have to redefine the `SYS_ify' macro here. */ +#undef SYS_ify +#define SYS_ify(syscall_name) __NR_##syscall_name + +/* ELF-like local names start with `.L'. */ +#undef L +#define L(name) .L##name + +#ifdef __ASSEMBLER__ + +/* Linux uses a negative return value to indicate syscall errors, + unlike most Unices, which use the condition codes' carry flag. + + Since version 2.1 the return value of a system call might be + negative even if the call succeeded. E.g., the `lseek' system call + might return a large offset. Therefore we must not anymore test + for < 0, but test for a real error by making sure the value in %eax + is a real error number. Linus said he will make sure the no syscall + returns a value in -1 .. -4095 as a valid result so we can savely + test with -4095. */ + +/* We don't want the label for the error handle to be global when we define + it here. */ +#ifdef PIC +# define SYSCALL_ERROR_LABEL 0f +#else +# define SYSCALL_ERROR_LABEL syscall_error +#endif + +#undef PSEUDO +#define PSEUDO(name, syscall_name, args) \ + .text; \ + ENTRY (name) \ + DO_CALL (args, syscall_name); \ + cmpl $-4095, %eax; \ + jae SYSCALL_ERROR_LABEL; \ + L(pseudo_end): + +#undef PSEUDO_END +#define PSEUDO_END(name) \ + SYSCALL_ERROR_HANDLER \ + END (name) + +#ifndef PIC +#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ +#else +/* Store (- %eax) into errno through the GOT. */ +#ifdef _LIBC_REENTRANT +#define SYSCALL_ERROR_HANDLER \ +0:pushl %ebx; \ + call 1f; \ +1:popl %ebx; \ + xorl %edx, %edx; \ + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx; \ + subl %eax, %edx; \ + pushl %edx; \ + PUSH_ERRNO_LOCATION_RETURN; \ + call BP_SYM (__errno_location)@PLT; \ + POP_ERRNO_LOCATION_RETURN; \ + popl %ecx; \ + popl %ebx; \ + movl %ecx, (%eax); \ + orl $-1, %eax; \ + jmp L(pseudo_end); +/* A quick note: it is assumed that the call to `__errno_location' does + not modify the stack! */ +#else +#define SYSCALL_ERROR_HANDLER \ +0:call 1f; \ +1:popl %ecx; \ + xorl %edx, %edx; \ + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx; \ + subl %eax, %edx; \ + movl errno@GOT(%ecx), %ecx; \ + movl %edx, (%ecx); \ + orl $-1, %eax; \ + jmp L(pseudo_end); +#endif /* _LIBC_REENTRANT */ +#endif /* PIC */ + +/* Linux takes system call arguments in registers: + + syscall number %eax call-clobbered + arg 1 %ebx call-saved + arg 2 %ecx call-clobbered + arg 3 %edx call-clobbered + arg 4 %esi call-saved + arg 5 %edi call-saved + + The stack layout upon entering the function is: + + 20(%esp) Arg# 5 + 16(%esp) Arg# 4 + 12(%esp) Arg# 3 + 8(%esp) Arg# 2 + 4(%esp) Arg# 1 + (%esp) Return address + + (Of course a function with say 3 arguments does not have entries for + arguments 4 and 5.) + + The following code tries hard to be optimal. A general assumption + (which is true according to the data books I have) is that + + 2 * xchg is more expensive than pushl + movl + popl + + Beside this a neat trick is used. The calling conventions for Linux + tell that among the registers used for parameters %ecx and %edx need + not be saved. Beside this we may clobber this registers even when + they are not used for parameter passing. + + As a result one can see below that we save the content of the %ebx + register in the %edx register when we have less than 3 arguments + (2 * movl is less expensive than pushl + popl). + + Second unlike for the other registers we don't save the content of + %ecx and %edx when we have more than 1 and 2 registers resp. + + The code below might look a bit long but we have to take care for + the pipelined processors (i586). Here the `pushl' and `popl' + instructions are marked as NP (not pairable) but the exception is + two consecutive of these instruction. This gives no penalty on + other processors though. */ + +#undef DO_CALL +#define DO_CALL(args, syscall_name) \ + PUSHARGS_##args \ + DOARGS_##args \ + movl $SYS_ify (syscall_name), %eax; \ + int $0x80 \ + POPARGS_##args + +#define PUSHARGS_0 /* No arguments to push. */ +#define DOARGS_0 /* No arguments to frob. */ +#define POPARGS_0 /* No arguments to pop. */ +#define _PUSHARGS_0 /* No arguments to push. */ +#define _DOARGS_0(n) /* No arguments to frob. */ +#define _POPARGS_0 /* No arguments to pop. */ + +#define PUSHARGS_1 movl %ebx, %edx; PUSHARGS_0 +#define DOARGS_1 _DOARGS_1 (4) +#define POPARGS_1 POPARGS_0; movl %edx, %ebx +#define _PUSHARGS_1 pushl %ebx; _PUSHARGS_0 +#define _DOARGS_1(n) movl n(%esp), %ebx; _DOARGS_0(n-4) +#define _POPARGS_1 _POPARGS_0; popl %ebx + +#define PUSHARGS_2 PUSHARGS_1 +#define DOARGS_2 _DOARGS_2 (8) +#define POPARGS_2 POPARGS_1 +#define _PUSHARGS_2 _PUSHARGS_1 +#define _DOARGS_2(n) movl n(%esp), %ecx; _DOARGS_1 (n-4) +#define _POPARGS_2 _POPARGS_1 + +#define PUSHARGS_3 _PUSHARGS_2 +#define DOARGS_3 _DOARGS_3 (16) +#define POPARGS_3 _POPARGS_3 +#define _PUSHARGS_3 _PUSHARGS_2 +#define _DOARGS_3(n) movl n(%esp), %edx; _DOARGS_2 (n-4) +#define _POPARGS_3 _POPARGS_2 + +#define PUSHARGS_4 _PUSHARGS_4 +#define DOARGS_4 _DOARGS_4 (24) +#define POPARGS_4 _POPARGS_4 +#define _PUSHARGS_4 pushl %esi; _PUSHARGS_3 +#define _DOARGS_4(n) movl n(%esp), %esi; _DOARGS_3 (n-4) +#define _POPARGS_4 _POPARGS_3; popl %esi + +#define PUSHARGS_5 _PUSHARGS_5 +#define DOARGS_5 _DOARGS_5 (32) +#define POPARGS_5 _POPARGS_5 +#define _PUSHARGS_5 pushl %edi; _PUSHARGS_4 +#define _DOARGS_5(n) movl n(%esp), %edi; _DOARGS_4 (n-4) +#define _POPARGS_5 _POPARGS_4; popl %edi + +#else /* !__ASSEMBLER__ */ + +/* We need some help from the assembler to generate optimal code. We + define some macros here which later will be used. */ +asm (".L__X'%ebx = 1\n\t" + ".L__X'%ecx = 2\n\t" + ".L__X'%edx = 2\n\t" + ".L__X'%eax = 3\n\t" + ".L__X'%esi = 3\n\t" + ".L__X'%edi = 3\n\t" + ".L__X'%ebp = 3\n\t" + ".L__X'%esp = 3\n\t" + ".macro bpushl name reg\n\t" + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" + "pushl %ebx\n\t" + ".else\n\t" + "xchgl \\reg, %ebx\n\t" + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" + ".macro bpopl name reg\n\t" + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" + "popl %ebx\n\t" + ".else\n\t" + "xchgl \\reg, %ebx\n\t" + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" + ".macro bmovl name reg\n\t" + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" + "movl \\reg, %ebx\n\t" + ".endif\n\t" + ".endif\n\t" + ".endm\n\t"); + +/* Define a macro which expands inline into the wrapper code for a system + call. */ +#undef INLINE_SYSCALL +#define INLINE_SYSCALL(name, nr, args...) \ + ({ \ + unsigned int resultvar; \ + asm volatile ( \ + LOADARGS_##nr \ + "movl %1, %%eax\n\t" \ + "int $0x80\n\t" \ + RESTOREARGS_##nr \ + : "=a" (resultvar) \ + : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \ + if (resultvar >= 0xfffff001) \ + { \ + __set_errno (-resultvar); \ + resultvar = 0xffffffff; \ + } \ + (int) resultvar; }) + +#define LOADARGS_0 +#define LOADARGS_1 \ + "bpushl .L__X'%k2, %k2\n\t" \ + "bmovl .L__X'%k2, %k2\n\t" +#define LOADARGS_2 LOADARGS_1 +#define LOADARGS_3 LOADARGS_1 +#define LOADARGS_4 LOADARGS_1 +#define LOADARGS_5 LOADARGS_1 + +#define RESTOREARGS_0 +#define RESTOREARGS_1 \ + "bpopl .L__X'%k2, %k2\n\t" +#define RESTOREARGS_2 RESTOREARGS_1 +#define RESTOREARGS_3 RESTOREARGS_1 +#define RESTOREARGS_4 RESTOREARGS_1 +#define RESTOREARGS_5 RESTOREARGS_1 + +#define ASMFMT_0() +#define ASMFMT_1(arg1) \ + , "acdSD" (arg1) +#define ASMFMT_2(arg1, arg2) \ + , "adCD" (arg1), "c" (arg2) +#define ASMFMT_3(arg1, arg2, arg3) \ + , "aCD" (arg1), "c" (arg2), "d" (arg3) +#define ASMFMT_4(arg1, arg2, arg3, arg4) \ + , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4) +#define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \ + , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5) + +#endif /* __ASSEMBLER__ */ + +#endif /* linux/i386/sysdep.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/machine/i386/useldt.h b/newlib/libc/sys/linux/linuxthreads/machine/i386/useldt.h new file mode 100644 index 000000000..02d079c9e --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/machine/i386/useldt.h @@ -0,0 +1,205 @@ +/* Special definitions for ix86 machine using segment register based + thread descriptor. + Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stddef.h> /* For offsetof. */ +#include <stdlib.h> /* For abort(). */ + + +/* We don't want to include the kernel header. So duplicate the + information. */ + +/* Structure passed on `modify_ldt' call. */ +struct modify_ldt_ldt_s +{ + unsigned int entry_number; + unsigned long int base_addr; + unsigned int limit; + unsigned int seg_32bit:1; + unsigned int contents:2; + unsigned int read_exec_only:1; + unsigned int limit_in_pages:1; + unsigned int seg_not_present:1; + unsigned int useable:1; + unsigned int empty:25; +}; + +/* System call to set LDT entry. */ +extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t); + + +/* Return the thread descriptor for the current thread. + + The contained asm must *not* be marked volatile since otherwise + assignments like + pthread_descr self = thread_self(); + do not get optimized away. */ +#define THREAD_SELF \ +({ \ + register pthread_descr __self; \ + __asm__ ("movl %%gs:%c1,%0" : "=r" (__self) \ + : "i" (offsetof (struct _pthread_descr_struct, \ + p_header.data.self))); \ + __self; \ +}) + +/* Initialize the thread-unique value. */ +#define INIT_THREAD_SELF(descr, nr) \ +{ \ + struct modify_ldt_ldt_s ldt_entry = \ + { nr, (unsigned long int) descr, sizeof (*descr), 1, 0, 0, 0, 0, 1, 0 }; \ + if (__modify_ldt (1, &ldt_entry, sizeof (ldt_entry)) != 0) \ + abort (); \ + __asm__ __volatile__ ("movw %w0, %%gs" : : "q" (nr * 8 + 7)); \ +} + +/* Free resources associated with thread descriptor. */ +#define FREE_THREAD(descr, nr) \ +{ \ + struct modify_ldt_ldt_s ldt_entry = \ + { nr, 0, 0, 0, 0, 1, 0, 1, 0, 0 }; \ + __modify_ldt (1, &ldt_entry, sizeof (ldt_entry)); \ +} + +/* Read member of the thread descriptor directly. */ +#define THREAD_GETMEM(descr, member) \ +({ \ + __typeof__ (descr->member) __value; \ + if (sizeof (__value) == 1) \ + __asm__ __volatile__ ("movb %%gs:%P2,%b0" \ + : "=q" (__value) \ + : "0" (0), \ + "i" (offsetof (struct _pthread_descr_struct, \ + member))); \ + else if (sizeof (__value) == 4) \ + __asm__ __volatile__ ("movl %%gs:%P1,%0" \ + : "=r" (__value) \ + : "i" (offsetof (struct _pthread_descr_struct, \ + member))); \ + else \ + { \ + if (sizeof (__value) != 8) \ + /* There should not be any value with a size other than 1, 4 or 8. */\ + abort (); \ + \ + __asm__ __volatile__ ("movl %%gs:%P1,%%eax\n\t" \ + "movl %%gs:%P2,%%edx" \ + : "=A" (__value) \ + : "i" (offsetof (struct _pthread_descr_struct, \ + member)), \ + "i" (offsetof (struct _pthread_descr_struct, \ + member) + 4)); \ + } \ + __value; \ +}) + +/* Same as THREAD_GETMEM, but the member offset can be non-constant. */ +#define THREAD_GETMEM_NC(descr, member) \ +({ \ + __typeof__ (descr->member) __value; \ + if (sizeof (__value) == 1) \ + __asm__ __volatile__ ("movb %%gs:(%2),%b0" \ + : "=q" (__value) \ + : "0" (0), \ + "r" (offsetof (struct _pthread_descr_struct, \ + member))); \ + else if (sizeof (__value) == 4) \ + __asm__ __volatile__ ("movl %%gs:(%1),%0" \ + : "=r" (__value) \ + : "r" (offsetof (struct _pthread_descr_struct, \ + member))); \ + else \ + { \ + if (sizeof (__value) != 8) \ + /* There should not be any value with a size other than 1, 4 or 8. */\ + abort (); \ + \ + __asm__ __volatile__ ("movl %%gs:(%1),%%eax\n\t" \ + "movl %%gs:4(%1),%%edx" \ + : "=&A" (__value) \ + : "r" (offsetof (struct _pthread_descr_struct, \ + member))); \ + } \ + __value; \ +}) + +/* Same as THREAD_SETMEM, but the member offset can be non-constant. */ +#define THREAD_SETMEM(descr, member, value) \ +({ \ + __typeof__ (descr->member) __value = (value); \ + if (sizeof (__value) == 1) \ + __asm__ __volatile__ ("movb %0,%%gs:%P1" : \ + : "q" (__value), \ + "i" (offsetof (struct _pthread_descr_struct, \ + member))); \ + else if (sizeof (__value) == 4) \ + __asm__ __volatile__ ("movl %0,%%gs:%P1" : \ + : "r" (__value), \ + "i" (offsetof (struct _pthread_descr_struct, \ + member))); \ + else \ + { \ + if (sizeof (__value) != 8) \ + /* There should not be any value with a size other than 1, 4 or 8. */\ + abort (); \ + \ + __asm__ __volatile__ ("movl %%eax,%%gs:%P1\n\n" \ + "movl %%edx,%%gs:%P2" : \ + : "A" (__value), \ + "i" (offsetof (struct _pthread_descr_struct, \ + member)), \ + "i" (offsetof (struct _pthread_descr_struct, \ + member) + 4)); \ + } \ +}) + +/* Set member of the thread descriptor directly. */ +#define THREAD_SETMEM_NC(descr, member, value) \ +({ \ + __typeof__ (descr->member) __value = (value); \ + if (sizeof (__value) == 1) \ + __asm__ __volatile__ ("movb %0,%%gs:(%1)" : \ + : "q" (__value), \ + "r" (offsetof (struct _pthread_descr_struct, \ + member))); \ + else if (sizeof (__value) == 4) \ + __asm__ __volatile__ ("movl %0,%%gs:(%1)" : \ + : "r" (__value), \ + "r" (offsetof (struct _pthread_descr_struct, \ + member))); \ + else \ + { \ + if (sizeof (__value) != 8) \ + /* There should not be any value with a size other than 1, 4 or 8. */\ + abort (); \ + \ + __asm__ __volatile__ ("movl %%eax,%%gs:(%1)\n\t" \ + "movl %%edx,%%gs:4(%1)" : \ + : "A" (__value), \ + "r" (offsetof (struct _pthread_descr_struct, \ + member))); \ + } \ +}) + +/* We want the OS to assign stack addresses. */ +#define FLOATING_STACKS 1 + +/* Maximum size of the stack if the rlimit is unlimited. */ +#define ARCH_STACK_MAX_SIZE 8*1024*1024 diff --git a/newlib/libc/sys/linux/linuxthreads/manager.c b/newlib/libc/sys/linux/linuxthreads/manager.c new file mode 100644 index 000000000..7729903cf --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/manager.c @@ -0,0 +1,981 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* The "thread manager" thread: manages creation and termination of threads */ + +#include <errno.h> +#include <sched.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/poll.h> /* for poll */ +#include <sys/mman.h> /* for mmap */ +#include <sys/param.h> +#include <sys/time.h> +#include <sys/wait.h> /* for waitpid macros */ + +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include "restart.h" +#include "semaphore.h" + +/* Array of active threads. Entry 0 is reserved for the initial thread. */ +struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX] = +{ { __LOCK_INITIALIZER, &__pthread_initial_thread, 0}, + { __LOCK_INITIALIZER, &__pthread_manager_thread, 0}, /* All NULLs */ }; + +/* For debugging purposes put the maximum number of threads in a variable. */ +const int __linuxthreads_pthread_threads_max = PTHREAD_THREADS_MAX; + +#ifndef THREAD_SELF +/* Indicate whether at least one thread has a user-defined stack (if 1), + or if all threads have stacks supplied by LinuxThreads (if 0). */ +int __pthread_nonstandard_stacks; +#endif + +/* Number of active entries in __pthread_handles (used by gdb) */ +volatile int __pthread_handles_num = 2; + +/* Whether to use debugger additional actions for thread creation + (set to 1 by gdb) */ +volatile int __pthread_threads_debug; + +/* Globally enabled events. */ +volatile td_thr_events_t __pthread_threads_events; + +/* Pointer to thread descriptor with last event. */ +volatile pthread_descr __pthread_last_event; + +/* Mapping from stack segment to thread descriptor. */ +/* Stack segment numbers are also indices into the __pthread_handles array. */ +/* Stack segment number 0 is reserved for the initial thread. */ + +#if FLOATING_STACKS +# define thread_segment(seq) NULL +#else +static inline pthread_descr thread_segment(int seg) +{ + return (pthread_descr)(THREAD_STACK_START_ADDRESS - (seg - 1) * STACK_SIZE) + - 1; +} +#endif + +/* Flag set in signal handler to record child termination */ + +static volatile int terminated_children; + +/* Flag set when the initial thread is blocked on pthread_exit waiting + for all other threads to terminate */ + +static int main_thread_exiting; + +/* Counter used to generate unique thread identifier. + Thread identifier is pthread_threads_counter + segment. */ + +static pthread_t pthread_threads_counter; + +/* Forward declarations */ + +static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, + void * (*start_routine)(void *), void *arg, + sigset_t *mask, int father_pid, + int report_events, + td_thr_events_t *event_maskp); +static void pthread_handle_free(pthread_t th_id); +static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode) + __attribute__ ((noreturn)); +static void pthread_reap_children(void); +static void pthread_kill_all_threads(int sig, int main_thread_also); +static void pthread_for_each_thread(void *arg, + void (*fn)(void *, pthread_descr)); + +/* The server thread managing requests for thread creation and termination */ + +int +__attribute__ ((noreturn)) +__pthread_manager(void *arg) +{ + int reqfd = (int) (long int) arg; + struct pollfd ufd; + sigset_t manager_mask; + int n; + struct pthread_request request; + + /* If we have special thread_self processing, initialize it. */ +#ifdef INIT_THREAD_SELF + INIT_THREAD_SELF(&__pthread_manager_thread, 1); +#endif + /* Set the error variable. */ + __pthread_manager_thread.p_reentp = &__pthread_manager_thread.p_reent; + __pthread_manager_thread.p_h_errnop = &__pthread_manager_thread.p_h_errno; + /* Block all signals except __pthread_sig_cancel and SIGTRAP */ + sigfillset(&manager_mask); + sigdelset(&manager_mask, __pthread_sig_cancel); /* for thread termination */ + sigdelset(&manager_mask, SIGTRAP); /* for debugging purposes */ + if (__pthread_threads_debug && __pthread_sig_debug > 0) + sigdelset(&manager_mask, __pthread_sig_debug); + sigprocmask(SIG_SETMASK, &manager_mask, NULL); + /* Raise our priority to match that of main thread */ + __pthread_manager_adjust_prio(__pthread_main_thread->p_priority); + /* Synchronize debugging of the thread manager */ + n = TEMP_FAILURE_RETRY(__libc_read(reqfd, (char *)&request, + sizeof(request))); + ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG); + ufd.fd = reqfd; + ufd.events = POLLIN; + /* Enter server loop */ + while(1) { + n = __poll(&ufd, 1, 2000); + + /* Check for termination of the main thread */ + if (getppid() == 1) { + pthread_kill_all_threads(SIGKILL, 0); + _exit(0); + } + /* Check for dead children */ + if (terminated_children) { + terminated_children = 0; + pthread_reap_children(); + } + /* Read and execute request */ + if (n == 1 && (ufd.revents & POLLIN)) { + n = TEMP_FAILURE_RETRY(__libc_read(reqfd, (char *)&request, + sizeof(request))); +#ifdef DEBUG + if (n < 0) { + char d[64]; + write(STDERR_FILENO, d, snprintf(d, sizeof(d), "*** read err %m\n")); + } else if (n != sizeof(request)) { + write(STDERR_FILENO, "*** short read in manager\n", 26); + } +#endif + + switch(request.req_kind) { + case REQ_CREATE: + request.req_thread->p_retcode = + pthread_handle_create((pthread_t *) &request.req_thread->p_retval, + request.req_args.create.attr, + request.req_args.create.fn, + request.req_args.create.arg, + &request.req_args.create.mask, + request.req_thread->p_pid, + request.req_thread->p_report_events, + &request.req_thread->p_eventbuf.eventmask); + restart(request.req_thread); + break; + case REQ_FREE: + pthread_handle_free(request.req_args.free.thread_id); + break; + case REQ_PROCESS_EXIT: + pthread_handle_exit(request.req_thread, + request.req_args.exit.code); + /* NOTREACHED */ + break; + case REQ_MAIN_THREAD_EXIT: + main_thread_exiting = 1; + /* Reap children in case all other threads died and the signal handler + went off before we set main_thread_exiting to 1, and therefore did + not do REQ_KICK. */ + pthread_reap_children(); + + if (__pthread_main_thread->p_nextlive == __pthread_main_thread) { + restart(__pthread_main_thread); + /* The main thread will now call exit() which will trigger an + __on_exit handler, which in turn will send REQ_PROCESS_EXIT + to the thread manager. In case you are wondering how the + manager terminates from its loop here. */ + } + break; + case REQ_POST: + __new_sem_post(request.req_args.post); + break; + case REQ_DEBUG: + /* Make gdb aware of new thread and gdb will restart the + new thread when it is ready to handle the new thread. */ + if (__pthread_threads_debug && __pthread_sig_debug > 0) + raise(__pthread_sig_debug); + break; + case REQ_KICK: + /* This is just a prod to get the manager to reap some + threads right away, avoiding a potential delay at shutdown. */ + break; + case REQ_FOR_EACH_THREAD: + pthread_for_each_thread(request.req_args.for_each.arg, + request.req_args.for_each.fn); + restart(request.req_thread); + break; + } + } + } +} + +int __pthread_manager_event(void *arg) +{ + /* If we have special thread_self processing, initialize it. */ +#ifdef INIT_THREAD_SELF + INIT_THREAD_SELF(&__pthread_manager_thread, 1); +#endif + + /* Get the lock the manager will free once all is correctly set up. */ + __pthread_lock (THREAD_GETMEM((&__pthread_manager_thread), p_lock), NULL); + /* Free it immediately. */ + __pthread_unlock (THREAD_GETMEM((&__pthread_manager_thread), p_lock)); + + return __pthread_manager(arg); +} + +/* Process creation */ + +static int +__attribute__ ((noreturn)) +pthread_start_thread(void *arg) +{ + pthread_descr self = (pthread_descr) arg; + struct pthread_request request; + void * outcome; +#if HP_TIMING_AVAIL + hp_timing_t tmpclock; +#endif + /* Initialize special thread_self processing, if any. */ +#ifdef INIT_THREAD_SELF + INIT_THREAD_SELF(self, self->p_nr); +#endif +#if HP_TIMING_AVAIL + HP_TIMING_NOW (tmpclock); + THREAD_SETMEM (self, p_cpuclock_offset, tmpclock); +#endif + /* Make sure our pid field is initialized, just in case we get there + before our father has initialized it. */ + THREAD_SETMEM(self, p_pid, __getpid()); + /* Initial signal mask is that of the creating thread. (Otherwise, + we'd just inherit the mask of the thread manager.) */ + sigprocmask(SIG_SETMASK, &self->p_start_args.mask, NULL); + /* Set the scheduling policy and priority for the new thread, if needed */ + if (THREAD_GETMEM(self, p_start_args.schedpolicy) >= 0) + /* Explicit scheduling attributes were provided: apply them */ + __sched_setscheduler(THREAD_GETMEM(self, p_pid), + THREAD_GETMEM(self, p_start_args.schedpolicy), + &self->p_start_args.schedparam); + else if (__pthread_manager_thread.p_priority > 0) + /* Default scheduling required, but thread manager runs in realtime + scheduling: switch new thread to SCHED_OTHER policy */ + { + struct sched_param default_params; + default_params.sched_priority = 0; + __sched_setscheduler(THREAD_GETMEM(self, p_pid), + SCHED_OTHER, &default_params); + } + /* Make gdb aware of new thread */ + if (__pthread_threads_debug && __pthread_sig_debug > 0) { + request.req_thread = self; + request.req_kind = REQ_DEBUG; + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + suspend(self); + } + /* Run the thread code */ + outcome = self->p_start_args.start_routine(THREAD_GETMEM(self, + p_start_args.arg)); + /* Exit with the given return value */ + __pthread_do_exit(outcome, CURRENT_STACK_FRAME); +} + +static int +__attribute__ ((noreturn)) +pthread_start_thread_event(void *arg) +{ + pthread_descr self = (pthread_descr) arg; + +#ifdef INIT_THREAD_SELF + INIT_THREAD_SELF(self, self->p_nr); +#endif + /* Make sure our pid field is initialized, just in case we get there + before our father has initialized it. */ + THREAD_SETMEM(self, p_pid, __getpid()); + /* Get the lock the manager will free once all is correctly set up. */ + __pthread_lock (THREAD_GETMEM(self, p_lock), NULL); + /* Free it immediately. */ + __pthread_unlock (THREAD_GETMEM(self, p_lock)); + + /* Continue with the real function. */ + pthread_start_thread (arg); +} + +static int pthread_allocate_stack(const pthread_attr_t *attr, + pthread_descr default_new_thread, + int pagesize, + pthread_descr * out_new_thread, + char ** out_new_thread_bottom, + char ** out_guardaddr, + size_t * out_guardsize) +{ + pthread_descr new_thread; + char * new_thread_bottom; + char * guardaddr; + size_t stacksize, guardsize; + + if (attr != NULL && attr->__stackaddr_set) + { +#ifdef _STACK_GROWS_UP + /* The user provided a stack. */ + new_thread = (pthread_descr) attr->__stackaddr; + new_thread_bottom = (char *) (new_thread + 1); + guardaddr = attr->__stackaddr + attr->__stacksize; + guardsize = 0; +#else + /* The user provided a stack. For now we interpret the supplied + address as 1 + the highest addr. in the stack segment. If a + separate register stack is needed, we place it at the low end + of the segment, relying on the associated stacksize to + determine the low end of the segment. This differs from many + (but not all) other pthreads implementations. The intent is + that on machines with a single stack growing toward higher + addresses, stackaddr would be the lowest address in the stack + segment, so that it is consistently close to the initial sp + value. */ + new_thread = + (pthread_descr) ((long)(attr->__stackaddr) & -sizeof(void *)) - 1; + new_thread_bottom = (char *) attr->__stackaddr - attr->__stacksize; + guardaddr = new_thread_bottom; + guardsize = 0; +#endif +#ifndef THREAD_SELF + __pthread_nonstandard_stacks = 1; +#endif + /* Clear the thread data structure. */ + memset (new_thread, '\0', sizeof (*new_thread)); + } + else + { +#ifdef NEED_SEPARATE_REGISTER_STACK + size_t granularity = 2 * pagesize; + /* Try to make stacksize/2 a multiple of pagesize */ +#else + size_t granularity = pagesize; +#endif + void *map_addr; + + /* Allocate space for stack and thread descriptor at default address */ +#if FLOATING_STACKS + if (attr != NULL) + { + guardsize = page_roundup (attr->__guardsize, granularity); + stacksize = __pthread_max_stacksize - guardsize; + stacksize = MIN (stacksize, + page_roundup (attr->__stacksize, granularity)); + } + else + { + guardsize = granularity; + stacksize = __pthread_max_stacksize - guardsize; + } + + map_addr = mmap(NULL, stacksize + guardsize, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (map_addr == MAP_FAILED) + /* No more memory available. */ + return -1; + +# ifdef NEED_SEPARATE_REGISTER_STACK + guardaddr = map_addr + stacksize / 2; + if (guardsize > 0) + mprotect (guardaddr, guardsize, PROT_NONE); + + new_thread_bottom = (char *) map_addr; + new_thread = ((pthread_descr) (new_thread_bottom + stacksize + + guardsize)) - 1; +# elif _STACK_GROWS_DOWN + guardaddr = map_addr; + if (guardsize > 0) + mprotect (guardaddr, guardsize, PROT_NONE); + + new_thread_bottom = (char *) map_addr + guardsize; + new_thread = ((pthread_descr) (new_thread_bottom + stacksize)) - 1; +# elif _STACK_GROWS_UP + guardaddr = map_addr + stacksize; + if (guardsize > 0) + mprotect (guardaddr, guardsize, PROT_NONE); + + new_thread = (pthread_descr) map_addr; + new_thread_bottom = (char *) (new_thread + 1); +# else +# error You must define a stack direction +# endif /* Stack direction */ +#else /* !FLOATING_STACKS */ + void *res_addr; + + if (attr != NULL) + { + guardsize = page_roundup (attr->__guardsize, granularity); + stacksize = STACK_SIZE - guardsize; + stacksize = MIN (stacksize, + page_roundup (attr->__stacksize, granularity)); + } + else + { + guardsize = granularity; + stacksize = STACK_SIZE - granularity; + } + +# ifdef NEED_SEPARATE_REGISTER_STACK + new_thread = default_new_thread; + new_thread_bottom = (char *) (new_thread + 1) - stacksize - guardsize; + /* Includes guard area, unlike the normal case. Use the bottom + end of the segment as backing store for the register stack. + Needed on IA64. In this case, we also map the entire stack at + once. According to David Mosberger, that's cheaper. It also + avoids the risk of intermittent failures due to other mappings + in the same region. The cost is that we might be able to map + slightly fewer stacks. */ + + /* First the main stack: */ + map_addr = (caddr_t)((char *)(new_thread + 1) - stacksize / 2); + res_addr = mmap(map_addr, stacksize / 2, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (res_addr != map_addr) + { + /* Bad luck, this segment is already mapped. */ + if (res_addr != MAP_FAILED) + munmap(res_addr, stacksize / 2); + return -1; + } + /* Then the register stack: */ + map_addr = (caddr_t)new_thread_bottom; + res_addr = mmap(map_addr, stacksize/2, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (res_addr != map_addr) + { + if (res_addr != MAP_FAILED) + munmap(res_addr, stacksize / 2); + munmap((caddr_t)((char *)(new_thread + 1) - stacksize/2), + stacksize/2); + return -1; + } + + guardaddr = new_thread_bottom + stacksize/2; + /* We leave the guard area in the middle unmapped. */ +# else /* !NEED_SEPARATE_REGISTER_STACK */ +# ifdef _STACK_GROWS_DOWN + new_thread = default_new_thread; + new_thread_bottom = (char *) (new_thread + 1) - stacksize; + map_addr = new_thread_bottom - guardsize; + res_addr = mmap(map_addr, stacksize + guardsize, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (res_addr != map_addr) + { + /* Bad luck, this segment is already mapped. */ + if (res_addr != MAP_FAILED) + munmap (res_addr, stacksize + guardsize); + return -1; + } + + /* We manage to get a stack. Protect the guard area pages if + necessary. */ + guardaddr = map_addr; + if (guardsize > 0) + mprotect (guardaddr, guardsize, PROT_NONE); +# else + /* The thread description goes at the bottom of this area, and + * the stack starts directly above it. + */ + new_thread = (pthread_descr)((unsigned long)default_new_thread &~ (STACK_SIZE - 1)); + map_addr = mmap(new_thread, stacksize + guardsize, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (map_addr == MAP_FAILED) + return -1; + + new_thread_bottom = map_addr + sizeof(*new_thread); + guardaddr = map_addr + stacksize; + if (guardsize > 0) + mprotect (guardaddr, guardsize, PROT_NONE); + +# endif /* stack direction */ +# endif /* !NEED_SEPARATE_REGISTER_STACK */ +#endif /* !FLOATING_STACKS */ + } + *out_new_thread = new_thread; + *out_new_thread_bottom = new_thread_bottom; + *out_guardaddr = guardaddr; + *out_guardsize = guardsize; + return 0; +} + +static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, + void * (*start_routine)(void *), void *arg, + sigset_t * mask, int father_pid, + int report_events, + td_thr_events_t *event_maskp) +{ + size_t sseg; + int pid; + pthread_descr new_thread; + char * new_thread_bottom; + pthread_t new_thread_id; + char *guardaddr = NULL; + size_t guardsize = 0; + int pagesize = __getpagesize(); + + /* First check whether we have to change the policy and if yes, whether + we can do this. Normally this should be done by examining the + return value of the __sched_setscheduler call in pthread_start_thread + but this is hard to implement. FIXME */ + if (attr != NULL && attr->__schedpolicy != SCHED_OTHER && geteuid () != 0) + return EPERM; + /* Find a free segment for the thread, and allocate a stack if needed */ + for (sseg = 2; ; sseg++) + { + if (sseg >= PTHREAD_THREADS_MAX) + return EAGAIN; + if (__pthread_handles[sseg].h_descr != NULL) + continue; + if (pthread_allocate_stack(attr, thread_segment(sseg), + pagesize, + &new_thread, &new_thread_bottom, + &guardaddr, &guardsize) == 0) + break; + } + __pthread_handles_num++; + /* Allocate new thread identifier */ + pthread_threads_counter += PTHREAD_THREADS_MAX; + new_thread_id = sseg + pthread_threads_counter; + /* Initialize the thread descriptor. Elements which have to be + initialized to zero already have this value. */ + new_thread->p_tid = new_thread_id; + new_thread->p_lock = &(__pthread_handles[sseg].h_lock); + new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE; + new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED; + new_thread->p_reentp = &new_thread->p_reent; + _REENT_INIT_PTR(new_thread->p_reentp); + new_thread->p_h_errnop = &new_thread->p_h_errno; + new_thread->p_resp = &new_thread->p_res; + new_thread->p_guardaddr = guardaddr; + new_thread->p_guardsize = guardsize; + new_thread->p_header.data.self = new_thread; + new_thread->p_nr = sseg; + new_thread->p_inheritsched = attr ? attr->__inheritsched : 0; + /* Initialize the thread handle */ + __pthread_init_lock(&__pthread_handles[sseg].h_lock); + __pthread_handles[sseg].h_descr = new_thread; + __pthread_handles[sseg].h_bottom = new_thread_bottom; + /* Determine scheduling parameters for the thread */ + new_thread->p_start_args.schedpolicy = -1; + if (attr != NULL) { + new_thread->p_detached = attr->__detachstate; + new_thread->p_userstack = attr->__stackaddr_set; + + switch(attr->__inheritsched) { + case PTHREAD_EXPLICIT_SCHED: + new_thread->p_start_args.schedpolicy = attr->__schedpolicy; + memcpy (&new_thread->p_start_args.schedparam, &attr->__schedparam, + sizeof (struct sched_param)); + break; + case PTHREAD_INHERIT_SCHED: + new_thread->p_start_args.schedpolicy = __sched_getscheduler(father_pid); + __sched_getparam(father_pid, &new_thread->p_start_args.schedparam); + break; + } + new_thread->p_priority = + new_thread->p_start_args.schedparam.sched_priority; + } + /* Finish setting up arguments to pthread_start_thread */ + new_thread->p_start_args.start_routine = start_routine; + new_thread->p_start_args.arg = arg; + new_thread->p_start_args.mask = *mask; + /* Make the new thread ID available already now. If any of the later + functions fail we return an error value and the caller must not use + the stored thread ID. */ + *thread = new_thread_id; + /* Raise priority of thread manager if needed */ + __pthread_manager_adjust_prio(new_thread->p_priority); + /* Do the cloning. We have to use two different functions depending + on whether we are debugging or not. */ + pid = 0; /* Note that the thread never can have PID zero. */ + if (report_events) + { + /* See whether the TD_CREATE event bit is set in any of the + masks. */ + int idx = __td_eventword (TD_CREATE); + uint32_t mask = __td_eventmask (TD_CREATE); + + if ((mask & (__pthread_threads_events.event_bits[idx] + | event_maskp->event_bits[idx])) != 0) + { + /* Lock the mutex the child will use now so that it will stop. */ + __pthread_lock(new_thread->p_lock, NULL); + + /* We have to report this event. */ +#ifdef NEED_SEPARATE_REGISTER_STACK + /* Perhaps this version should be used on all platforms. But + this requires that __clone2 be uniformly supported + everywhere. + + And there is some argument for changing the __clone2 + interface to pass sp and bsp instead, making it more IA64 + specific, but allowing stacks to grow outward from each + other, to get less paging and fewer mmaps. */ + pid = __clone2(pthread_start_thread_event, + (void **)new_thread_bottom, + (char *)new_thread - new_thread_bottom, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | + __pthread_sig_cancel, new_thread); +#elif _STACK_GROWS_UP + pid = __clone(pthread_start_thread_event, (void **) new_thread_bottom, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | + __pthread_sig_cancel, new_thread); +#else + pid = __clone(pthread_start_thread_event, (void **) new_thread, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | + __pthread_sig_cancel, new_thread); +#endif + if (pid != -1) + { + /* Now fill in the information about the new thread in + the newly created thread's data structure. We cannot let + the new thread do this since we don't know whether it was + already scheduled when we send the event. */ + new_thread->p_eventbuf.eventdata = new_thread; + new_thread->p_eventbuf.eventnum = TD_CREATE; + __pthread_last_event = new_thread; + + /* We have to set the PID here since the callback function + in the debug library will need it and we cannot guarantee + the child got scheduled before the debugger. */ + new_thread->p_pid = pid; + + /* Now call the function which signals the event. */ + __linuxthreads_create_event (); + + /* Now restart the thread. */ + __pthread_unlock(new_thread->p_lock); + } + } + } + if (pid == 0) + { +#ifdef NEED_SEPARATE_REGISTER_STACK + pid = __clone2(pthread_start_thread, + (void **)new_thread_bottom, + (char *)new_thread - new_thread_bottom, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | + __pthread_sig_cancel, new_thread); +#elif _STACK_GROWS_UP + pid = __clone(pthread_start_thread, (void **) new_thread_bottom, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | + __pthread_sig_cancel, new_thread); +#else + pid = __clone(pthread_start_thread, (void **) new_thread, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | + __pthread_sig_cancel, new_thread); +#endif /* !NEED_SEPARATE_REGISTER_STACK */ + } + /* Check if cloning succeeded */ + if (pid == -1) { + /* Free the stack if we allocated it */ + if (attr == NULL || !attr->__stackaddr_set) + { +#ifdef NEED_SEPARATE_REGISTER_STACK + size_t stacksize = ((char *)(new_thread->p_guardaddr) + - new_thread_bottom); + munmap((caddr_t)new_thread_bottom, + 2 * stacksize + new_thread->p_guardsize); +#elif _STACK_GROWS_UP + size_t stacksize = guardaddr - (char *)new_thread; + munmap(new_thread, stacksize + guardsize); +#else + size_t stacksize = (char *)(new_thread+1) - new_thread_bottom; + munmap(new_thread_bottom - guardsize, guardsize + stacksize); +#endif + } + __pthread_handles[sseg].h_descr = NULL; + __pthread_handles[sseg].h_bottom = NULL; + __pthread_handles_num--; + return errno; + } + /* Insert new thread in doubly linked list of active threads */ + new_thread->p_prevlive = __pthread_main_thread; + new_thread->p_nextlive = __pthread_main_thread->p_nextlive; + __pthread_main_thread->p_nextlive->p_prevlive = new_thread; + __pthread_main_thread->p_nextlive = new_thread; + /* Set pid field of the new thread, in case we get there before the + child starts. */ + new_thread->p_pid = pid; + return 0; +} + + +/* Try to free the resources of a thread when requested by pthread_join + or pthread_detach on a terminated thread. */ + +static void pthread_free(pthread_descr th) +{ + pthread_handle handle; + pthread_readlock_info *iter, *next; + + ASSERT(th->p_exited); + /* Make the handle invalid */ + handle = thread_handle(th->p_tid); + __pthread_lock(&handle->h_lock, NULL); + handle->h_descr = NULL; + handle->h_bottom = (char *)(-1L); + __pthread_unlock(&handle->h_lock); +#ifdef FREE_THREAD + FREE_THREAD(th, th->p_nr); +#endif + /* One fewer threads in __pthread_handles */ + __pthread_handles_num--; + + /* Destroy read lock list, and list of free read lock structures. + If the former is not empty, it means the thread exited while + holding read locks! */ + + for (iter = th->p_readlock_list; iter != NULL; iter = next) + { + next = iter->pr_next; + free(iter); + } + + for (iter = th->p_readlock_free; iter != NULL; iter = next) + { + next = iter->pr_next; + free(iter); + } + + /* If initial thread, nothing to free */ + if (!th->p_userstack) + { + size_t guardsize = th->p_guardsize; + /* Free the stack and thread descriptor area */ + char *guardaddr = th->p_guardaddr; +#ifdef _STACK_GROWS_UP + size_t stacksize = guardaddr - (char *)th; + guardaddr = (char *)th; +#else + /* Guardaddr is always set, even if guardsize is 0. This allows + us to compute everything else. */ + size_t stacksize = (char *)(th+1) - guardaddr - guardsize; +#ifdef NEED_SEPARATE_REGISTER_STACK + /* Take account of the register stack, which is below guardaddr. */ + guardaddr -= stacksize; + stacksize *= 2; +#endif +#endif + /* Unmap the stack. */ + munmap(guardaddr, stacksize + guardsize); + } +} + +/* Handle threads that have exited */ + +static void pthread_exited(pid_t pid) +{ + pthread_descr th; + int detached; + /* Find thread with that pid */ + for (th = __pthread_main_thread->p_nextlive; + th != __pthread_main_thread; + th = th->p_nextlive) { + if (th->p_pid == pid) { + /* Remove thread from list of active threads */ + th->p_nextlive->p_prevlive = th->p_prevlive; + th->p_prevlive->p_nextlive = th->p_nextlive; + /* Mark thread as exited, and if detached, free its resources */ + __pthread_lock(th->p_lock, NULL); + th->p_exited = 1; + /* If we have to signal this event do it now. */ + if (th->p_report_events) + { + /* See whether TD_REAP is in any of the mask. */ + int idx = __td_eventword (TD_REAP); + uint32_t mask = __td_eventmask (TD_REAP); + + if ((mask & (__pthread_threads_events.event_bits[idx] + | th->p_eventbuf.eventmask.event_bits[idx])) != 0) + { + /* Yep, we have to signal the reapage. */ + th->p_eventbuf.eventnum = TD_REAP; + th->p_eventbuf.eventdata = th; + __pthread_last_event = th; + + /* Now call the function to signal the event. */ + __linuxthreads_reap_event(); + } + } + detached = th->p_detached; + __pthread_unlock(th->p_lock); + if (detached) + pthread_free(th); + break; + } + } + /* If all threads have exited and the main thread is pending on a + pthread_exit, wake up the main thread and terminate ourselves. */ + if (main_thread_exiting && + __pthread_main_thread->p_nextlive == __pthread_main_thread) { + restart(__pthread_main_thread); + /* Same logic as REQ_MAIN_THREAD_EXIT. */ + } +} + +static void pthread_reap_children(void) +{ + pid_t pid; + int status; + + while ((pid = __libc___waitpid(-1, &status, WNOHANG | __WCLONE)) > 0) { + pthread_exited(pid); + if (WIFSIGNALED(status)) { + /* If a thread died due to a signal, send the same signal to + all other threads, including the main thread. */ + pthread_kill_all_threads(WTERMSIG(status), 1); + _exit(0); + } + } +} + +/* Try to free the resources of a thread when requested by pthread_join + or pthread_detach on a terminated thread. */ + +static void pthread_handle_free(pthread_t th_id) +{ + pthread_handle handle = thread_handle(th_id); + pthread_descr th; + + __pthread_lock(&handle->h_lock, NULL); + if (nonexisting_handle(handle, th_id)) { + /* pthread_reap_children has deallocated the thread already, + nothing needs to be done */ + __pthread_unlock(&handle->h_lock); + return; + } + th = handle->h_descr; + if (th->p_exited) { + __pthread_unlock(&handle->h_lock); + pthread_free(th); + } else { + /* The Unix process of the thread is still running. + Mark the thread as detached so that the thread manager will + deallocate its resources when the Unix process exits. */ + th->p_detached = 1; + __pthread_unlock(&handle->h_lock); + } +} + +/* Send a signal to all running threads */ + +static void pthread_kill_all_threads(int sig, int main_thread_also) +{ + pthread_descr th; + for (th = __pthread_main_thread->p_nextlive; + th != __pthread_main_thread; + th = th->p_nextlive) { + kill(th->p_pid, sig); + } + if (main_thread_also) { + kill(__pthread_main_thread->p_pid, sig); + } +} + +static void pthread_for_each_thread(void *arg, + void (*fn)(void *, pthread_descr)) +{ + pthread_descr th; + + for (th = __pthread_main_thread->p_nextlive; + th != __pthread_main_thread; + th = th->p_nextlive) { + fn(arg, th); + } + + fn(arg, __pthread_main_thread); +} + +/* Process-wide exit() */ + +static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode) +{ + pthread_descr th; + __pthread_exit_requested = 1; + __pthread_exit_code = exitcode; + /* A forced asynchronous cancellation follows. Make sure we won't + get stuck later in the main thread with a system lock being held + by one of the cancelled threads. Ideally one would use the same + code as in pthread_atfork(), but we can't distinguish system and + user handlers there. */ + __flockfilelist(); + /* Send the CANCEL signal to all running threads, including the main + thread, but excluding the thread from which the exit request originated + (that thread must complete the exit, e.g. calling atexit functions + and flushing stdio buffers). */ + for (th = issuing_thread->p_nextlive; + th != issuing_thread; + th = th->p_nextlive) { + kill(th->p_pid, __pthread_sig_cancel); + } + /* Now, wait for all these threads, so that they don't become zombies + and their times are properly added to the thread manager's times. */ + for (th = issuing_thread->p_nextlive; + th != issuing_thread; + th = th->p_nextlive) { + __waitpid(th->p_pid, NULL, __WCLONE); + } + __fresetlockfiles(); + restart(issuing_thread); + _exit(0); +} + +/* Handler for __pthread_sig_cancel in thread manager thread */ + +void __pthread_manager_sighandler(int sig) +{ + int kick_manager = terminated_children == 0 && main_thread_exiting; + terminated_children = 1; + + /* If the main thread is terminating, kick the thread manager loop + each time some threads terminate. This eliminates a two second + shutdown delay caused by the thread manager sleeping in the + call to __poll(). Instead, the thread manager is kicked into + action, reaps the outstanding threads and resumes the main thread + so that it can complete the shutdown. */ + + if (kick_manager) { + struct pthread_request request; + request.req_thread = 0; + request.req_kind = REQ_KICK; + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + } +} + +/* Adjust priority of thread manager so that it always run at a priority + higher than all threads */ + +void __pthread_manager_adjust_prio(int thread_prio) +{ + struct sched_param param; + + if (thread_prio <= __pthread_manager_thread.p_priority) return; + param.sched_priority = + thread_prio < __sched_get_priority_max(SCHED_FIFO) + ? thread_prio + 1 : thread_prio; + __sched_setscheduler(__pthread_manager_thread.p_pid, SCHED_FIFO, ¶m); + __pthread_manager_thread.p_priority = thread_prio; +} diff --git a/newlib/libc/sys/linux/linuxthreads/mq_notify.c b/newlib/libc/sys/linux/linuxthreads/mq_notify.c new file mode 100644 index 000000000..46492e470 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/mq_notify.c @@ -0,0 +1,106 @@ +/* Copyright 2002, Red Hat Inc. */ + +#include <mqueue.h> +#include <unistd.h> +#include <errno.h> +#include <sys/ipc.h> +#include <sys/sem.h> +#include <string.h> + +#include "internals.h" +#include <sys/lock.h> + +#include "mqlocal.h" + +static void *mq_notify_process (void *); + +void +__cleanup_mq_notify (struct libc_mq *info) +{ + struct sembuf sb4 = {4, 1, 0}; + /* kill notification thread and allow other processes to set a notification */ + pthread_cancel ((pthread_t)info->th); + semop (info->semid, &sb4, 1); +} + +static void * +mq_notify_process (void *arg) +{ + struct libc_mq *info = (struct libc_mq *)arg; + struct sembuf sb3[2] = {{3, 0, 0}, {5, 0, 0}}; + struct sembuf sb4 = {4, 1, 0}; + int rc; + + /* wait until queue is empty */ + while (!(rc = semop (info->semid, sb3, 1)) && errno == EINTR) + /* empty */ ; + + if (!rc) + { + /* now wait until there are 0 readers and the queue has something in it */ + sb3[0].sem_op = -1; + while (!(rc = semop (info->semid, sb3, 2)) && errno == EINTR) + /* empty */ ; + /* restore value since we have not actually performed a read */ + sb3[0].sem_op = 1; + semop (info->semid, sb3, 1); + /* perform desired notification - either run function in this thread or pass signal */ + if (!rc) + { + if (info->sigevent->sigev_notify == SIGEV_SIGNAL) + raise (info->sigevent->sigev_signo); + else if (info->sigevent->sigev_notify == SIGEV_THREAD) + info->sigevent->sigev_notify_function (info->sigevent->sigev_value); + /* allow other processes to now mq_notify */ + semop (info->semid, &sb4, 1); + } + } + pthread_exit (NULL); +} + +int +mq_notify (mqd_t msgid, const struct sigevent *notification) +{ + struct libc_mq *info; + struct sembuf sb4 = {4, -1, IPC_NOWAIT}; + int rc; + pthread_attr_t *attr = NULL; + + info = __find_mq (msgid); + + if (info == NULL) + { + errno = EBADF; + return -1; + } + + /* get notification lock */ + rc = semop (info->semid, &sb4, 1); + + if (rc == -1) + { + errno = EBUSY; + return -1; + } + + /* to get the notification running we use a pthread - if the user has requested + an action in a pthread, we use the user's attributes when setting up the thread */ + info->sigevent = (struct sigevent *)notification; + if (info->sigevent->sigev_notify == SIGEV_THREAD) + attr = (pthread_attr_t *)info->sigevent->sigev_notify_attributes; + rc = pthread_create ((pthread_t *)&info->th, attr, mq_notify_process, (void *)info); + + if (rc != 0) + rc = -1; + else + info->cleanup_notify = &__cleanup_mq_notify; + + return rc; +} + + + + + + + diff --git a/newlib/libc/sys/linux/linuxthreads/mutex.c b/newlib/libc/sys/linux/linuxthreads/mutex.c new file mode 100644 index 000000000..fb2e60770 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/mutex.c @@ -0,0 +1,366 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Mutexes */ + +#include <bits/libc-lock.h> +#include <errno.h> +#include <sched.h> +#include <stddef.h> +#include <limits.h> +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include "queue.h" +#include "restart.h" + +int __pthread_mutex_init(pthread_mutex_t * mutex, + const pthread_mutexattr_t * mutex_attr) +{ + __pthread_init_lock(&mutex->__m_lock); + mutex->__m_kind = + mutex_attr == NULL ? PTHREAD_MUTEX_TIMED_NP : mutex_attr->__mutexkind; + mutex->__m_count = 0; + mutex->__m_owner = NULL; + return 0; +} +strong_alias (__pthread_mutex_init, pthread_mutex_init) + +int __pthread_mutex_destroy(pthread_mutex_t * mutex) +{ + switch (mutex->__m_kind) { + case PTHREAD_MUTEX_ADAPTIVE_NP: + case PTHREAD_MUTEX_RECURSIVE_NP: + if ((mutex->__m_lock.__status & 1) != 0) + return EBUSY; + return 0; + case PTHREAD_MUTEX_ERRORCHECK_NP: + case PTHREAD_MUTEX_TIMED_NP: + if (mutex->__m_lock.__status != 0) + return EBUSY; + return 0; + default: + return EINVAL; + } +} +strong_alias (__pthread_mutex_destroy, pthread_mutex_destroy) + +int __pthread_mutex_trylock(pthread_mutex_t * mutex) +{ + pthread_descr self; + int retcode; + + switch(mutex->__m_kind) { + case PTHREAD_MUTEX_ADAPTIVE_NP: + retcode = __pthread_trylock(&mutex->__m_lock); + return retcode; + case PTHREAD_MUTEX_RECURSIVE_NP: + self = thread_self(); + if (mutex->__m_owner == self) { + mutex->__m_count++; + return 0; + } + retcode = __pthread_trylock(&mutex->__m_lock); + if (retcode == 0) { + mutex->__m_owner = self; + mutex->__m_count = 0; + } + return retcode; + case PTHREAD_MUTEX_ERRORCHECK_NP: + retcode = __pthread_alt_trylock(&mutex->__m_lock); + if (retcode == 0) { + mutex->__m_owner = thread_self(); + } + return retcode; + case PTHREAD_MUTEX_TIMED_NP: + retcode = __pthread_alt_trylock(&mutex->__m_lock); + return retcode; + default: + return EINVAL; + } +} +strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock) + +int __pthread_mutex_lock(pthread_mutex_t * mutex) +{ + pthread_descr self; + + switch(mutex->__m_kind) { + case PTHREAD_MUTEX_ADAPTIVE_NP: + __pthread_lock(&mutex->__m_lock, NULL); + return 0; + case PTHREAD_MUTEX_RECURSIVE_NP: + self = thread_self(); + if (mutex->__m_owner == self) { + mutex->__m_count++; + return 0; + } + __pthread_lock(&mutex->__m_lock, self); + mutex->__m_owner = self; + mutex->__m_count = 0; + return 0; + case PTHREAD_MUTEX_ERRORCHECK_NP: + self = thread_self(); + if (mutex->__m_owner == self) return EDEADLK; + __pthread_alt_lock(&mutex->__m_lock, self); + mutex->__m_owner = self; + return 0; + case PTHREAD_MUTEX_TIMED_NP: + __pthread_alt_lock(&mutex->__m_lock, NULL); + return 0; + default: + return EINVAL; + } +} +strong_alias (__pthread_mutex_lock, pthread_mutex_lock) + +int __pthread_mutex_timedlock (pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + pthread_descr self; + int res; + + if (__builtin_expect (abstime->tv_nsec, 0) < 0 + || __builtin_expect (abstime->tv_nsec, 0) >= 1000000000) + return EINVAL; + + switch(mutex->__m_kind) { + case PTHREAD_MUTEX_ADAPTIVE_NP: + __pthread_lock(&mutex->__m_lock, NULL); + return 0; + case PTHREAD_MUTEX_RECURSIVE_NP: + self = thread_self(); + if (mutex->__m_owner == self) { + mutex->__m_count++; + return 0; + } + __pthread_lock(&mutex->__m_lock, self); + mutex->__m_owner = self; + mutex->__m_count = 0; + return 0; + case PTHREAD_MUTEX_ERRORCHECK_NP: + self = thread_self(); + if (mutex->__m_owner == self) return EDEADLK; + res = __pthread_alt_timedlock(&mutex->__m_lock, self, abstime); + if (res != 0) + { + mutex->__m_owner = self; + return 0; + } + return ETIMEDOUT; + case PTHREAD_MUTEX_TIMED_NP: + /* Only this type supports timed out lock. */ + return (__pthread_alt_timedlock(&mutex->__m_lock, NULL, abstime) + ? 0 : ETIMEDOUT); + default: + return EINVAL; + } +} +strong_alias (__pthread_mutex_timedlock, pthread_mutex_timedlock) + +int __pthread_mutex_unlock(pthread_mutex_t * mutex) +{ + switch (mutex->__m_kind) { + case PTHREAD_MUTEX_ADAPTIVE_NP: + __pthread_unlock(&mutex->__m_lock); + return 0; + case PTHREAD_MUTEX_RECURSIVE_NP: + if (mutex->__m_owner != thread_self()) + return EPERM; + if (mutex->__m_count > 0) { + mutex->__m_count--; + return 0; + } + mutex->__m_owner = NULL; + __pthread_unlock(&mutex->__m_lock); + return 0; + case PTHREAD_MUTEX_ERRORCHECK_NP: + if (mutex->__m_owner != thread_self() || mutex->__m_lock.__status == 0) + return EPERM; + mutex->__m_owner = NULL; + __pthread_alt_unlock(&mutex->__m_lock); + return 0; + case PTHREAD_MUTEX_TIMED_NP: + __pthread_alt_unlock(&mutex->__m_lock); + return 0; + default: + return EINVAL; + } +} +strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock) + +int __pthread_mutexattr_init(pthread_mutexattr_t *attr) +{ + attr->__mutexkind = PTHREAD_MUTEX_TIMED_NP; + return 0; +} +strong_alias (__pthread_mutexattr_init, pthread_mutexattr_init) + +int __pthread_mutexattr_destroy(pthread_mutexattr_t *attr) +{ + return 0; +} +strong_alias (__pthread_mutexattr_destroy, pthread_mutexattr_destroy) + +int __pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind) +{ + if (kind != PTHREAD_MUTEX_ADAPTIVE_NP + && kind != PTHREAD_MUTEX_RECURSIVE_NP + && kind != PTHREAD_MUTEX_ERRORCHECK_NP + && kind != PTHREAD_MUTEX_TIMED_NP) + return EINVAL; + attr->__mutexkind = kind; + return 0; +} +weak_alias (__pthread_mutexattr_settype, pthread_mutexattr_settype) +#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2 +strong_alias ( __pthread_mutexattr_settype, __pthread_mutexattr_setkind_np) +weak_alias (__pthread_mutexattr_setkind_np, pthread_mutexattr_setkind_np) +#endif /* !_ELIX_LEVEL || _ELIX_LEVEL >= 2 */ + +int __pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *kind) +{ + *kind = attr->__mutexkind; + return 0; +} +weak_alias (__pthread_mutexattr_gettype, pthread_mutexattr_gettype) +#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2 +strong_alias (__pthread_mutexattr_gettype, __pthread_mutexattr_getkind_np) +weak_alias (__pthread_mutexattr_getkind_np, pthread_mutexattr_getkind_np) +#endif /* !_ELIX_LEVEL || _ELIX_LEVEL >= 2 */ + + +#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 3 + +int __pthread_mutexattr_getpshared (const pthread_mutexattr_t *attr, + int *pshared) +{ + *pshared = PTHREAD_PROCESS_PRIVATE; + return 0; +} +weak_alias (__pthread_mutexattr_getpshared, pthread_mutexattr_getpshared) + +int __pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared) +{ + if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED) + return EINVAL; + + /* For now it is not possible to shared a conditional variable. */ + if (pshared != PTHREAD_PROCESS_PRIVATE) + return ENOSYS; + + return 0; +} +weak_alias (__pthread_mutexattr_setpshared, pthread_mutexattr_setpshared) + +#endif /* !_ELIX_LEVEL || _ELIX_LEVEL >= 3 */ + +/* Once-only execution */ + +static pthread_mutex_t once_masterlock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t once_finished = PTHREAD_COND_INITIALIZER; +static int fork_generation = 0; /* Child process increments this after fork. */ + +enum { NEVER = 0, IN_PROGRESS = 1, DONE = 2 }; + +/* If a thread is canceled while calling the init_routine out of + pthread once, this handler will reset the once_control variable + to the NEVER state. */ + +static void pthread_once_cancelhandler(void *arg) +{ + pthread_once_t *once_control = arg; + + pthread_mutex_lock(&once_masterlock); + *once_control = NEVER; + pthread_mutex_unlock(&once_masterlock); + pthread_cond_broadcast(&once_finished); +} + +int __pthread_once(pthread_once_t * once_control, void (*init_routine)(void)) +{ + /* flag for doing the condition broadcast outside of mutex */ + int state_changed; + + /* Test without locking first for speed */ + if (*once_control == DONE) { + READ_MEMORY_BARRIER(); + return 0; + } + /* Lock and test again */ + + state_changed = 0; + + pthread_mutex_lock(&once_masterlock); + + /* If this object was left in an IN_PROGRESS state in a parent + process (indicated by stale generation field), reset it to NEVER. */ + if ((*once_control & 3) == IN_PROGRESS && (*once_control & ~3) != fork_generation) + *once_control = NEVER; + + /* If init_routine is being called from another routine, wait until + it completes. */ + while ((*once_control & 3) == IN_PROGRESS) { + pthread_cond_wait(&once_finished, &once_masterlock); + } + /* Here *once_control is stable and either NEVER or DONE. */ + if (*once_control == NEVER) { + *once_control = IN_PROGRESS | fork_generation; + pthread_mutex_unlock(&once_masterlock); + pthread_cleanup_push(pthread_once_cancelhandler, once_control); + init_routine(); + pthread_cleanup_pop(0); + pthread_mutex_lock(&once_masterlock); + WRITE_MEMORY_BARRIER(); + *once_control = DONE; + state_changed = 1; + } + pthread_mutex_unlock(&once_masterlock); + + if (state_changed) + pthread_cond_broadcast(&once_finished); + + return 0; +} +strong_alias (__pthread_once, pthread_once) + +/* + * Handle the state of the pthread_once mechanism across forks. The + * once_masterlock is acquired in the parent process prior to a fork to ensure + * that no thread is in the critical region protected by the lock. After the + * fork, the lock is released. In the child, the lock and the condition + * variable are simply reset. The child also increments its generation + * counter which lets pthread_once calls detect stale IN_PROGRESS states + * and reset them back to NEVER. + */ + +void __pthread_once_fork_prepare(void) +{ + pthread_mutex_lock(&once_masterlock); +} + +void __pthread_once_fork_parent(void) +{ + pthread_mutex_unlock(&once_masterlock); +} + +void __pthread_once_fork_child(void) +{ + pthread_mutex_init(&once_masterlock, NULL); + pthread_cond_init(&once_finished, NULL); + if (fork_generation <= INT_MAX - 4) + fork_generation += 4; /* leave least significant two bits zero */ + else + fork_generation = 0; +} diff --git a/newlib/libc/sys/linux/linuxthreads/no-tsd.c b/newlib/libc/sys/linux/linuxthreads/no-tsd.c new file mode 100644 index 000000000..84abb6f40 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/no-tsd.c @@ -0,0 +1,34 @@ +/* libc-internal interface for thread-specific data. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <sys/cdefs.h> /* for __const */ +#include <bits/libc-tsd.h> + +/* This file provides uinitialized (common) definitions for the + hooks used internally by libc to access thread-specific data. + + When -lpthread is used, it provides initialized definitions for these + variables (in specific.c), which override these uninitialized definitions. + + If -lpthread is not used, these uninitialized variables default to zero, + which the __libc_tsd_* macros check for. */ + +void *(*__libc_internal_tsd_get) (enum __libc_tsd_key_t); +int (*__libc_internal_tsd_set) (enum __libc_tsd_key_t, + __const void *); diff --git a/newlib/libc/sys/linux/linuxthreads/oldsemaphore.c b/newlib/libc/sys/linux/linuxthreads/oldsemaphore.c new file mode 100644 index 000000000..80a82dfcf --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/oldsemaphore.c @@ -0,0 +1,245 @@ +/* + * This file contains the old semaphore code that we need to + * preserve for glibc-2.0 backwards compatibility. Port to glibc 2.1 + * done by Cristian Gafton. + */ + +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Semaphores a la POSIX 1003.1b */ +#include <shlib-compat.h> +#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) + +#include <errno.h> +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include "restart.h" +#include "queue.h" + +typedef struct { + long int sem_status; + int sem_spinlock; +} old_sem_t; + +extern int __old_sem_init (old_sem_t *__sem, int __pshared, unsigned int __value); +extern int __old_sem_wait (old_sem_t *__sem); +extern int __old_sem_trywait (old_sem_t *__sem); +extern int __old_sem_post (old_sem_t *__sem); +extern int __old_sem_getvalue (old_sem_t *__sem, int *__sval); +extern int __old_sem_destroy (old_sem_t *__sem); + + +/* Maximum value the semaphore can have. */ +#define SEM_VALUE_MAX ((int) ((~0u) >> 1)) + +static inline int sem_compare_and_swap(old_sem_t *sem, long oldval, long newval) +{ + return compare_and_swap(&sem->sem_status, oldval, newval, &sem->sem_spinlock); +} + +/* The state of a semaphore is represented by a long int encoding + either the semaphore count if >= 0 and no thread is waiting on it, + or the head of the list of threads waiting for the semaphore. + To distinguish the two cases, we encode the semaphore count N + as 2N+1, so that it has the lowest bit set. + + A sequence of sem_wait operations on a semaphore initialized to N + result in the following successive states: + 2N+1, 2N-1, ..., 3, 1, &first_waiting_thread, &second_waiting_thread, ... +*/ + +static void sem_restart_list(pthread_descr waiting); + +int __old_sem_init(old_sem_t *sem, int pshared, unsigned int value) +{ + if (value > SEM_VALUE_MAX) { + errno = EINVAL; + return -1; + } + if (pshared) { + errno = ENOSYS; + return -1; + } + sem->sem_spinlock = __LT_SPINLOCK_INIT; + sem->sem_status = ((long)value << 1) + 1; + return 0; +} + +/* Function called by pthread_cancel to remove the thread from + waiting inside __old_sem_wait. Here we simply unconditionally + indicate that the thread is to be woken, by returning 1. */ + +static int old_sem_extricate_func(void *obj, pthread_descr th) +{ + return 1; +} + +int __old_sem_wait(old_sem_t * sem) +{ + long oldstatus, newstatus; + volatile pthread_descr self = thread_self(); + pthread_descr * th; + pthread_extricate_if extr; + + /* Set up extrication interface */ + extr.pu_object = 0; + extr.pu_extricate_func = old_sem_extricate_func; + + while (1) { + /* Register extrication interface */ + __pthread_set_own_extricate_if(self, &extr); + do { + oldstatus = sem->sem_status; + if ((oldstatus & 1) && (oldstatus != 1)) + newstatus = oldstatus - 2; + else { + newstatus = (long) self; + self->p_nextwaiting = (pthread_descr) oldstatus; + } + } + while (! sem_compare_and_swap(sem, oldstatus, newstatus)); + if (newstatus & 1) { + /* We got the semaphore. */ + __pthread_set_own_extricate_if(self, 0); + self->p_nextwaiting = NULL; + return 0; + } + /* Wait for sem_post or cancellation */ + suspend(self); + __pthread_set_own_extricate_if(self, 0); + + /* This is a cancellation point */ + if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) { + /* Remove ourselves from the waiting list if we're still on it */ + /* First check if we're at the head of the list. */ + do { + oldstatus = sem->sem_status; + if (oldstatus != (long) self) break; + newstatus = (long) self->p_nextwaiting; + } + while (! sem_compare_and_swap(sem, oldstatus, newstatus)); + /* Now, check if we're somewhere in the list. + There's a race condition with sem_post here, but it does not matter: + the net result is that at the time pthread_exit is called, + self is no longer reachable from sem->sem_status. */ + if (oldstatus != (long) self && (oldstatus & 1) == 0) { + for (th = &(((pthread_descr) oldstatus)->p_nextwaiting); + *th != NULL && *th != (pthread_descr) 1; + th = &((*th)->p_nextwaiting)) { + if (*th == self) { + *th = self->p_nextwaiting; + break; + } + } + } + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + } +} + +int __old_sem_trywait(old_sem_t * sem) +{ + long oldstatus, newstatus; + + do { + oldstatus = sem->sem_status; + if ((oldstatus & 1) == 0 || (oldstatus == 1)) { + errno = EAGAIN; + return -1; + } + newstatus = oldstatus - 2; + } + while (! sem_compare_and_swap(sem, oldstatus, newstatus)); + return 0; +} + +int __old_sem_post(old_sem_t * sem) +{ + long oldstatus, newstatus; + + do { + oldstatus = sem->sem_status; + if ((oldstatus & 1) == 0) + newstatus = 3; + else { + if (oldstatus >= SEM_VALUE_MAX) { + /* Overflow */ + errno = ERANGE; + return -1; + } + newstatus = oldstatus + 2; + } + } + while (! sem_compare_and_swap(sem, oldstatus, newstatus)); + if ((oldstatus & 1) == 0) + sem_restart_list((pthread_descr) oldstatus); + return 0; +} + +int __old_sem_getvalue(old_sem_t * sem, int * sval) +{ + long status = sem->sem_status; + if (status & 1) + *sval = (int)((unsigned long) status >> 1); + else + *sval = 0; + return 0; +} + +int __old_sem_destroy(old_sem_t * sem) +{ + if ((sem->sem_status & 1) == 0) { + errno = EBUSY; + return -1; + } + return 0; +} + +/* Auxiliary function for restarting all threads on a waiting list, + in priority order. */ + +static void sem_restart_list(pthread_descr waiting) +{ + pthread_descr th, towake, *p; + + /* Sort list of waiting threads by decreasing priority (insertion sort) */ + towake = NULL; + while (waiting != (pthread_descr) 1) { + th = waiting; + waiting = waiting->p_nextwaiting; + p = &towake; + while (*p != NULL && th->p_priority < (*p)->p_priority) + p = &((*p)->p_nextwaiting); + th->p_nextwaiting = *p; + *p = th; + } + /* Wake up threads in priority order */ + while (towake != NULL) { + th = towake; + towake = towake->p_nextwaiting; + th->p_nextwaiting = NULL; + restart(th); + } +} + +compat_symbol (libpthread, __old_sem_init, sem_init, GLIBC_2_0); +compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0); +compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0); +compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0); +compat_symbol (libpthread, __old_sem_getvalue, sem_getvalue, GLIBC_2_0); +compat_symbol (libpthread, __old_sem_destroy, sem_destroy, GLIBC_2_0); + +#endif diff --git a/newlib/libc/sys/linux/linuxthreads/posix-timer.h b/newlib/libc/sys/linux/linuxthreads/posix-timer.h new file mode 100644 index 000000000..0596c18f4 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/posix-timer.h @@ -0,0 +1,210 @@ +/* Definitions for POSIX timer implementation on top of LinuxThreads. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kaz Kylheku <kaz@ashi.footprints.net>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <limits.h> +#include <signal.h> +#include <linux/time.h> + +/* Double linked list. */ +struct list_links +{ + struct list_links *next; + struct list_links *prev; +}; + + +/* Forward declaration. */ +struct timer_node; + + +/* Definitions for an internal thread of the POSIX timer implementation. */ +struct thread_node +{ + struct list_links links; + pthread_attr_t attr; + pthread_t id; + unsigned int exists; + struct list_links timer_queue; + pthread_cond_t cond; + struct timer_node *current_timer; + pthread_t captured; + clockid_t clock_id; +}; + + +/* Internal representation of a timer. */ +struct timer_node +{ + struct list_links links; + struct sigevent event; + clockid_t clock; + struct itimerspec value; + struct timespec expirytime; + pthread_attr_t attr; + unsigned int abstime; + unsigned int armed; + enum { + TIMER_FREE, TIMER_INUSE, TIMER_DELETED + } inuse; + struct thread_node *thread; + pid_t creator_pid; + int refcount; +}; + + +/* Static array with the structures for all the timers. */ +extern struct timer_node __timer_array[TIMER_MAX]; + +/* Global lock to protect operation on the lists. */ +extern pthread_mutex_t __timer_mutex; + +/* Variable to protext initialization. */ +extern pthread_once_t __timer_init_once_control; + +/* Nonzero if initialization of timer implementation failed. */ +extern int __timer_init_failed; + +/* Nodes for the threads used to deliver signals. */ +/* A distinct thread is used for each clock type. */ + +extern struct thread_node __timer_signal_thread_rclk; +#ifdef _POSIX_CPUTIME +extern struct thread_node __timer_signal_thread_pclk; +#endif +#ifdef _POSIX_THREAD_CPUTIME +extern struct thread_node __timer_signal_thread_tclk; +#endif + + +/* Return pointer to timer structure corresponding to ID. */ +static inline struct timer_node * +timer_id2ptr (timer_t timerid) +{ + if (timerid >= 0 && timerid < TIMER_MAX) + return &__timer_array[timerid]; + + return NULL; +} + +/* Return ID of TIMER. */ +static inline int +timer_ptr2id (struct timer_node *timer) +{ + return timer - __timer_array; +} + +/* Check whether timer is valid; global mutex must be held. */ +static inline int +timer_valid (struct timer_node *timer) +{ + return timer && timer->inuse == TIMER_INUSE; +} + +/* Timer refcount functions; need global mutex. */ +extern void __timer_dealloc (struct timer_node *timer); + +static inline void +timer_addref (struct timer_node *timer) +{ + timer->refcount++; +} + +static inline void +timer_delref (struct timer_node *timer) +{ + if (--timer->refcount == 0) + __timer_dealloc (timer); +} + +/* Timespec helper routines. */ +static inline int +timespec_compare (const struct timespec *left, const struct timespec *right) +{ + if (left->tv_sec < right->tv_sec) + return -1; + if (left->tv_sec > right->tv_sec) + return 1; + + if (left->tv_nsec < right->tv_nsec) + return -1; + if (left->tv_nsec > right->tv_nsec) + return 1; + + return 0; +} + +static inline void +timespec_add (struct timespec *sum, const struct timespec *left, + const struct timespec *right) +{ + sum->tv_sec = left->tv_sec + right->tv_sec; + sum->tv_nsec = left->tv_nsec + right->tv_nsec; + + if (sum->tv_nsec >= 1000000000) + { + ++sum->tv_sec; + sum->tv_nsec -= 1000000000; + } +} + +static inline void +timespec_sub (struct timespec *diff, const struct timespec *left, + const struct timespec *right) +{ + diff->tv_sec = left->tv_sec - right->tv_sec; + diff->tv_nsec = left->tv_nsec - right->tv_nsec; + + if (diff->tv_nsec < 0) + { + --diff->tv_sec; + diff->tv_nsec += 1000000000; + } +} + + +/* We need one of the list functions in the other modules. */ +static inline void +list_unlink_ip (struct list_links *list) +{ + struct list_links *lnext = list->next, *lprev = list->prev; + + lnext->prev = lprev; + lprev->next = lnext; + + /* The suffix ip means idempotent; list_unlink_ip can be called + * two or more times on the same node. + */ + + list->next = list; + list->prev = list; +} + + +/* Functions in the helper file. */ +extern void __timer_mutex_cancel_handler (void *arg); +extern void __timer_init_once (void); +extern struct timer_node *__timer_alloc (void); +extern int __timer_thread_start (struct thread_node *thread); +extern struct thread_node *__timer_thread_find_matching (const pthread_attr_t *desired_attr, clockid_t); +extern struct thread_node *__timer_thread_alloc (const pthread_attr_t *desired_attr, clockid_t); +extern void __timer_thread_dealloc (struct thread_node *thread); +extern int __timer_thread_queue_timer (struct thread_node *thread, + struct timer_node *insert); +extern void __timer_thread_wakeup (struct thread_node *thread); diff --git a/newlib/libc/sys/linux/linuxthreads/prio.c b/newlib/libc/sys/linux/linuxthreads/prio.c new file mode 100644 index 000000000..475371176 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/prio.c @@ -0,0 +1,65 @@ +#include <stddef.h> +#include <unistd.h> +#include <errno.h> +#include "pthread.h" +#include "internals.h" +#include <bits/posix_opt.h> + +#ifndef _POSIX_THREAD_PRIO_PROTECT +int +__pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attr, + int *priority) +{ + errno = ENOSYS; + return ENOSYS; +} +weak_alias(__pthread_mutexattr_getprotocol,pthread_mutexattr_getprotocol) + +int +__pthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, + int priority) +{ + errno = ENOSYS; + return ENOSYS; +} +weak_alias(__pthread_mutexattr_setprotocol,pthread_mutexattr_setprotocol) + +int +__pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *attr, + int *prioceiling) +{ + errno = ENOSYS; + return ENOSYS; +} +weak_alias(__pthread_mutexattr_getprioceiling,pthread_mutexattr_getprioceiling) + +int +__pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attr, + int prioceiling) +{ + errno = ENOSYS; + return ENOSYS; +} +weak_alias(__pthread_mutexattr_setprioceiling,pthread_mutexattr_setprioceiling) +#endif /* !_POSIX_THREAD_PRIO_PROTECT */ + +#if !defined(_POSIX_THREAD_PRIO_PROTECT) && !defined(_POSIX_THREAD_PRIO_INHERIT) +int +__pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, + int *prioceiling) +{ + errno = ENOSYS; + return ENOSYS; +} +weak_alias(__pthread_mutex_getprioceiling,pthread_mutex_getprioceiling) + +int +__pthread_mutex_setprioceiling (pthread_mutex_t *mutex, + int prioceiling, int *oldceiling) +{ + errno = ENOSYS; + return ENOSYS; +} +weak_alias(__pthread_mutex_setprioceiling,pthread_mutex_setprioceiling) +#endif /* !_POSIX_THREAD_PRIO_PROTECT && !_POSIX_THREAD_PRIO_INHERIT) */ + diff --git a/newlib/libc/sys/linux/linuxthreads/proc_service.h b/newlib/libc/sys/linux/linuxthreads/proc_service.h new file mode 100644 index 000000000..74136c03e --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/proc_service.h @@ -0,0 +1,70 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* The definitions in this file must correspond to those in the debugger. */ +#include <sys/procfs.h> + +typedef enum +{ + PS_OK, /* generic "call succeeded" */ + PS_ERR, /* generic. */ + PS_BADPID, /* bad process handle */ + PS_BADLID, /* bad lwp identifier */ + PS_BADADDR, /* bad address */ + PS_NOSYM, /* p_lookup() could not find given symbol */ + PS_NOFREGS + /* + * FPU register set not available for given + * lwp + */ +} ps_err_e; + + +struct ps_prochandle; /* user defined. */ + + +extern ps_err_e ps_pdread(struct ps_prochandle *, + psaddr_t, void *, size_t); +extern ps_err_e ps_pdwrite(struct ps_prochandle *, + psaddr_t, const void *, size_t); +extern ps_err_e ps_ptread(struct ps_prochandle *, + psaddr_t, void *, size_t); +extern ps_err_e ps_ptwrite(struct ps_prochandle *, + psaddr_t, const void *, size_t); + +extern ps_err_e ps_pglobal_lookup(struct ps_prochandle *, + const char *object_name, const char *sym_name, psaddr_t *sym_addr); + + +extern ps_err_e ps_lgetregs(struct ps_prochandle *, + lwpid_t, prgregset_t); +extern ps_err_e ps_lsetregs(struct ps_prochandle *, + lwpid_t, const prgregset_t); +extern ps_err_e ps_lgetfpregs(struct ps_prochandle *, + lwpid_t, prfpregset_t *); +extern ps_err_e ps_lsetfpregs(struct ps_prochandle *, + lwpid_t, const prfpregset_t *); + +extern pid_t ps_getpid (struct ps_prochandle *); + + +extern ps_err_e ps_pstop (const struct ps_prochandle *); +extern ps_err_e ps_pcontinue (const struct ps_prochandle *); + +extern ps_err_e ps_lstop (const struct ps_prochandle *, lwpid_t); +extern ps_err_e ps_lcontinue (const struct ps_prochandle *, lwpid_t); diff --git a/newlib/libc/sys/linux/linuxthreads/pt-machine.c b/newlib/libc/sys/linux/linuxthreads/pt-machine.c new file mode 100644 index 000000000..f6298c47a --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/pt-machine.c @@ -0,0 +1,25 @@ +/* "Instantiation of machine-dependent pthreads inline functions. + Copyright (C) 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#define PT_EI + +extern long int testandset (int *spinlock); +extern int __compare_and_swap (long int *p, long int oldval, long int newval); + +#include <pt-machine.h> diff --git a/newlib/libc/sys/linux/linuxthreads/ptclock_gettime.c b/newlib/libc/sys/linux/linuxthreads/ptclock_gettime.c new file mode 100644 index 000000000..3323edbcd --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/ptclock_gettime.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <time.h> +#include <libc-internal.h> +#include "internals.h" + + +#if HP_TIMING_AVAIL +int +__pthread_clock_gettime (hp_timing_t freq, struct timespec *tp) +{ + hp_timing_t tsc; + pthread_descr self = thread_self (); + + /* Get the current counter. */ + HP_TIMING_NOW (tsc); + + /* Compute the offset since the start time of the process. */ + tsc -= THREAD_GETMEM (self, p_cpuclock_offset); + + /* Compute the seconds. */ + tp->tv_sec = tsc / freq; + + /* And the nanoseconds. This computation should be stable until + we get machines with about 16GHz frequency. */ + tp->tv_nsec = ((tsc % freq) * 1000000000ull) / freq; + + return 0; +} +#endif diff --git a/newlib/libc/sys/linux/linuxthreads/ptclock_settime.c b/newlib/libc/sys/linux/linuxthreads/ptclock_settime.c new file mode 100644 index 000000000..e293e0dfb --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/ptclock_settime.c @@ -0,0 +1,33 @@ +/* Copyright (C) 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <time.h> +#include <libc-internal.h> +#include "internals.h" + + +#if HP_TIMING_AVAIL +void +__pthread_clock_settime (hp_timing_t offset) +{ + pthread_descr self = thread_self (); + + /* Compute the offset since the start time of the process. */ + THREAD_SETMEM (self, p_cpuclock_offset, offset); +} +#endif diff --git a/newlib/libc/sys/linux/linuxthreads/ptfork.c b/newlib/libc/sys/linux/linuxthreads/ptfork.c new file mode 100644 index 000000000..6e31b772c --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/ptfork.c @@ -0,0 +1,120 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* The "atfork" stuff */ + +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> +#include <unistd.h> +#include "pthread.h" +#include "internals.h" +#include <bits/libc-lock.h> + +struct handler_list { + void (*handler)(void); + struct handler_list * next; +}; + +static pthread_mutex_t pthread_atfork_lock = PTHREAD_MUTEX_INITIALIZER; +static struct handler_list * pthread_atfork_prepare = NULL; +static struct handler_list * pthread_atfork_parent = NULL; +static struct handler_list * pthread_atfork_child = NULL; + +static void pthread_insert_list(struct handler_list ** list, + void (*handler)(void), + struct handler_list * newlist, + int at_end) +{ + if (handler == NULL) return; + if (at_end) { + while(*list != NULL) list = &((*list)->next); + } + newlist->handler = handler; + newlist->next = *list; + *list = newlist; +} + +struct handler_list_block { + struct handler_list prepare, parent, child; +}; + +int __pthread_atfork(void (*prepare)(void), + void (*parent)(void), + void (*child)(void)) +{ + struct handler_list_block * block = + (struct handler_list_block *) malloc(sizeof(struct handler_list_block)); + if (block == NULL) return ENOMEM; + pthread_mutex_lock(&pthread_atfork_lock); + /* "prepare" handlers are called in LIFO */ + pthread_insert_list(&pthread_atfork_prepare, prepare, &block->prepare, 0); + /* "parent" handlers are called in FIFO */ + pthread_insert_list(&pthread_atfork_parent, parent, &block->parent, 1); + /* "child" handlers are called in FIFO */ + pthread_insert_list(&pthread_atfork_child, child, &block->child, 1); + pthread_mutex_unlock(&pthread_atfork_lock); + return 0; +} +strong_alias (__pthread_atfork, pthread_atfork) + +static inline void pthread_call_handlers(struct handler_list * list) +{ + for (/*nothing*/; list != NULL; list = list->next) (list->handler)(); +} + +extern int __libc_fork(void); + +pid_t __fork(void) +{ + pid_t pid; + + pthread_mutex_lock(&pthread_atfork_lock); + + pthread_call_handlers(pthread_atfork_prepare); + __pthread_once_fork_prepare(); + __flockfilelist(); + + pid = __libc_fork(); + + if (pid == 0) { + __pthread_reset_main_thread(); + + __fresetlockfiles(); + __pthread_once_fork_child(); + pthread_call_handlers(pthread_atfork_child); + + pthread_mutex_init(&pthread_atfork_lock, NULL); + } else { + __funlockfilelist(); + __pthread_once_fork_parent(); + pthread_call_handlers(pthread_atfork_parent); + + pthread_mutex_unlock(&pthread_atfork_lock); + } + + return pid; +} + +weak_alias (__fork, fork); + +#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 4 + +pid_t __vfork(void) +{ + return __fork(); +} +weak_alias (__vfork, vfork); + +#endif /* !_ELIX_LEVEL || _ELIX_LEVEL >= 4 */ diff --git a/newlib/libc/sys/linux/linuxthreads/pthread.c b/newlib/libc/sys/linux/linuxthreads/pthread.c new file mode 100644 index 000000000..b42d9d60a --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/pthread.c @@ -0,0 +1,1248 @@ + +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Thread creation, initialization, and basic low-level routines */ + +#include <errno.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/wait.h> +#include <sys/resource.h> +#include <sys/sysctl.h> +#include <shlib-compat.h> +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include "restart.h" +#include <machine/syscall.h> + +/* for threading we use processes so we require a few EL/IX level 2 and + level 3 syscalls. We only allow this file to see them to preserve + the interface. */ +#if defined(_ELIX_LEVEL) && _ELIX_LEVEL < 3 +static _syscall1_base(int,pipe,int *,filedes) +#endif /* _ELIX_LEVEL < 3 */ + +#if defined(_ELIX_LEVEL) && _ELIX_LEVEL < 2 +static _syscall2_base(int,setrlimit,int,resource,const struct rlimit *,rlp) +int on_exit (void (*fn)(int, void *), void *arg) +{ + register struct _atexit *p; + void (*x)(void) = (void (*)(void))fn; + +/* _REENT_SMALL on_exit() doesn't allow more than the required 32 entries. */ +#ifndef _REENT_SMALL + if ((p = _REENT->_atexit) == NULL) + _REENT->_atexit = p = &_REENT->_atexit0; + if (p->_ind >= _ATEXIT_SIZE) + { + if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL) + return -1; + p->_ind = 0; + p->_fntypes = 0; + p->_next = _REENT->_atexit; + _REENT->_atexit = p; + } +#else + p = &_REENT->_atexit; + if (p->_ind >= _ATEXIT_SIZE) + return -1; +#endif + p->_fntypes |= (1 << p->_ind); + p->_fnargs[p->_ind] = arg; + p->_fns[p->_ind++] = x; + return 0; +} + +#endif /* _ELIX_LEVEL < 2 */ + +/* We need the global/static resolver state here. */ +#include <resolv.h> +#undef _res + +/* FIXME: for now, set up _res here */ +struct __res_state _res; + +/* Sanity check. */ +#if __ASSUME_REALTIME_SIGNALS && !defined __SIGRTMIN +# error "This must not happen; new kernel assumed but old headers" +#endif + +/* These variables are used by the setup code. */ + +/* Descriptor of the initial thread */ + +struct _pthread_descr_struct __pthread_initial_thread = { + { + { + &__pthread_initial_thread /* pthread_descr self */ + } + }, + &__pthread_initial_thread, /* pthread_descr p_nextlive */ + &__pthread_initial_thread, /* pthread_descr p_prevlive */ + NULL, /* pthread_descr p_nextwaiting */ + NULL, /* pthread_descr p_nextlock */ + PTHREAD_THREADS_MAX, /* pthread_t p_tid */ + 0, /* int p_pid */ + 0, /* int p_priority */ + &__pthread_handles[0].h_lock, /* struct _pthread_fastlock * p_lock */ + 0, /* int p_signal */ + NULL, /* sigjmp_buf * p_signal_buf */ + NULL, /* sigjmp_buf * p_cancel_buf */ + 0, /* char p_terminated */ + 0, /* char p_detached */ + 0, /* char p_exited */ + NULL, /* void * p_retval */ + 0, /* int p_retval */ + NULL, /* pthread_descr p_joining */ + NULL, /* struct _pthread_cleanup_buffer * p_cleanup */ + 0, /* char p_cancelstate */ + 0, /* char p_canceltype */ + 0, /* char p_canceled */ + &__pthread_initial_thread.p_reent, /* struct _reent *p_reentp */ + _REENT_INIT(__pthread_initial_thread.p_reent), /* struct _reent p_reent */ + NULL, /* int *p_h_errnop */ + 0, /* int p_h_errno */ + NULL, /* char * p_in_sighandler */ + 0, /* char p_sigwaiting */ + PTHREAD_START_ARGS_INITIALIZER(NULL), + /* struct pthread_start_args p_start_args */ + {NULL}, /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */ + {NULL}, /* void * p_libc_specific[_LIBC_TSD_KEY_N] */ + 1, /* int p_userstack */ + NULL, /* void * p_guardaddr */ + 0, /* size_t p_guardsize */ + 0, /* Always index 0 */ + 0, /* int p_report_events */ + {{{0, }}, 0, NULL}, /* td_eventbuf_t p_eventbuf */ + __ATOMIC_INITIALIZER, /* struct pthread_atomic p_resume_count */ + 0, /* char p_woken_by_cancel */ + 0, /* char p_condvar_avail */ + 0, /* char p_sem_avail */ + NULL, /* struct pthread_extricate_if *p_extricate */ + NULL, /* pthread_readlock_info *p_readlock_list; */ + NULL, /* pthread_readlock_info *p_readlock_free; */ + 0 /* int p_untracked_readlock_count; */ +}; + +/* Descriptor of the manager thread; none of this is used but the error + variables, the p_pid and p_priority fields, + and the address for identification. */ + +struct _pthread_descr_struct __pthread_manager_thread = { + { + { + &__pthread_manager_thread /* pthread_descr self */ + } + }, + NULL, /* pthread_descr p_nextlive */ + NULL, /* pthread_descr p_prevlive */ + NULL, /* pthread_descr p_nextwaiting */ + NULL, /* pthread_descr p_nextlock */ + 0, /* int p_tid */ + 0, /* int p_pid */ + 0, /* int p_priority */ + &__pthread_handles[1].h_lock, /* struct _pthread_fastlock * p_lock */ + 0, /* int p_signal */ + NULL, /* sigjmp_buf * p_signal_buf */ + NULL, /* sigjmp_buf * p_cancel_buf */ + 0, /* char p_terminated */ + 0, /* char p_detached */ + 0, /* char p_exited */ + NULL, /* void * p_retval */ + 0, /* int p_retval */ + NULL, /* pthread_descr p_joining */ + NULL, /* struct _pthread_cleanup_buffer * p_cleanup */ + 0, /* char p_cancelstate */ + 0, /* char p_canceltype */ + 0, /* char p_canceled */ + &__pthread_manager_thread.p_reent, /* struct _reent *p_reentp */ + _REENT_INIT(__pthread_manager_thread.p_reent), /* struct _reent p_reent */ + NULL, /* int *p_h_errnop */ + 0, /* int p_h_errno */ + NULL, /* char * p_in_sighandler */ + 0, /* char p_sigwaiting */ + PTHREAD_START_ARGS_INITIALIZER(__pthread_manager), + /* struct pthread_start_args p_start_args */ + {NULL}, /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */ + {NULL}, /* void * p_libc_specific[_LIBC_TSD_KEY_N] */ + 0, /* int p_userstack */ + NULL, /* void * p_guardaddr */ + 0, /* size_t p_guardsize */ + 1, /* Always index 1 */ + 0, /* int p_report_events */ + {{{0, }}, 0, NULL}, /* td_eventbuf_t p_eventbuf */ + __ATOMIC_INITIALIZER, /* struct pthread_atomic p_resume_count */ + 0, /* char p_woken_by_cancel */ + 0, /* char p_condvar_avail */ + 0, /* char p_sem_avail */ + NULL, /* struct pthread_extricate_if *p_extricate */ + NULL, /* pthread_readlock_info *p_readlock_list; */ + NULL, /* pthread_readlock_info *p_readlock_free; */ + 0 /* int p_untracked_readlock_count; */ +}; + +/* Pointer to the main thread (the father of the thread manager thread) */ +/* Originally, this is the initial thread, but this changes after fork() */ + +pthread_descr __pthread_main_thread = &__pthread_initial_thread; + +/* Limit between the stack of the initial thread (above) and the + stacks of other threads (below). Aligned on a STACK_SIZE boundary. */ + +char *__pthread_initial_thread_bos; + +/* File descriptor for sending requests to the thread manager. */ +/* Initially -1, meaning that the thread manager is not running. */ + +int __pthread_manager_request = -1; + +/* Other end of the pipe for sending requests to the thread manager. */ + +int __pthread_manager_reader; + +/* Limits of the thread manager stack */ + +char *__pthread_manager_thread_bos; +char *__pthread_manager_thread_tos; + +/* For process-wide exit() */ + +int __pthread_exit_requested; +int __pthread_exit_code; + +/* Maximum stack size. */ +size_t __pthread_max_stacksize; + +/* Nozero if the machine has more than one processor. */ +int __pthread_smp_kernel; + + +#if !__ASSUME_REALTIME_SIGNALS +/* Pointers that select new or old suspend/resume functions + based on availability of rt signals. */ + +void (*__pthread_restart)(pthread_descr) = __pthread_restart_old; +void (*__pthread_suspend)(pthread_descr) = __pthread_suspend_old; +int (*__pthread_timedsuspend)(pthread_descr, const struct timespec *) = __pthread_timedsuspend_old; +#endif /* __ASSUME_REALTIME_SIGNALS */ + +/* Communicate relevant LinuxThreads constants to gdb */ + +const int __pthread_threads_max = PTHREAD_THREADS_MAX; +const int __pthread_sizeof_handle = sizeof(struct pthread_handle_struct); +const int __pthread_offsetof_descr = offsetof(struct pthread_handle_struct, + h_descr); +const int __pthread_offsetof_pid = offsetof(struct _pthread_descr_struct, + p_pid); +const int __linuxthreads_pthread_sizeof_descr + = sizeof(struct _pthread_descr_struct); + +/* Forward declarations */ + +static void pthread_onexit_process(int retcode, void *arg); +#ifndef HAVE_Z_NODELETE +static void pthread_atexit_process(void *arg, int retcode); +static void pthread_atexit_retcode(void *arg, int retcode); +#endif +static void pthread_handle_sigcancel(int sig); +static void pthread_handle_sigrestart(int sig); +static void pthread_handle_sigdebug(int sig); + +/* CPU clock handling. */ +#if HP_TIMING_AVAIL +extern hp_timing_t _dl_cpuclock_offset; +#endif + +/* Signal numbers used for the communication. + In these variables we keep track of the used variables. If the + platform does not support any real-time signals we will define the + values to some unreasonable value which will signal failing of all + the functions below. */ +#ifndef __SIGRTMIN +static int current_rtmin = -1; +static int current_rtmax = -1; +int __pthread_sig_restart = SIGUSR1; +int __pthread_sig_cancel = SIGUSR2; +int __pthread_sig_debug; +#else +static int current_rtmin; +static int current_rtmax; + +#if __SIGRTMAX - __SIGRTMIN >= 3 +int __pthread_sig_restart = __SIGRTMIN; +int __pthread_sig_cancel = __SIGRTMIN + 1; +int __pthread_sig_debug = __SIGRTMIN + 2; +#else +int __pthread_sig_restart = SIGUSR1; +int __pthread_sig_cancel = SIGUSR2; +int __pthread_sig_debug; +#endif + +static int rtsigs_initialized; + +#if !__ASSUME_REALTIME_SIGNALS +# include "testrtsig.h" +#endif + +static void +init_rtsigs (void) +{ +#if !__ASSUME_REALTIME_SIGNALS + if (__builtin_expect (!kernel_has_rtsig (), 0)) + { + current_rtmin = -1; + current_rtmax = -1; +# if __SIGRTMAX - __SIGRTMIN >= 3 + __pthread_sig_restart = SIGUSR1; + __pthread_sig_cancel = SIGUSR2; + __pthread_sig_debug = 0; +# endif + } + else +#endif /* __ASSUME_REALTIME_SIGNALS */ + { +#if __SIGRTMAX - __SIGRTMIN >= 3 + current_rtmin = __SIGRTMIN + 3; +# if !__ASSUME_REALTIME_SIGNALS + __pthread_restart = __pthread_restart_new; + __pthread_suspend = __pthread_wait_for_restart_signal; + __pthread_timedsuspend = __pthread_timedsuspend_new; +# endif /* __ASSUME_REALTIME_SIGNALS */ +#else + current_rtmin = __SIGRTMIN; +#endif + + current_rtmax = __SIGRTMAX; + } + + rtsigs_initialized = 1; +} +#endif + +/* Return number of available real-time signal with highest priority. */ +int +__libc_current_sigrtmin (void) +{ +#ifdef __SIGRTMIN + if (__builtin_expect (!rtsigs_initialized, 0)) + init_rtsigs (); +#endif + return current_rtmin; +} + +/* Return number of available real-time signal with lowest priority. */ +int +__libc_current_sigrtmax (void) +{ +#ifdef __SIGRTMIN + if (__builtin_expect (!rtsigs_initialized, 0)) + init_rtsigs (); +#endif + return current_rtmax; +} + +/* Allocate real-time signal with highest/lowest available + priority. Please note that we don't use a lock since we assume + this function to be called at program start. */ +int +__libc_allocate_rtsig (int high) +{ +#ifndef __SIGRTMIN + return -1; +#else + if (__builtin_expect (!rtsigs_initialized, 0)) + init_rtsigs (); + if (__builtin_expect (current_rtmin == -1, 0) + || __builtin_expect (current_rtmin > current_rtmax, 0)) + /* We don't have anymore signal available. */ + return -1; + + return high ? current_rtmin++ : current_rtmax--; +#endif +} + +/* The function we use to get the kernel revision. */ +extern int __sysctl (int *name, int nlen, void *oldval, size_t *oldlenp, + void *newval, size_t newlen); + +/* Test whether the machine has more than one processor. This is not the + best test but good enough. More complicated tests would require `malloc' + which is not available at that time. */ +static int +is_smp_system (void) +{ + static const int sysctl_args[] = { CTL_KERN, KERN_VERSION }; + char buf[512]; + size_t reslen = sizeof (buf); + + /* Try reading the number using `sysctl' first. */ + if (__sysctl ((int *) sysctl_args, + sizeof (sysctl_args) / sizeof (sysctl_args[0]), + buf, &reslen, NULL, 0) < 0) + { + /* This was not successful. Now try reading the /proc filesystem. */ + int fd = __open ("/proc/sys/kernel/version", O_RDONLY); + if (__builtin_expect (fd, 0) == -1 + || (reslen = __read (fd, buf, sizeof (buf))) <= 0) + /* This also didn't work. We give up and say it's a UP machine. */ + buf[0] = '\0'; + + __close (fd); + } + + return strstr (buf, "SMP") != NULL; +} + + +/* Initialize the pthread library. + Initialization is split in two functions: + - a constructor function that blocks the __pthread_sig_restart signal + (must do this very early, since the program could capture the signal + mask with e.g. sigsetjmp before creating the first thread); + - a regular function called from pthread_create when needed. */ + +static void pthread_initialize(void) __attribute__((constructor)); + +#ifndef HAVE_Z_NODELETE +extern void *__dso_handle __attribute__ ((weak)); +#endif + + +/* Do some minimal initialization which has to be done during the + startup of the C library. */ +void +__pthread_initialize_minimal(void) +{ + /* If we have special thread_self processing, initialize that for the + main thread now. */ +#ifdef INIT_THREAD_SELF + INIT_THREAD_SELF(&__pthread_initial_thread, 0); +#endif +#if HP_TIMING_AVAIL + __pthread_initial_thread.p_cpuclock_offset = _dl_cpuclock_offset; +#endif +} + + +void +__pthread_init_max_stacksize(void) +{ + struct rlimit limit; + size_t max_stack; + + getrlimit(RLIMIT_STACK, &limit); +#ifdef FLOATING_STACKS + if (limit.rlim_cur == RLIM_INFINITY) + limit.rlim_cur = ARCH_STACK_MAX_SIZE; +# ifdef NEED_SEPARATE_REGISTER_STACK + max_stack = limit.rlim_cur / 2; +# else + max_stack = limit.rlim_cur; +# endif +#else + /* Play with the stack size limit to make sure that no stack ever grows + beyond STACK_SIZE minus one page (to act as a guard page). */ +# ifdef NEED_SEPARATE_REGISTER_STACK + /* STACK_SIZE bytes hold both the main stack and register backing + store. The rlimit value applies to each individually. */ + max_stack = STACK_SIZE/2 - __getpagesize (); +# else + max_stack = STACK_SIZE - __getpagesize(); +# endif + if (limit.rlim_cur > max_stack) { + limit.rlim_cur = max_stack; + __libc_setrlimit(RLIMIT_STACK, &limit); + } +#endif + __pthread_max_stacksize = max_stack; +} + + +static void pthread_initialize(void) +{ + struct sigaction sa; + sigset_t mask; + + /* If already done (e.g. by a constructor called earlier!), bail out */ + if (__pthread_initial_thread_bos != NULL) return; +#ifdef TEST_FOR_COMPARE_AND_SWAP + /* Test if compare-and-swap is available */ + __pthread_has_cas = compare_and_swap_is_available(); +#endif +#ifdef FLOATING_STACKS + /* We don't need to know the bottom of the stack. Give the pointer some + value to signal that initialization happened. */ + __pthread_initial_thread_bos = (void *) -1l; +#else + /* Determine stack size limits . */ + __pthread_init_max_stacksize (); +# ifdef _STACK_GROWS_UP + /* The initial thread already has all the stack it needs */ + __pthread_initial_thread_bos = (char *) + ((long)CURRENT_STACK_FRAME &~ (STACK_SIZE - 1)); +# else + /* For the initial stack, reserve at least STACK_SIZE bytes of stack + below the current stack address, and align that on a + STACK_SIZE boundary. */ + __pthread_initial_thread_bos = + (char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1)); +# endif +#endif + /* Update the descriptor for the initial thread. */ + __pthread_initial_thread.p_pid = __getpid(); + /* Likewise for the resolver state _res. */ + __pthread_initial_thread.p_resp = &_res; +#ifdef __SIGRTMIN + /* Initialize real-time signals. */ + init_rtsigs (); +#endif + /* Setup signal handlers for the initial thread. + Since signal handlers are shared between threads, these settings + will be inherited by all other threads. */ + sa.sa_handler = pthread_handle_sigrestart; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + __libc_sigaction(__pthread_sig_restart, &sa, NULL); + sa.sa_handler = pthread_handle_sigcancel; + // sa.sa_flags = 0; + __libc_sigaction(__pthread_sig_cancel, &sa, NULL); + if (__pthread_sig_debug > 0) { + sa.sa_handler = pthread_handle_sigdebug; + sigemptyset(&sa.sa_mask); + // sa.sa_flags = 0; + __libc_sigaction(__pthread_sig_debug, &sa, NULL); + } + /* Initially, block __pthread_sig_restart. Will be unblocked on demand. */ + sigemptyset(&mask); + sigaddset(&mask, __pthread_sig_restart); + sigprocmask(SIG_BLOCK, &mask, NULL); + /* Register an exit function to kill all other threads. */ + /* Do it early so that user-registered atexit functions are called + before pthread_*exit_process. */ +#ifndef HAVE_Z_NODELETE + if (__builtin_expect (&__dso_handle != NULL, 1)) + __cxa_atexit ((void (*) (void *)) pthread_atexit_process, NULL, + __dso_handle); + else +#endif + on_exit (pthread_onexit_process, NULL); + /* How many processors. */ + __pthread_smp_kernel = is_smp_system (); +} + +void __pthread_initialize(void) +{ + pthread_initialize(); +} + +int __pthread_initialize_manager(void) +{ + int manager_pipe[2]; + int pid; + struct pthread_request request; + +#ifndef HAVE_Z_NODELETE + if (__builtin_expect (&__dso_handle != NULL, 1)) + __cxa_atexit ((void (*) (void *)) pthread_atexit_retcode, NULL, + __dso_handle); +#endif + + if (__pthread_max_stacksize == 0) + __pthread_init_max_stacksize (); + /* If basic initialization not done yet (e.g. we're called from a + constructor run before our constructor), do it now */ + if (__pthread_initial_thread_bos == NULL) pthread_initialize(); + /* Setup stack for thread manager */ + __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE); + if (__pthread_manager_thread_bos == NULL) return -1; + __pthread_manager_thread_tos = + __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE; + /* Setup pipe to communicate with thread manager */ + if (__libc_pipe(manager_pipe) == -1) { + free(__pthread_manager_thread_bos); + return -1; + } + /* Start the thread manager */ + pid = 0; + if (__builtin_expect (__pthread_initial_thread.p_report_events, 0)) + { + /* It's a bit more complicated. We have to report the creation of + the manager thread. */ + int idx = __td_eventword (TD_CREATE); + uint32_t mask = __td_eventmask (TD_CREATE); + + if ((mask & (__pthread_threads_events.event_bits[idx] + | __pthread_initial_thread.p_eventbuf.eventmask.event_bits[idx])) + != 0) + { + __pthread_lock(__pthread_manager_thread.p_lock, NULL); + +#ifdef NEED_SEPARATE_REGISTER_STACK + pid = __clone2(__pthread_manager_event, + (void **) __pthread_manager_thread_bos, + THREAD_MANAGER_STACK_SIZE, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + (void *)(long)manager_pipe[0]); +#elif _STACK_GROWS_UP + pid = __clone(__pthread_manager_event, + (void **) __pthread_manager_thread_bos, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + (void *)(long)manager_pipe[0]); +#else + pid = __clone(__pthread_manager_event, + (void **) __pthread_manager_thread_tos, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + (void *)(long)manager_pipe[0]); +#endif + + if (pid != -1) + { + /* Now fill in the information about the new thread in + the newly created thread's data structure. We cannot let + the new thread do this since we don't know whether it was + already scheduled when we send the event. */ + __pthread_manager_thread.p_eventbuf.eventdata = + &__pthread_manager_thread; + __pthread_manager_thread.p_eventbuf.eventnum = TD_CREATE; + __pthread_last_event = &__pthread_manager_thread; + __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1; + __pthread_manager_thread.p_pid = pid; + + /* Now call the function which signals the event. */ + __linuxthreads_create_event (); + } + + /* Now restart the thread. */ + __pthread_unlock(__pthread_manager_thread.p_lock); + } + } + + if (__builtin_expect (pid, 0) == 0) + { +#ifdef NEED_SEPARATE_REGISTER_STACK + pid = __clone2(__pthread_manager, (void **) __pthread_manager_thread_bos, + THREAD_MANAGER_STACK_SIZE, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + (void *)(long)manager_pipe[0]); +#elif _STACK_GROWS_UP + pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_bos, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + (void *)(long)manager_pipe[0]); +#else + pid = __clone(__pthread_manager, (void **) __pthread_manager_thread_tos, + CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, + (void *)(long)manager_pipe[0]); +#endif + } + if (__builtin_expect (pid, 0) == -1) { + free(__pthread_manager_thread_bos); + __libc_close(manager_pipe[0]); + __libc_close(manager_pipe[1]); + return -1; + } + __pthread_manager_request = manager_pipe[1]; /* writing end */ + __pthread_manager_reader = manager_pipe[0]; /* reading end */ + __pthread_manager_thread.p_tid = 2* PTHREAD_THREADS_MAX + 1; + __pthread_manager_thread.p_pid = pid; + /* Make gdb aware of new thread manager */ + if (__builtin_expect (__pthread_threads_debug, 0) && __pthread_sig_debug > 0) + { + raise(__pthread_sig_debug); + /* We suspend ourself and gdb will wake us up when it is + ready to handle us. */ + __pthread_wait_for_restart_signal(thread_self()); + } + /* Synchronize debugging of the thread manager */ + request.req_kind = REQ_DEBUG; + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + return 0; +} + +/* Thread creation */ + +int __pthread_create_2_1(pthread_t *thread, const pthread_attr_t *attr, + void * (*start_routine)(void *), void *arg) +{ + pthread_descr self = thread_self(); + struct pthread_request request; + int retval; + if (__builtin_expect (__pthread_manager_request, 0) < 0) { + if (__pthread_initialize_manager() < 0) return EAGAIN; + } + request.req_thread = self; + request.req_kind = REQ_CREATE; + request.req_args.create.attr = attr; + request.req_args.create.fn = start_routine; + request.req_args.create.arg = arg; + sigprocmask(SIG_SETMASK, (const sigset_t *) NULL, + &request.req_args.create.mask); + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + suspend(self); + retval = THREAD_GETMEM(self, p_retcode); + if (__builtin_expect (retval, 0) == 0) + *thread = (pthread_t) THREAD_GETMEM(self, p_retval); + return retval; +} + +versioned_symbol (libpthread, __pthread_create_2_1, pthread_create, GLIBC_2_1); + +#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1) + +int __pthread_create_2_0(pthread_t *thread, const pthread_attr_t *attr, + void * (*start_routine)(void *), void *arg) +{ + /* The ATTR attribute is not really of type `pthread_attr_t *'. It has + the old size and access to the new members might crash the program. + We convert the struct now. */ + pthread_attr_t new_attr; + + if (attr != NULL) + { + size_t ps = __getpagesize (); + + memcpy (&new_attr, attr, + (size_t) &(((pthread_attr_t*)NULL)->__guardsize)); + new_attr.__guardsize = ps; + new_attr.__stackaddr_set = 0; + new_attr.__stackaddr = NULL; + new_attr.__stacksize = STACK_SIZE - ps; + attr = &new_attr; + } + return __pthread_create_2_1 (thread, attr, start_routine, arg); +} +compat_symbol (libpthread, __pthread_create_2_0, pthread_create, GLIBC_2_0); +#endif + +/* Simple operations on thread identifiers */ + +pthread_t pthread_self(void) +{ + pthread_descr self = thread_self(); + return THREAD_GETMEM(self, p_tid); +} + +int pthread_equal(pthread_t thread1, pthread_t thread2) +{ + return thread1 == thread2; +} + +/* Helper function for thread_self in the case of user-provided stacks */ + +#ifndef THREAD_SELF + +pthread_descr __pthread_find_self(void) +{ + char * sp = CURRENT_STACK_FRAME; + pthread_handle h; + + /* __pthread_handles[0] is the initial thread, __pthread_handles[1] is + the manager threads handled specially in thread_self(), so start at 2 */ + h = __pthread_handles + 2; + while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) h++; + return h->h_descr; +} + +#else + +static pthread_descr thread_self_stack(void) +{ + char *sp = CURRENT_STACK_FRAME; + pthread_handle h; + + if (sp >= __pthread_manager_thread_bos && sp < __pthread_manager_thread_tos) + return &__pthread_manager_thread; + h = __pthread_handles + 2; + while (! (sp <= (char *) h->h_descr && sp >= h->h_bottom)) + h++; + return h->h_descr; +} + +#endif + +/* Thread scheduling */ + +int pthread_setschedparam(pthread_t thread, int policy, + const struct sched_param *param) +{ + pthread_handle handle = thread_handle(thread); + pthread_descr th; + + __pthread_lock(&handle->h_lock, NULL); + if (__builtin_expect (invalid_handle(handle, thread), 0)) { + __pthread_unlock(&handle->h_lock); + return ESRCH; + } + th = handle->h_descr; + if (__builtin_expect (__sched_setscheduler(th->p_pid, policy, param) == -1, + 0)) { + __pthread_unlock(&handle->h_lock); + return errno; + } + th->p_priority = policy == SCHED_OTHER ? 0 : param->sched_priority; + __pthread_unlock(&handle->h_lock); + if (__pthread_manager_request >= 0) + __pthread_manager_adjust_prio(th->p_priority); + return 0; +} + +int pthread_getschedparam(pthread_t thread, int *policy, + struct sched_param *param) +{ + pthread_handle handle = thread_handle(thread); + int pid, pol; + + __pthread_lock(&handle->h_lock, NULL); + if (__builtin_expect (invalid_handle(handle, thread), 0)) { + __pthread_unlock(&handle->h_lock); + return ESRCH; + } + pid = handle->h_descr->p_pid; + __pthread_unlock(&handle->h_lock); + pol = __sched_getscheduler(pid); + if (__builtin_expect (pol, 0) == -1) return errno; + if (__sched_getparam(pid, param) == -1) return errno; + *policy = pol; + return 0; +} + +int __pthread_yield (void) +{ + /* For now this is equivalent with the POSIX call. */ + return sched_yield (); +} +weak_alias (__pthread_yield, pthread_yield) + +/* Process-wide exit() request */ + +static void pthread_onexit_process(int retcode, void *arg) +{ + if (__builtin_expect (__pthread_manager_request, 0) >= 0) { + struct pthread_request request; + pthread_descr self = thread_self(); + + request.req_thread = self; + request.req_kind = REQ_PROCESS_EXIT; + request.req_args.exit.code = retcode; + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + suspend(self); + /* Main thread should accumulate times for thread manager and its + children, so that timings for main thread account for all threads. */ + if (self == __pthread_main_thread) + { + __waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE); + /* Since all threads have been asynchronously terminated + (possibly holding locks), free cannot be used any more. */ + /*free (__pthread_manager_thread_bos);*/ + __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL; + } + } +} + +#ifndef HAVE_Z_NODELETE +static int __pthread_atexit_retcode; + +static void pthread_atexit_process(void *arg, int retcode) +{ + pthread_onexit_process (retcode ?: __pthread_atexit_retcode, arg); +} + +static void pthread_atexit_retcode(void *arg, int retcode) +{ + __pthread_atexit_retcode = retcode; +} +#endif + +/* The handler for the RESTART signal just records the signal received + in the thread descriptor, and optionally performs a siglongjmp + (for pthread_cond_timedwait). */ + +static void pthread_handle_sigrestart(int sig) +{ + pthread_descr self = thread_self(); + THREAD_SETMEM(self, p_signal, sig); + if (THREAD_GETMEM(self, p_signal_jmp) != NULL) + siglongjmp(*THREAD_GETMEM(self, p_signal_jmp), 1); +} + +/* The handler for the CANCEL signal checks for cancellation + (in asynchronous mode), for process-wide exit and exec requests. + For the thread manager thread, redirect the signal to + __pthread_manager_sighandler. */ + +static void pthread_handle_sigcancel(int sig) +{ + pthread_descr self = thread_self(); + sigjmp_buf * jmpbuf; + + if (self == &__pthread_manager_thread) + { +#ifdef THREAD_SELF + /* A new thread might get a cancel signal before it is fully + initialized, so that the thread register might still point to the + manager thread. Double check that this is really the manager + thread. */ + pthread_descr real_self = thread_self_stack(); + if (real_self == &__pthread_manager_thread) + { + __pthread_manager_sighandler(sig); + return; + } + /* Oops, thread_self() isn't working yet.. */ + self = real_self; +# ifdef INIT_THREAD_SELF + INIT_THREAD_SELF(self, self->p_nr); +# endif +#else + __pthread_manager_sighandler(sig); + return; +#endif + } + if (__builtin_expect (__pthread_exit_requested, 0)) { + /* Main thread should accumulate times for thread manager and its + children, so that timings for main thread account for all threads. */ + if (self == __pthread_main_thread) + __waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE); + _exit(__pthread_exit_code); + } + if (__builtin_expect (THREAD_GETMEM(self, p_canceled), 0) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { + if (THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS) + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + jmpbuf = THREAD_GETMEM(self, p_cancel_jmp); + if (jmpbuf != NULL) { + THREAD_SETMEM(self, p_cancel_jmp, NULL); + siglongjmp(*jmpbuf, 1); + } + } +} + +/* Handler for the DEBUG signal. + The debugging strategy is as follows: + On reception of a REQ_DEBUG request (sent by new threads created to + the thread manager under debugging mode), the thread manager throws + __pthread_sig_debug to itself. The debugger (if active) intercepts + this signal, takes into account new threads and continue execution + of the thread manager by propagating the signal because it doesn't + know what it is specifically done for. In the current implementation, + the thread manager simply discards it. */ + +static void pthread_handle_sigdebug(int sig) +{ + /* Nothing */ +} + +/* Reset the state of the thread machinery after a fork(). + Close the pipe used for requests and set the main thread to the forked + thread. + Notice that we can't free the stack segments, as the forked thread + may hold pointers into them. */ + +void __pthread_reset_main_thread(void) +{ + pthread_descr self = thread_self(); + struct rlimit limit; + + if (__pthread_manager_request != -1) { + /* Free the thread manager stack */ + free(__pthread_manager_thread_bos); + __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL; + /* Close the two ends of the pipe */ + __libc_close(__pthread_manager_request); + __libc_close(__pthread_manager_reader); + __pthread_manager_request = __pthread_manager_reader = -1; + } + + /* Update the pid of the main thread */ + THREAD_SETMEM(self, p_pid, __getpid()); + /* Make the forked thread the main thread */ + __pthread_main_thread = self; + THREAD_SETMEM(self, p_nextlive, self); + THREAD_SETMEM(self, p_prevlive, self); + /* Now this thread modifies the global variables. */ + THREAD_SETMEM(self, p_resp, &_res); + + if (getrlimit (RLIMIT_STACK, &limit) == 0 + && limit.rlim_cur != limit.rlim_max) { + limit.rlim_cur = limit.rlim_max; + __libc_setrlimit(RLIMIT_STACK, &limit); + } +} + +/* Process-wide exec() request */ + +#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2 + +void __pthread_kill_other_threads_np(void) +{ + struct sigaction sa; + /* Terminate all other threads and thread manager */ + pthread_onexit_process(0, NULL); + /* Make current thread the main thread in case the calling thread + changes its mind, does not exec(), and creates new threads instead. */ + __pthread_reset_main_thread(); + + /* Reset the signal handlers behaviour for the signals the + implementation uses since this would be passed to the new + process. */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + __libc_sigaction(__pthread_sig_restart, &sa, NULL); + __libc_sigaction(__pthread_sig_cancel, &sa, NULL); + if (__pthread_sig_debug > 0) + __libc_sigaction(__pthread_sig_debug, &sa, NULL); +} +weak_alias (__pthread_kill_other_threads_np, pthread_kill_other_threads_np) + +#endif /* !_ELIX_LEVEL || _ELIX_LEVEL >= 2 */ + +/* Concurrency symbol level. */ +static int current_level; + +int __pthread_setconcurrency(int level) +{ + /* We don't do anything unless we have found a useful interpretation. */ + current_level = level; + return 0; +} +weak_alias (__pthread_setconcurrency, pthread_setconcurrency) + +int __pthread_getconcurrency(void) +{ + return current_level; +} +weak_alias (__pthread_getconcurrency, pthread_getconcurrency) + +/* Primitives for controlling thread execution */ + +void __pthread_wait_for_restart_signal(pthread_descr self) +{ + sigset_t mask; + + sigprocmask(SIG_SETMASK, NULL, &mask); /* Get current signal mask */ + sigdelset(&mask, __pthread_sig_restart); /* Unblock the restart signal */ + THREAD_SETMEM(self, p_signal, 0); + do { + sigsuspend(&mask); /* Wait for signal */ + } while (THREAD_GETMEM(self, p_signal) !=__pthread_sig_restart); + + READ_MEMORY_BARRIER(); /* See comment in __pthread_restart_new */ +} + +#if !__ASSUME_REALTIME_SIGNALS +/* The _old variants are for 2.0 and early 2.1 kernels which don't have RT + signals. + On these kernels, we use SIGUSR1 and SIGUSR2 for restart and cancellation. + Since the restart signal does not queue, we use an atomic counter to create + queuing semantics. This is needed to resolve a rare race condition in + pthread_cond_timedwait_relative. */ + +void __pthread_restart_old(pthread_descr th) +{ + if (atomic_increment(&th->p_resume_count) == -1) + kill(th->p_pid, __pthread_sig_restart); +} + +void __pthread_suspend_old(pthread_descr self) +{ + if (atomic_decrement(&self->p_resume_count) <= 0) + __pthread_wait_for_restart_signal(self); +} + +int +__pthread_timedsuspend_old(pthread_descr self, const struct timespec *abstime) +{ + sigset_t unblock, initial_mask; + int was_signalled = 0; + sigjmp_buf jmpbuf; + + if (atomic_decrement(&self->p_resume_count) == 0) { + /* Set up a longjmp handler for the restart signal, unblock + the signal and sleep. */ + + if (sigsetjmp(jmpbuf, 1) == 0) { + THREAD_SETMEM(self, p_signal_jmp, &jmpbuf); + THREAD_SETMEM(self, p_signal, 0); + /* Unblock the restart signal */ + sigemptyset(&unblock); + sigaddset(&unblock, __pthread_sig_restart); + sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask); + + while (1) { + struct timeval now; + struct timespec reltime; + + /* Compute a time offset relative to now. */ + __gettimeofday (&now, NULL); + reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000; + reltime.tv_sec = abstime->tv_sec - now.tv_sec; + if (reltime.tv_nsec < 0) { + reltime.tv_nsec += 1000000000; + reltime.tv_sec -= 1; + } + + /* Sleep for the required duration. If woken by a signal, + resume waiting as required by Single Unix Specification. */ + if (reltime.tv_sec < 0 || __libc_nanosleep(&reltime, NULL) == 0) + break; + } + + /* Block the restart signal again */ + sigprocmask(SIG_SETMASK, &initial_mask, NULL); + was_signalled = 0; + } else { + was_signalled = 1; + } + THREAD_SETMEM(self, p_signal_jmp, NULL); + } + + /* Now was_signalled is true if we exited the above code + due to the delivery of a restart signal. In that case, + we know we have been dequeued and resumed and that the + resume count is balanced. Otherwise, there are some + cases to consider. First, try to bump up the resume count + back to zero. If it goes to 1, it means restart() was + invoked on this thread. The signal must be consumed + and the count bumped down and everything is cool. We + can return a 1 to the caller. + Otherwise, no restart was delivered yet, so a potential + race exists; we return a 0 to the caller which must deal + with this race in an appropriate way; for example by + atomically removing the thread from consideration for a + wakeup---if such a thing fails, it means a restart is + being delivered. */ + + if (!was_signalled) { + if (atomic_increment(&self->p_resume_count) != -1) { + __pthread_wait_for_restart_signal(self); + atomic_decrement(&self->p_resume_count); /* should be zero now! */ + /* woke spontaneously and consumed restart signal */ + return 1; + } + /* woke spontaneously but did not consume restart---caller must resolve */ + return 0; + } + /* woken due to restart signal */ + return 1; +} +#endif /* __ASSUME_REALTIME_SIGNALS */ + +void __pthread_restart_new(pthread_descr th) +{ + /* The barrier is proabably not needed, in which case it still documents + our assumptions. The intent is to commit previous writes to shared + memory so the woken thread will have a consistent view. Complementary + read barriers are present to the suspend functions. */ + WRITE_MEMORY_BARRIER(); + kill(th->p_pid, __pthread_sig_restart); +} + +/* There is no __pthread_suspend_new because it would just + be a wasteful wrapper for __pthread_wait_for_restart_signal */ + +int +__pthread_timedsuspend_new(pthread_descr self, const struct timespec *abstime) +{ + sigset_t unblock, initial_mask; + int was_signalled = 0; + sigjmp_buf jmpbuf; + + if (sigsetjmp(jmpbuf, 1) == 0) { + THREAD_SETMEM(self, p_signal_jmp, &jmpbuf); + THREAD_SETMEM(self, p_signal, 0); + /* Unblock the restart signal */ + sigemptyset(&unblock); + sigaddset(&unblock, __pthread_sig_restart); + sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask); + + while (1) { + struct timeval now; + struct timespec reltime; + + /* Compute a time offset relative to now. */ + __gettimeofday (&now, NULL); + reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000; + reltime.tv_sec = abstime->tv_sec - now.tv_sec; + if (reltime.tv_nsec < 0) { + reltime.tv_nsec += 1000000000; + reltime.tv_sec -= 1; + } + + /* Sleep for the required duration. If woken by a signal, + resume waiting as required by Single Unix Specification. */ + if (reltime.tv_sec < 0 || __libc_nanosleep(&reltime, NULL) == 0) + break; + } + + /* Block the restart signal again */ + sigprocmask(SIG_SETMASK, &initial_mask, NULL); + was_signalled = 0; + } else { + was_signalled = 1; + } + THREAD_SETMEM(self, p_signal_jmp, NULL); + + /* Now was_signalled is true if we exited the above code + due to the delivery of a restart signal. In that case, + everything is cool. We have been removed from whatever + we were waiting on by the other thread, and consumed its signal. + + Otherwise we this thread woke up spontaneously, or due to a signal other + than restart. This is an ambiguous case that must be resolved by + the caller; the thread is still eligible for a restart wakeup + so there is a race. */ + + READ_MEMORY_BARRIER(); /* See comment in __pthread_restart_new */ + return was_signalled; +} + + +/* Debugging aid */ + +#ifdef DEBUG +#include <stdarg.h> + +void __pthread_message(char * fmt, ...) +{ + char buffer[1024]; + va_list args; + sprintf(buffer, "%05d : ", __getpid()); + va_start(args, fmt); + vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args); + va_end(args); + TEMP_FAILURE_RETRY(__libc_write(2, buffer, strlen(buffer))); +} + +#endif + + +#ifndef SHARED +/* We need a hook to force the cancelation wrappers and file locking + to be linked in when static libpthread is used. */ +extern const int __pthread_provide_wrappers; +static const int *const __pthread_require_wrappers = + &__pthread_provide_wrappers; +extern const int __pthread_provide_lockfile; +static const int *const __pthread_require_lockfile = + &__pthread_provide_lockfile; +#endif diff --git a/newlib/libc/sys/linux/linuxthreads/ptlongjmp.c b/newlib/libc/sys/linux/linuxthreads/ptlongjmp.c new file mode 100644 index 000000000..c2ac55f63 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/ptlongjmp.c @@ -0,0 +1,73 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Redefine siglongjmp and longjmp so that they interact correctly + with cleanup handlers */ + +#include <setjmp.h> +#include "pthread.h" +#include "internals.h" + +/* These functions are not declared anywhere since they shouldn't be + used at another place but here. */ +extern void __libc_siglongjmp (sigjmp_buf env, int val) + __attribute__ ((noreturn)); +extern void __libc_longjmp (jmp_buf env, int val) + __attribute__ ((noreturn)); + + +static void pthread_cleanup_upto(jmp_buf target) +{ + pthread_descr self = thread_self(); + struct _pthread_cleanup_buffer * c; + char *currentframe = CURRENT_STACK_FRAME; + + for (c = THREAD_GETMEM(self, p_cleanup); + c != NULL && _JMPBUF_UNWINDS(target, c); + c = c->__prev) + { +#if _STACK_GROWS_DOWN + if ((char *) c <= currentframe) + { + c = NULL; + break; + } +#elif _STACK_GROWS_UP + if ((char *) c >= currentframe) + { + c = NULL; + break; + } +#else +# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP" +#endif + c->__routine(c->__arg); + } + THREAD_SETMEM(self, p_cleanup, c); + if (THREAD_GETMEM(self, p_in_sighandler) + && _JMPBUF_UNWINDS(target, THREAD_GETMEM(self, p_in_sighandler))) + THREAD_SETMEM(self, p_in_sighandler, NULL); +} + +void siglongjmp(sigjmp_buf env, int val) +{ + pthread_cleanup_upto(env.__buf); + __libc_siglongjmp(env, val); +} + +void longjmp(jmp_buf env, int val) +{ + pthread_cleanup_upto(env); + __libc_longjmp(env, val); +} diff --git a/newlib/libc/sys/linux/linuxthreads/queue.h b/newlib/libc/sys/linux/linuxthreads/queue.h new file mode 100644 index 000000000..28bd75531 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/queue.h @@ -0,0 +1,61 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Waiting queues */ + +/* Waiting queues are represented by lists of thread descriptors + linked through their p_nextwaiting field. The lists are kept + sorted by decreasing priority, and then decreasing waiting time. */ + +static inline void enqueue(pthread_descr * q, pthread_descr th) +{ + int prio = th->p_priority; + ASSERT(th->p_nextwaiting == NULL); + for (; *q != NULL; q = &((*q)->p_nextwaiting)) { + if (prio > (*q)->p_priority) { + th->p_nextwaiting = *q; + *q = th; + return; + } + } + *q = th; +} + +static inline pthread_descr dequeue(pthread_descr * q) +{ + pthread_descr th; + th = *q; + if (th != NULL) { + *q = th->p_nextwaiting; + th->p_nextwaiting = NULL; + } + return th; +} + +static inline int remove_from_queue(pthread_descr * q, pthread_descr th) +{ + for (; *q != NULL; q = &((*q)->p_nextwaiting)) { + if (*q == th) { + *q = th->p_nextwaiting; + th->p_nextwaiting = NULL; + return 1; + } + } + return 0; +} + +static inline int queue_is_empty(pthread_descr * q) +{ + return *q == NULL; +} diff --git a/newlib/libc/sys/linux/linuxthreads/reent.c b/newlib/libc/sys/linux/linuxthreads/reent.c new file mode 100644 index 000000000..44d6f7858 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/reent.c @@ -0,0 +1,18 @@ +/* Define the location of _REENT for the newlib C library */ + +#include <reent.h> +#include "pthread.h" +#include "internals.h" + +struct _reent * __thread_reent() +{ + pthread_descr self = thread_self(); + return THREAD_GETMEM (self, p_reentp); +} + +/* Return thread specific resolver state. */ +struct __res_state * __res_state() +{ + pthread_descr self = thread_self(); + return THREAD_GETMEM (self, p_resp); +} diff --git a/newlib/libc/sys/linux/linuxthreads/reqsyscalls.c b/newlib/libc/sys/linux/linuxthreads/reqsyscalls.c new file mode 100644 index 000000000..714a8ba36 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/reqsyscalls.c @@ -0,0 +1,20 @@ +/* EL/IX level 1 and 2 libraries don't have the following syscalls, + but we need them due to our threading model based on processes */ + +#include <time.h> +#include <sched.h> +#include <sys/wait.h> +#include <machine/syscall.h> + +#define __NR___waitpid __NR_waitpid +#define __NR___sched_getparam __NR_sched_getparam +#define __NR___sched_getscheduler __NR_sched_getscheduler +#define __NR___sched_setscheduler __NR_sched_setscheduler + +_syscall2(int,__sched_getparam,pid_t,pid,struct sched_param *,sched); +_syscall1(int,__sched_getscheduler,pid_t,pid); +_syscall3(int,__sched_setscheduler,pid_t,pid,int,policy,const struct sched_param *,sched); + +/* we want __libc____waitpid defined to support __waitpid which is + defined in wrapsyscall.c */ +_syscall3_base(pid_t,__waitpid,pid_t,pid,int *,wait_stat,int,options) diff --git a/newlib/libc/sys/linux/linuxthreads/restart.h b/newlib/libc/sys/linux/linuxthreads/restart.h new file mode 100644 index 000000000..24d9fab74 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/restart.h @@ -0,0 +1,49 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +#include <signal.h> +#include <kernel-features.h> + +/* Primitives for controlling thread execution */ + +static inline void restart(pthread_descr th) +{ + /* See pthread.c */ +#if __ASSUME_REALTIME_SIGNALS + __pthread_restart_new(th); +#else + __pthread_restart(th); +#endif +} + +static inline void suspend(pthread_descr self) +{ + /* See pthread.c */ +#if __ASSUME_REALTIME_SIGNALS + __pthread_wait_for_restart_signal(self); +#else + __pthread_suspend(self); +#endif +} + +static inline int timedsuspend(pthread_descr self, + const struct timespec *abstime) +{ + /* See pthread.c */ +#if __ASSUME_REALTIME_SIGNALS + return __pthread_timedsuspend_new(self, abstime); +#else + return __pthread_timedsuspend(self, abstime); +#endif +} diff --git a/newlib/libc/sys/linux/linuxthreads/rwlock.c b/newlib/libc/sys/linux/linuxthreads/rwlock.c new file mode 100644 index 000000000..e39597014 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/rwlock.c @@ -0,0 +1,658 @@ +/* Read-write lock implementation. + Copyright (C) 1998, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Xavier Leroy <Xavier.Leroy@inria.fr> + and Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <bits/libc-lock.h> +#include <errno.h> +#include <pthread.h> +#include <stdlib.h> +#include "internals.h" +#include "queue.h" +#include "spinlock.h" +#include "restart.h" + +/* Function called by pthread_cancel to remove the thread from + waiting inside pthread_rwlock_timedrdlock or pthread_rwlock_timedwrlock. */ + +static int rwlock_rd_extricate_func(void *obj, pthread_descr th) +{ + pthread_rwlock_t *rwlock = obj; + int did_remove = 0; + + __pthread_lock(&rwlock->__rw_lock, NULL); + did_remove = remove_from_queue(&rwlock->__rw_read_waiting, th); + __pthread_unlock(&rwlock->__rw_lock); + + return did_remove; +} + +static int rwlock_wr_extricate_func(void *obj, pthread_descr th) +{ + pthread_rwlock_t *rwlock = obj; + int did_remove = 0; + + __pthread_lock(&rwlock->__rw_lock, NULL); + did_remove = remove_from_queue(&rwlock->__rw_write_waiting, th); + __pthread_unlock(&rwlock->__rw_lock); + + return did_remove; +} + +/* + * Check whether the calling thread already owns one or more read locks on the + * specified lock. If so, return a pointer to the read lock info structure + * corresponding to that lock. + */ + +static pthread_readlock_info * +rwlock_is_in_list(pthread_descr self, pthread_rwlock_t *rwlock) +{ + pthread_readlock_info *info; + + for (info = THREAD_GETMEM (self, p_readlock_list); info != NULL; + info = info->pr_next) + { + if (info->pr_lock == rwlock) + return info; + } + + return NULL; +} + +/* + * Add a new lock to the thread's list of locks for which it has a read lock. + * A new info node must be allocated for this, which is taken from the thread's + * free list, or by calling malloc. If malloc fails, a null pointer is + * returned. Otherwise the lock info structure is initialized and pushed + * onto the thread's list. + */ + +static pthread_readlock_info * +rwlock_add_to_list(pthread_descr self, pthread_rwlock_t *rwlock) +{ + pthread_readlock_info *info = THREAD_GETMEM (self, p_readlock_free); + + if (info != NULL) + THREAD_SETMEM (self, p_readlock_free, info->pr_next); + else + info = malloc(sizeof *info); + + if (info == NULL) + return NULL; + + info->pr_lock_count = 1; + info->pr_lock = rwlock; + info->pr_next = THREAD_GETMEM (self, p_readlock_list); + THREAD_SETMEM (self, p_readlock_list, info); + + return info; +} + +/* + * If the thread owns a read lock over the given pthread_rwlock_t, + * and this read lock is tracked in the thread's lock list, + * this function returns a pointer to the info node in that list. + * It also decrements the lock count within that node, and if + * it reaches zero, it removes the node from the list. + * If nothing is found, it returns a null pointer. + */ + +static pthread_readlock_info * +rwlock_remove_from_list(pthread_descr self, pthread_rwlock_t *rwlock) +{ + pthread_readlock_info **pinfo; + + for (pinfo = &self->p_readlock_list; *pinfo != NULL; pinfo = &(*pinfo)->pr_next) + { + if ((*pinfo)->pr_lock == rwlock) + { + pthread_readlock_info *info = *pinfo; + if (--info->pr_lock_count == 0) + *pinfo = info->pr_next; + return info; + } + } + + return NULL; +} + +/* + * This function checks whether the conditions are right to place a read lock. + * It returns 1 if so, otherwise zero. The rwlock's internal lock must be + * locked upon entry. + */ + +static int +rwlock_can_rdlock(pthread_rwlock_t *rwlock, int have_lock_already) +{ + /* Can't readlock; it is write locked. */ + if (rwlock->__rw_writer != NULL) + return 0; + + /* Lock prefers readers; get it. */ + if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP) + return 1; + + /* Lock prefers writers, but none are waiting. */ + if (queue_is_empty(&rwlock->__rw_write_waiting)) + return 1; + + /* Writers are waiting, but this thread already has a read lock */ + if (have_lock_already) + return 1; + + /* Writers are waiting, and this is a new lock */ + return 0; +} + +/* + * This function helps support brain-damaged recursive read locking + * semantics required by Unix 98, while maintaining write priority. + * This basically determines whether this thread already holds a read lock + * already. It returns 1 if so, otherwise it returns 0. + * + * If the thread has any ``untracked read locks'' then it just assumes + * that this lock is among them, just to be safe, and returns 1. + * + * Also, if it finds the thread's lock in the list, it sets the pointer + * referenced by pexisting to refer to the list entry. + * + * If the thread has no untracked locks, and the lock is not found + * in its list, then it is added to the list. If this fails, + * then *pout_of_mem is set to 1. + */ + +static int +rwlock_have_already(pthread_descr *pself, pthread_rwlock_t *rwlock, + pthread_readlock_info **pexisting, int *pout_of_mem) +{ + pthread_readlock_info *existing = NULL; + int out_of_mem = 0, have_lock_already = 0; + pthread_descr self = *pself; + + if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_WRITER_NP) + { + if (!self) + *pself = self = thread_self(); + + existing = rwlock_is_in_list(self, rwlock); + + if (existing != NULL + || THREAD_GETMEM (self, p_untracked_readlock_count) > 0) + have_lock_already = 1; + else + { + existing = rwlock_add_to_list(self, rwlock); + if (existing == NULL) + out_of_mem = 1; + } + } + + *pout_of_mem = out_of_mem; + *pexisting = existing; + + return have_lock_already; +} + +int +__pthread_rwlock_init (pthread_rwlock_t *rwlock, + const pthread_rwlockattr_t *attr) +{ + __pthread_init_lock(&rwlock->__rw_lock); + rwlock->__rw_readers = 0; + rwlock->__rw_writer = NULL; + rwlock->__rw_read_waiting = NULL; + rwlock->__rw_write_waiting = NULL; + + if (attr == NULL) + { + rwlock->__rw_kind = PTHREAD_RWLOCK_DEFAULT_NP; + rwlock->__rw_pshared = PTHREAD_PROCESS_PRIVATE; + } + else + { + rwlock->__rw_kind = attr->__lockkind; + rwlock->__rw_pshared = attr->__pshared; + } + + return 0; +} +strong_alias (__pthread_rwlock_init, pthread_rwlock_init) + + +int +__pthread_rwlock_destroy (pthread_rwlock_t *rwlock) +{ + int readers; + _pthread_descr writer; + + __pthread_lock (&rwlock->__rw_lock, NULL); + readers = rwlock->__rw_readers; + writer = rwlock->__rw_writer; + __pthread_unlock (&rwlock->__rw_lock); + + if (readers > 0 || writer != NULL) + return EBUSY; + + return 0; +} +strong_alias (__pthread_rwlock_destroy, pthread_rwlock_destroy) + +int +__pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) +{ + pthread_descr self = NULL; + pthread_readlock_info *existing; + int out_of_mem, have_lock_already; + + have_lock_already = rwlock_have_already(&self, rwlock, + &existing, &out_of_mem); + + if (self == NULL) + self = thread_self (); + + for (;;) + { + __pthread_lock (&rwlock->__rw_lock, self); + + if (rwlock_can_rdlock(rwlock, have_lock_already)) + break; + + enqueue (&rwlock->__rw_read_waiting, self); + __pthread_unlock (&rwlock->__rw_lock); + suspend (self); /* This is not a cancellation point */ + } + + ++rwlock->__rw_readers; + __pthread_unlock (&rwlock->__rw_lock); + + if (have_lock_already || out_of_mem) + { + if (existing != NULL) + ++existing->pr_lock_count; + else + ++self->p_untracked_readlock_count; + } + + return 0; +} +strong_alias (__pthread_rwlock_rdlock, pthread_rwlock_rdlock) + +int +__pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock, + const struct timespec *abstime) +{ + pthread_descr self = NULL; + pthread_readlock_info *existing; + int out_of_mem, have_lock_already; + pthread_extricate_if extr; + + if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) + return EINVAL; + + have_lock_already = rwlock_have_already(&self, rwlock, + &existing, &out_of_mem); + + if (self == NULL) + self = thread_self (); + + /* Set up extrication interface */ + extr.pu_object = rwlock; + extr.pu_extricate_func = rwlock_rd_extricate_func; + + /* Register extrication interface */ + __pthread_set_own_extricate_if (self, &extr); + + for (;;) + { + __pthread_lock (&rwlock->__rw_lock, self); + + if (rwlock_can_rdlock(rwlock, have_lock_already)) + break; + + enqueue (&rwlock->__rw_read_waiting, self); + __pthread_unlock (&rwlock->__rw_lock); + /* This is not a cancellation point */ + if (timedsuspend (self, abstime) == 0) + { + int was_on_queue; + + __pthread_lock (&rwlock->__rw_lock, self); + was_on_queue = remove_from_queue (&rwlock->__rw_read_waiting, self); + __pthread_unlock (&rwlock->__rw_lock); + + if (was_on_queue) + { + __pthread_set_own_extricate_if (self, 0); + return ETIMEDOUT; + } + + /* Eat the outstanding restart() from the signaller */ + suspend (self); + } + } + + __pthread_set_own_extricate_if (self, 0); + + ++rwlock->__rw_readers; + __pthread_unlock (&rwlock->__rw_lock); + + if (have_lock_already || out_of_mem) + { + if (existing != NULL) + ++existing->pr_lock_count; + else + ++self->p_untracked_readlock_count; + } + + return 0; +} +strong_alias (__pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock) + +int +__pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) +{ + pthread_descr self = thread_self(); + pthread_readlock_info *existing; + int out_of_mem, have_lock_already; + int retval = EBUSY; + + have_lock_already = rwlock_have_already(&self, rwlock, + &existing, &out_of_mem); + + __pthread_lock (&rwlock->__rw_lock, self); + + /* 0 is passed to here instead of have_lock_already. + This is to meet Single Unix Spec requirements: + if writers are waiting, pthread_rwlock_tryrdlock + does not acquire a read lock, even if the caller has + one or more read locks already. */ + + if (rwlock_can_rdlock(rwlock, 0)) + { + ++rwlock->__rw_readers; + retval = 0; + } + + __pthread_unlock (&rwlock->__rw_lock); + + if (retval == 0) + { + if (have_lock_already || out_of_mem) + { + if (existing != NULL) + ++existing->pr_lock_count; + else + ++self->p_untracked_readlock_count; + } + } + + return retval; +} +strong_alias (__pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock) + + +int +__pthread_rwlock_wrlock (pthread_rwlock_t *rwlock) +{ + pthread_descr self = thread_self (); + + while(1) + { + __pthread_lock (&rwlock->__rw_lock, self); + if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL) + { + rwlock->__rw_writer = self; + __pthread_unlock (&rwlock->__rw_lock); + return 0; + } + + /* Suspend ourselves, then try again */ + enqueue (&rwlock->__rw_write_waiting, self); + __pthread_unlock (&rwlock->__rw_lock); + suspend (self); /* This is not a cancellation point */ + } +} +strong_alias (__pthread_rwlock_wrlock, pthread_rwlock_wrlock) + + +int +__pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, + const struct timespec *abstime) +{ + pthread_descr self; + pthread_extricate_if extr; + + if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) + return EINVAL; + + self = thread_self (); + + /* Set up extrication interface */ + extr.pu_object = rwlock; + extr.pu_extricate_func = rwlock_wr_extricate_func; + + /* Register extrication interface */ + __pthread_set_own_extricate_if (self, &extr); + + while(1) + { + __pthread_lock (&rwlock->__rw_lock, self); + + if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL) + { + rwlock->__rw_writer = self; + __pthread_set_own_extricate_if (self, 0); + __pthread_unlock (&rwlock->__rw_lock); + return 0; + } + + /* Suspend ourselves, then try again */ + enqueue (&rwlock->__rw_write_waiting, self); + __pthread_unlock (&rwlock->__rw_lock); + /* This is not a cancellation point */ + if (timedsuspend (self, abstime) == 0) + { + int was_on_queue; + + __pthread_lock (&rwlock->__rw_lock, self); + was_on_queue = remove_from_queue (&rwlock->__rw_write_waiting, self); + __pthread_unlock (&rwlock->__rw_lock); + + if (was_on_queue) + { + __pthread_set_own_extricate_if (self, 0); + return ETIMEDOUT; + } + + /* Eat the outstanding restart() from the signaller */ + suspend (self); + } + } +} +strong_alias (__pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock) + + +int +__pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) +{ + int result = EBUSY; + + __pthread_lock (&rwlock->__rw_lock, NULL); + if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL) + { + rwlock->__rw_writer = thread_self (); + result = 0; + } + __pthread_unlock (&rwlock->__rw_lock); + + return result; +} +strong_alias (__pthread_rwlock_trywrlock, pthread_rwlock_trywrlock) + + +int +__pthread_rwlock_unlock (pthread_rwlock_t *rwlock) +{ + pthread_descr torestart; + pthread_descr th; + + __pthread_lock (&rwlock->__rw_lock, NULL); + if (rwlock->__rw_writer != NULL) + { + /* Unlocking a write lock. */ + if (rwlock->__rw_writer != thread_self ()) + { + __pthread_unlock (&rwlock->__rw_lock); + return EPERM; + } + rwlock->__rw_writer = NULL; + + if ((rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP + && !queue_is_empty(&rwlock->__rw_read_waiting)) + || (th = dequeue(&rwlock->__rw_write_waiting)) == NULL) + { + /* Restart all waiting readers. */ + torestart = rwlock->__rw_read_waiting; + rwlock->__rw_read_waiting = NULL; + __pthread_unlock (&rwlock->__rw_lock); + while ((th = dequeue (&torestart)) != NULL) + restart (th); + } + else + { + /* Restart one waiting writer. */ + __pthread_unlock (&rwlock->__rw_lock); + restart (th); + } + } + else + { + /* Unlocking a read lock. */ + if (rwlock->__rw_readers == 0) + { + __pthread_unlock (&rwlock->__rw_lock); + return EPERM; + } + + --rwlock->__rw_readers; + if (rwlock->__rw_readers == 0) + /* Restart one waiting writer, if any. */ + th = dequeue (&rwlock->__rw_write_waiting); + else + th = NULL; + + __pthread_unlock (&rwlock->__rw_lock); + if (th != NULL) + restart (th); + + /* Recursive lock fixup */ + + if (rwlock->__rw_kind == PTHREAD_RWLOCK_PREFER_WRITER_NP) + { + pthread_descr self = thread_self(); + pthread_readlock_info *victim = rwlock_remove_from_list(self, rwlock); + + if (victim != NULL) + { + if (victim->pr_lock_count == 0) + { + victim->pr_next = THREAD_GETMEM (self, p_readlock_free); + THREAD_SETMEM (self, p_readlock_free, victim); + } + } + else + { + int val = THREAD_GETMEM (self, p_untracked_readlock_count); + if (val > 0) + THREAD_SETMEM (self, p_untracked_readlock_count, val - 1); + } + } + } + + return 0; +} +strong_alias (__pthread_rwlock_unlock, pthread_rwlock_unlock) + + + +int +pthread_rwlockattr_init (pthread_rwlockattr_t *attr) +{ + attr->__lockkind = 0; + attr->__pshared = PTHREAD_PROCESS_PRIVATE; + + return 0; +} + + +int +__pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr) +{ + return 0; +} +strong_alias (__pthread_rwlockattr_destroy, pthread_rwlockattr_destroy) + + +int +pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared) +{ + *pshared = attr->__pshared; + return 0; +} + + +int +pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared) +{ + if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED) + return EINVAL; + + /* For now it is not possible to shared a conditional variable. */ + if (pshared != PTHREAD_PROCESS_PRIVATE) + return ENOSYS; + + attr->__pshared = pshared; + + return 0; +} + + +int +pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t *attr, int *pref) +{ + *pref = attr->__lockkind; + return 0; +} + + +int +pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref) +{ + if (pref != PTHREAD_RWLOCK_PREFER_READER_NP + && pref != PTHREAD_RWLOCK_PREFER_WRITER_NP + && pref != PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP + && pref != PTHREAD_RWLOCK_DEFAULT_NP) + return EINVAL; + + attr->__lockkind = pref; + + return 0; +} diff --git a/newlib/libc/sys/linux/linuxthreads/semaphore.c b/newlib/libc/sys/linux/linuxthreads/semaphore.c new file mode 100644 index 000000000..e0dac4120 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/semaphore.c @@ -0,0 +1,304 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Semaphores a la POSIX 1003.1b */ + +#include <errno.h> +#include "pthread.h" +#include "semaphore.h" +#include "internals.h" +#include "spinlock.h" +#include "restart.h" +#include "queue.h" +#include <shlib-compat.h> + +int __new_sem_init(sem_t *sem, int pshared, unsigned int value) +{ + if (value > SEM_VALUE_MAX) { + errno = EINVAL; + return -1; + } + if (pshared) { + errno = ENOSYS; + return -1; + } + __pthread_init_lock(&sem->__sem_lock); + sem->__sem_value = value; + sem->__sem_waiting = NULL; + return 0; +} + +/* Function called by pthread_cancel to remove the thread from + waiting inside __new_sem_wait. */ + +static int new_sem_extricate_func(void *obj, pthread_descr th) +{ + volatile pthread_descr self = thread_self(); + sem_t *sem = obj; + int did_remove = 0; + + __pthread_lock(&sem->__sem_lock, self); + did_remove = remove_from_queue(&sem->__sem_waiting, th); + __pthread_unlock(&sem->__sem_lock); + + return did_remove; +} + +int __new_sem_wait(sem_t * sem) +{ + volatile pthread_descr self = thread_self(); + pthread_extricate_if extr; + int already_canceled = 0; + int spurious_wakeup_count; + + /* Set up extrication interface */ + extr.pu_object = sem; + extr.pu_extricate_func = new_sem_extricate_func; + + __pthread_lock(&sem->__sem_lock, self); + if (sem->__sem_value > 0) { + sem->__sem_value--; + __pthread_unlock(&sem->__sem_lock); + return 0; + } + /* Register extrication interface */ + THREAD_SETMEM(self, p_sem_avail, 0); + __pthread_set_own_extricate_if(self, &extr); + /* Enqueue only if not already cancelled. */ + if (!(THREAD_GETMEM(self, p_canceled) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) + enqueue(&sem->__sem_waiting, self); + else + already_canceled = 1; + __pthread_unlock(&sem->__sem_lock); + + if (already_canceled) { + __pthread_set_own_extricate_if(self, 0); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + + /* Wait for sem_post or cancellation, or fall through if already canceled */ + spurious_wakeup_count = 0; + while (1) + { + suspend(self); + if (THREAD_GETMEM(self, p_sem_avail) == 0 + && (THREAD_GETMEM(self, p_woken_by_cancel) == 0 + || THREAD_GETMEM(self, p_cancelstate) != PTHREAD_CANCEL_ENABLE)) + { + /* Count resumes that don't belong to us. */ + spurious_wakeup_count++; + continue; + } + break; + } + __pthread_set_own_extricate_if(self, 0); + + /* Terminate only if the wakeup came from cancellation. */ + /* Otherwise ignore cancellation because we got the semaphore. */ + + if (THREAD_GETMEM(self, p_woken_by_cancel) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { + THREAD_SETMEM(self, p_woken_by_cancel, 0); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + /* We got the semaphore */ + return 0; +} + +int __new_sem_trywait(sem_t * sem) +{ + int retval; + + __pthread_lock(&sem->__sem_lock, NULL); + if (sem->__sem_value == 0) { + errno = EAGAIN; + retval = -1; + } else { + sem->__sem_value--; + retval = 0; + } + __pthread_unlock(&sem->__sem_lock); + return retval; +} + +int __new_sem_post(sem_t * sem) +{ + pthread_descr self = thread_self(); + pthread_descr th; + struct pthread_request request; + + if (THREAD_GETMEM(self, p_in_sighandler) == NULL) { + __pthread_lock(&sem->__sem_lock, self); + if (sem->__sem_waiting == NULL) { + if (sem->__sem_value >= SEM_VALUE_MAX) { + /* Overflow */ + errno = ERANGE; + __pthread_unlock(&sem->__sem_lock); + return -1; + } + sem->__sem_value++; + __pthread_unlock(&sem->__sem_lock); + } else { + th = dequeue(&sem->__sem_waiting); + __pthread_unlock(&sem->__sem_lock); + th->p_sem_avail = 1; + WRITE_MEMORY_BARRIER(); + restart(th); + } + } else { + /* If we're in signal handler, delegate post operation to + the thread manager. */ + if (__pthread_manager_request < 0) { + if (__pthread_initialize_manager() < 0) { + errno = EAGAIN; + return -1; + } + } + request.req_kind = REQ_POST; + request.req_args.post = sem; + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + } + return 0; +} + +int __new_sem_getvalue(sem_t * sem, int * sval) +{ + *sval = sem->__sem_value; + return 0; +} + +int __new_sem_destroy(sem_t * sem) +{ + if (sem->__sem_waiting != NULL) { + __set_errno (EBUSY); + return -1; + } + return 0; +} + +sem_t *sem_open(const char *name, int oflag, ...) +{ + __set_errno (ENOSYS); + return SEM_FAILED; +} + +int sem_close(sem_t *sem) +{ + __set_errno (ENOSYS); + return -1; +} + +int sem_unlink(const char *name) +{ + __set_errno (ENOSYS); + return -1; +} + +int sem_timedwait(sem_t *sem, const struct timespec *abstime) +{ + pthread_descr self = thread_self(); + pthread_extricate_if extr; + int already_canceled = 0; + int spurious_wakeup_count; + + __pthread_lock(&sem->__sem_lock, self); + if (sem->__sem_value > 0) { + --sem->__sem_value; + __pthread_unlock(&sem->__sem_lock); + return 0; + } + + if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) { + /* The standard requires that if the function would block and the + time value is illegal, the function returns with an error. */ + __pthread_unlock(&sem->__sem_lock); + return EINVAL; + } + + /* Set up extrication interface */ + extr.pu_object = sem; + extr.pu_extricate_func = new_sem_extricate_func; + + /* Register extrication interface */ + THREAD_SETMEM(self, p_sem_avail, 0); + __pthread_set_own_extricate_if(self, &extr); + /* Enqueue only if not already cancelled. */ + if (!(THREAD_GETMEM(self, p_canceled) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) + enqueue(&sem->__sem_waiting, self); + else + already_canceled = 1; + __pthread_unlock(&sem->__sem_lock); + + if (already_canceled) { + __pthread_set_own_extricate_if(self, 0); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + + spurious_wakeup_count = 0; + while (1) + { + if (timedsuspend(self, abstime) == 0) { + int was_on_queue; + + /* __pthread_lock will queue back any spurious restarts that + may happen to it. */ + + __pthread_lock(&sem->__sem_lock, self); + was_on_queue = remove_from_queue(&sem->__sem_waiting, self); + __pthread_unlock(&sem->__sem_lock); + + if (was_on_queue) { + __pthread_set_own_extricate_if(self, 0); + return ETIMEDOUT; + } + + /* Eat the outstanding restart() from the signaller */ + suspend(self); + } + + if (THREAD_GETMEM(self, p_sem_avail) == 0 + && (THREAD_GETMEM(self, p_woken_by_cancel) == 0 + || THREAD_GETMEM(self, p_cancelstate) != PTHREAD_CANCEL_ENABLE)) + { + /* Count resumes that don't belong to us. */ + spurious_wakeup_count++; + continue; + } + break; + } + + __pthread_set_own_extricate_if(self, 0); + + /* Terminate only if the wakeup came from cancellation. */ + /* Otherwise ignore cancellation because we got the semaphore. */ + + if (THREAD_GETMEM(self, p_woken_by_cancel) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) { + THREAD_SETMEM(self, p_woken_by_cancel, 0); + __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME); + } + /* We got the semaphore */ + return 0; +} + + +versioned_symbol (libpthread, __new_sem_init, sem_init, GLIBC_2_1); +versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1); +versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1); +versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1); +versioned_symbol (libpthread, __new_sem_getvalue, sem_getvalue, GLIBC_2_1); +versioned_symbol (libpthread, __new_sem_destroy, sem_destroy, GLIBC_2_1); diff --git a/newlib/libc/sys/linux/linuxthreads/semaphore.h b/newlib/libc/sys/linux/linuxthreads/semaphore.h new file mode 100644 index 000000000..9c283c864 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/semaphore.h @@ -0,0 +1,88 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +#ifndef _SEMAPHORE_H +#define _SEMAPHORE_H 1 + +#include <features.h> +#include <sys/types.h> +#ifdef __USE_XOPEN2K +# define __need_timespec +# include <time.h> +#endif + +#ifndef _PTHREAD_DESCR_DEFINED +/* Thread descriptors. Needed for `sem_t' definition. */ +typedef struct _pthread_descr_struct *_pthread_descr; +# define _PTHREAD_DESCR_DEFINED +#endif + +/* System specific semaphore definition. */ +typedef struct +{ + struct _pthread_fastlock __sem_lock; + int __sem_value; + _pthread_descr __sem_waiting; +} sem_t; + + + +/* Value returned if `sem_open' failed. */ +#define SEM_FAILED ((sem_t *) 0) + +/* Maximum value the semaphore can have. */ +#define SEM_VALUE_MAX ((int) ((~0u) >> 1)) + + +__BEGIN_DECLS + +/* Initialize semaphore object SEM to VALUE. If PSHARED then share it + with other processes. */ +extern int sem_init (sem_t *__sem, int __pshared, unsigned int __value) __THROW; + +/* Free resources associated with semaphore object SEM. */ +extern int sem_destroy (sem_t *__sem) __THROW; + +/* Open a named semaphore NAME with open flaot OFLAG. */ +extern sem_t *sem_open (__const char *__name, int __oflag, ...) __THROW; + +/* Close descriptor for named semaphore SEM. */ +extern int sem_close (sem_t *__sem) __THROW; + +/* Remove named semaphore NAME. */ +extern int sem_unlink (__const char *__name) __THROW; + +/* Wait for SEM being posted. */ +extern int sem_wait (sem_t *__sem) __THROW; + +#ifdef __USE_XOPEN2K +/* Similar to `sem_wait' but wait only until ABSTIME. */ +extern int sem_timedwait (sem_t *__restrict __sem, + __const struct timespec *__restrict __abstime) + __THROW; +#endif + +/* Test whether SEM is posted. */ +extern int sem_trywait (sem_t *__sem) __THROW; + +/* Post SEM. */ +extern int sem_post (sem_t *__sem) __THROW; + +/* Get current value of SEM and store it in *SVAL. */ +extern int sem_getvalue (sem_t *__restrict __sem, int *__restrict __sval) + __THROW; + +__END_DECLS + +#endif /* semaphore.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/shlib-compat.h b/newlib/libc/sys/linux/linuxthreads/shlib-compat.h new file mode 100644 index 000000000..245b8aa89 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/shlib-compat.h @@ -0,0 +1,84 @@ +/* Macros for managing ABI-compatibility definitions using ELF symbol versions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _SHLIB_COMPAT_H +#define _SHLIB_COMPAT_H 1 + +#if defined HAVE_ELF && defined DO_VERSIONING +/* Since there is just one set of .d files generated, we need to + include this unconditionally to have the dependency noticed properly. */ +#include <abi-versions.h> /* header generated by abi-versions.awk */ +#endif + +#if defined HAVE_ELF && defined SHARED && defined DO_VERSIONING + +/* The file abi-versions.h (generated by scripts/abi-versions.awk) defines + symbols like `ABI_libm_GLIBC_2_0' for each version set in the source + code for each library. For a version set that is subsumed by a later + version set, the definition gives the subsuming set, i.e. if GLIBC_2_0 + is subsumed by GLIBC_2_1, then ABI_libm_GLIBC_2_0 == ABI_libm_GLIBC_2_1. + Each version set that is to be distinctly defined in the output has an + unique positive integer value, increasing with newer versions. Thus, + evaluating two ABI_* symbols reduces to integer values that differ only + when the two version sets named are in fact two different ABIs we are + supporting. If these do not differ, then there is no need to compile in + extra code to support this version set where it has been superseded by a + newer version. The compatibility code should be conditionalized with + e.g. `#if SHLIB_COMPAT (libm, GLIBC_2_0, GLIBC_2_2)' for code introduced + in the GLIBC_2.0 version and obsoleted in the GLIBC_2.2 version. */ + +# define SHLIB_COMPAT(lib, introduced, obsoleted) \ + (!(ABI_##lib##_##obsoleted - 0) \ + || ((ABI_##lib##_##introduced - 0) < (ABI_##lib##_##obsoleted - 0))) + +/* That header also defines symbols like `VERSION_libm_GLIBC_2_1' to + the version set name to use for e.g. symbols first introduced into + libm in the GLIBC_2.1 version. Definitions of symbols with explicit + versions should look like: + versioned_symbol (libm, new_foo, foo, GLIBC_2_1); + This will define the symbol `foo' with the appropriate default version, + i.e. either GLIBC_2.1 or the "earliest version" specified in + shlib-versions if that is newer. */ + +# define versioned_symbol(lib, local, symbol, version) \ + versioned_symbol_1 (local, symbol, VERSION_##lib##_##version) +# define versioned_symbol_1(local, symbol, name) \ + default_symbol_version (local, symbol, name) + +# define compat_symbol(lib, local, symbol, version) \ + compat_symbol_1 (local, symbol, VERSION_##lib##_##version) +# define compat_symbol_1(local, symbol, name) \ + symbol_version (local, symbol, name) + +#else + +/* Not compiling ELF shared libraries at all, so never any old versions. */ +# define SHLIB_COMPAT(lib, introduced, obsoleted) 0 + +/* No versions to worry about, just make this the global definition. */ +# define versioned_symbol(lib, local, symbol, version) \ + weak_alias (local, symbol) + +/* This should not appear outside `#if SHLIB_COMPAT (...)'. */ +# define compat_symbol(lib, local, symbol, version) ... + +#endif + + +#endif /* shlib-compat.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/signals.c b/newlib/libc/sys/linux/linuxthreads/signals.c new file mode 100644 index 000000000..da3ce69a4 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/signals.c @@ -0,0 +1,243 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Handling of signals */ + +#include <errno.h> +#include <signal.h> +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include <ucontext.h> +#include <sigcontextinfo.h> + +int pthread_sigmask(int how, const sigset_t * newmask, sigset_t * oldmask) +{ + sigset_t mask; + + if (newmask != NULL) { + mask = *newmask; + /* Don't allow __pthread_sig_restart to be unmasked. + Don't allow __pthread_sig_cancel to be masked. */ + switch(how) { + case SIG_SETMASK: + sigaddset(&mask, __pthread_sig_restart); + sigdelset(&mask, __pthread_sig_cancel); + break; + case SIG_BLOCK: + sigdelset(&mask, __pthread_sig_cancel); + break; + case SIG_UNBLOCK: + sigdelset(&mask, __pthread_sig_restart); + break; + } + newmask = &mask; + } + if (sigprocmask(how, newmask, oldmask) == -1) + return errno; + else + return 0; +} + +int pthread_kill(pthread_t thread, int signo) +{ + pthread_handle handle = thread_handle(thread); + int pid; + + __pthread_lock(&handle->h_lock, NULL); + if (invalid_handle(handle, thread)) { + __pthread_unlock(&handle->h_lock); + return ESRCH; + } + pid = handle->h_descr->p_pid; + __pthread_unlock(&handle->h_lock); + if (kill(pid, signo) == -1) + return errno; + else + return 0; +} + +/* User-provided signal handlers */ +typedef void (*arch_sighandler_t) (int, SIGCONTEXT); +static union +{ + arch_sighandler_t old; + void (*rt) (int, struct siginfo *, struct ucontext *); +} sighandler[NSIG] = { [1 ... NSIG - 1] = { (arch_sighandler_t) SIG_ERR } }; + +/* The wrapper around user-provided signal handlers */ +static void pthread_sighandler(int signo, SIGCONTEXT ctx) +{ + pthread_descr self; + char * in_sighandler; + self = thread_self(); + /* If we're in a sigwait operation, just record the signal received + and return without calling the user's handler */ + if (THREAD_GETMEM(self, p_sigwaiting)) { + THREAD_SETMEM(self, p_sigwaiting, 0); + THREAD_SETMEM(self, p_signal, signo); + return; + } + /* Record that we're in a signal handler and call the user's + handler function */ + in_sighandler = THREAD_GETMEM(self, p_in_sighandler); + if (in_sighandler == NULL) + THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME); + CALL_SIGHANDLER(sighandler[signo].old, signo, ctx); + if (in_sighandler == NULL) + THREAD_SETMEM(self, p_in_sighandler, NULL); +} + +/* The same, this time for real-time signals. */ +static void pthread_sighandler_rt(int signo, struct siginfo *si, + struct ucontext *uc) +{ + pthread_descr self; + char * in_sighandler; + self = thread_self(); + /* If we're in a sigwait operation, just record the signal received + and return without calling the user's handler */ + if (THREAD_GETMEM(self, p_sigwaiting)) { + THREAD_SETMEM(self, p_sigwaiting, 0); + THREAD_SETMEM(self, p_signal, signo); + return; + } + /* Record that we're in a signal handler and call the user's + handler function */ + in_sighandler = THREAD_GETMEM(self, p_in_sighandler); + if (in_sighandler == NULL) + THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME); + sighandler[signo].rt(signo, si, uc); + if (in_sighandler == NULL) + THREAD_SETMEM(self, p_in_sighandler, NULL); +} + +/* The wrapper around sigaction. Install our own signal handler + around the signal. */ +int __sigaction(int sig, const struct sigaction * act, + struct sigaction * oact) +{ + struct sigaction newact; + struct sigaction *newactp; + + if (sig == __pthread_sig_restart || + sig == __pthread_sig_cancel || + (sig == __pthread_sig_debug && __pthread_sig_debug > 0)) + { + __set_errno (EINVAL); + return -1; + } + if (act) + { + newact = *act; + if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL + && sig > 0 && sig < NSIG) + { + if (act->sa_flags & SA_SIGINFO) + newact.sa_handler = (__sighandler_t) pthread_sighandler_rt; + else + newact.sa_handler = (__sighandler_t) pthread_sighandler; + } + newactp = &newact; + } + else + newactp = NULL; + if (__libc_sigaction(sig, newactp, oact) == -1) + return -1; + if (sig > 0 && sig < NSIG) + { + if (oact != NULL + /* We may have inherited SIG_IGN from the parent, so return the + kernel's idea of the signal handler the first time + through. */ + && (__sighandler_t) sighandler[sig].old != SIG_ERR) + oact->sa_handler = (__sighandler_t) sighandler[sig].old; + if (act) + /* For the assignment it does not matter whether it's a normal + or real-time signal. */ + sighandler[sig].old = (arch_sighandler_t) act->sa_handler; + } + return 0; +} +strong_alias(__sigaction, sigaction) + +/* A signal handler that does nothing */ +static void pthread_null_sighandler(int sig) { } + +/* sigwait -- synchronously wait for a signal */ +int sigwait(const sigset_t * set, int * sig) +{ + volatile pthread_descr self = thread_self(); + sigset_t mask; + int s; + sigjmp_buf jmpbuf; + struct sigaction sa; + + /* Get ready to block all signals except those in set + and the cancellation signal. + Also check that handlers are installed on all signals in set, + and if not, install our dummy handler. This is conformant to + POSIX: "The effect of sigwait() on the signal actions for the + signals in set is unspecified." */ + sigfillset(&mask); + sigdelset(&mask, __pthread_sig_cancel); + for (s = 1; s < NSIG; s++) { + if (sigismember(set, s) && + s != __pthread_sig_restart && + s != __pthread_sig_cancel && + s != __pthread_sig_debug) { + sigdelset(&mask, s); + if (sighandler[s].old == (arch_sighandler_t) SIG_ERR || + sighandler[s].old == (arch_sighandler_t) SIG_DFL || + sighandler[s].old == (arch_sighandler_t) SIG_IGN) { + sa.sa_handler = pthread_null_sighandler; + sigfillset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(s, &sa, NULL); + } + } + } + /* Test for cancellation */ + if (sigsetjmp(jmpbuf, 1) == 0) { + THREAD_SETMEM(self, p_cancel_jmp, &jmpbuf); + if (! (THREAD_GETMEM(self, p_canceled) + && THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)) { + /* Reset the signal count */ + THREAD_SETMEM(self, p_signal, 0); + /* Say we're in sigwait */ + THREAD_SETMEM(self, p_sigwaiting, 1); + /* Unblock the signals and wait for them */ + sigsuspend(&mask); + } + } + THREAD_SETMEM(self, p_cancel_jmp, NULL); + /* The signals are now reblocked. Check for cancellation */ + pthread_testcancel(); + /* We should have self->p_signal != 0 and equal to the signal received */ + *sig = THREAD_GETMEM(self, p_signal); + return 0; +} + +/* Redefine raise() to send signal to calling thread only, + as per POSIX 1003.1c */ +int raise (int sig) +{ + int retcode = pthread_kill(pthread_self(), sig); + if (retcode == 0) + return 0; + else { + errno = retcode; + return -1; + } +} diff --git a/newlib/libc/sys/linux/linuxthreads/specific.c b/newlib/libc/sys/linux/linuxthreads/specific.c new file mode 100644 index 000000000..2dbf2055e --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/specific.c @@ -0,0 +1,228 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Thread-specific data */ + +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include "restart.h" +#include <bits/libc-lock.h> + + +/* Table of keys. */ + +static struct pthread_key_struct pthread_keys[PTHREAD_KEYS_MAX] = + { { 0, NULL } }; + +/* For debugging purposes put the maximum number of keys in a variable. */ +const int __linuxthreads_pthread_keys_max = PTHREAD_KEYS_MAX; +const int __linuxthreads_pthread_key_2ndlevel_size = PTHREAD_KEY_2NDLEVEL_SIZE; + +/* Mutex to protect access to pthread_keys */ + +static pthread_mutex_t pthread_keys_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Create a new key */ + +int __pthread_key_create(pthread_key_t * key, destr_function destr) +{ + int i; + + pthread_mutex_lock(&pthread_keys_mutex); + for (i = 0; i < PTHREAD_KEYS_MAX; i++) { + if (! pthread_keys[i].in_use) { + /* Mark key in use */ + pthread_keys[i].in_use = 1; + pthread_keys[i].destr = destr; + pthread_mutex_unlock(&pthread_keys_mutex); + *key = i; + return 0; + } + } + pthread_mutex_unlock(&pthread_keys_mutex); + return EAGAIN; +} +strong_alias (__pthread_key_create, pthread_key_create) + +/* Reset deleted key's value to NULL in each live thread. + * NOTE: this executes in the context of the thread manager! */ + +struct pthread_key_delete_helper_args { + /* Damn, we need lexical closures in C! ;) */ + unsigned int idx1st, idx2nd; + pthread_descr self; +}; + +static void pthread_key_delete_helper(void *arg, pthread_descr th) +{ + struct pthread_key_delete_helper_args *args = arg; + unsigned int idx1st = args->idx1st; + unsigned int idx2nd = args->idx2nd; + pthread_descr self = args->self; + + if (self == 0) + self = args->self = thread_self(); + + if (!th->p_terminated) { + /* pthread_exit() may try to free th->p_specific[idx1st] concurrently. */ + __pthread_lock(THREAD_GETMEM(th, p_lock), self); + if (th->p_specific[idx1st] != NULL) + th->p_specific[idx1st][idx2nd] = NULL; + __pthread_unlock(THREAD_GETMEM(th, p_lock)); + } +} + +/* Delete a key */ +int pthread_key_delete(pthread_key_t key) +{ + pthread_descr self = thread_self(); + + pthread_mutex_lock(&pthread_keys_mutex); + if (key >= PTHREAD_KEYS_MAX || !pthread_keys[key].in_use) { + pthread_mutex_unlock(&pthread_keys_mutex); + return EINVAL; + } + pthread_keys[key].in_use = 0; + pthread_keys[key].destr = NULL; + + /* Set the value of the key to NULL in all running threads, so + that if the key is reallocated later by pthread_key_create, its + associated values will be NULL in all threads. + + Do nothing if no threads have been created yet. */ + + if (__pthread_manager_request != -1) + { + struct pthread_key_delete_helper_args args; + struct pthread_request request; + + args.idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE; + args.idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE; + args.self = 0; + + request.req_thread = self; + request.req_kind = REQ_FOR_EACH_THREAD; + request.req_args.for_each.arg = &args; + request.req_args.for_each.fn = pthread_key_delete_helper; + + TEMP_FAILURE_RETRY(__libc_write(__pthread_manager_request, + (char *) &request, sizeof(request))); + suspend(self); + } + + pthread_mutex_unlock(&pthread_keys_mutex); + return 0; +} + +/* Set the value of a key */ + +int __pthread_setspecific(pthread_key_t key, const void * pointer) +{ + pthread_descr self = thread_self(); + unsigned int idx1st, idx2nd; + + if (key >= PTHREAD_KEYS_MAX || !pthread_keys[key].in_use) + return EINVAL; + idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE; + idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE; + if (THREAD_GETMEM_NC(self, p_specific[idx1st]) == NULL) { + void *newp = calloc(PTHREAD_KEY_2NDLEVEL_SIZE, sizeof (void *)); + if (newp == NULL) + return ENOMEM; + THREAD_SETMEM_NC(self, p_specific[idx1st], newp); + } + THREAD_GETMEM_NC(self, p_specific[idx1st])[idx2nd] = (void *) pointer; + return 0; +} +strong_alias (__pthread_setspecific, pthread_setspecific) + +/* Get the value of a key */ + +void * __pthread_getspecific(pthread_key_t key) +{ + pthread_descr self = thread_self(); + unsigned int idx1st, idx2nd; + + if (key >= PTHREAD_KEYS_MAX) + return NULL; + idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE; + idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE; + if (THREAD_GETMEM_NC(self, p_specific[idx1st]) == NULL + || !pthread_keys[key].in_use) + return NULL; + return THREAD_GETMEM_NC(self, p_specific[idx1st])[idx2nd]; +} +strong_alias (__pthread_getspecific, pthread_getspecific) + +/* Call the destruction routines on all keys */ + +void __pthread_destroy_specifics() +{ + pthread_descr self = thread_self(); + int i, j, round, found_nonzero; + destr_function destr; + void * data; + + for (round = 0, found_nonzero = 1; + found_nonzero && round < PTHREAD_DESTRUCTOR_ITERATIONS; + round++) { + found_nonzero = 0; + for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++) + if (THREAD_GETMEM_NC(self, p_specific[i]) != NULL) + for (j = 0; j < PTHREAD_KEY_2NDLEVEL_SIZE; j++) { + destr = pthread_keys[i * PTHREAD_KEY_2NDLEVEL_SIZE + j].destr; + data = THREAD_GETMEM_NC(self, p_specific[i])[j]; + if (destr != NULL && data != NULL) { + THREAD_GETMEM_NC(self, p_specific[i])[j] = NULL; + destr(data); + found_nonzero = 1; + } + } + } + __pthread_lock(THREAD_GETMEM(self, p_lock), self); + for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++) { + if (THREAD_GETMEM_NC(self, p_specific[i]) != NULL) { + free(THREAD_GETMEM_NC(self, p_specific[i])); + THREAD_SETMEM_NC(self, p_specific[i], NULL); + } + } + __pthread_unlock(THREAD_GETMEM(self, p_lock)); +} + +/* Thread-specific data for libc. */ + +static int +libc_internal_tsd_set(enum __libc_tsd_key_t key, const void * pointer) +{ + pthread_descr self = thread_self(); + + THREAD_SETMEM_NC(self, p_libc_specific[key], (void *) pointer); + return 0; +} +int (*__libc_internal_tsd_set)(enum __libc_tsd_key_t key, const void * pointer) + = libc_internal_tsd_set; + +static void * +libc_internal_tsd_get(enum __libc_tsd_key_t key) +{ + pthread_descr self = thread_self(); + + return THREAD_GETMEM_NC(self, p_libc_specific[key]); +} +void * (*__libc_internal_tsd_get)(enum __libc_tsd_key_t key) + = libc_internal_tsd_get; diff --git a/newlib/libc/sys/linux/linuxthreads/spinlock.c b/newlib/libc/sys/linux/linuxthreads/spinlock.c new file mode 100644 index 000000000..3e1682599 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/spinlock.c @@ -0,0 +1,774 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Internal locks */ + +#include <errno.h> +#include <sched.h> +#include <time.h> +#include <stdlib.h> +#include <limits.h> +#include "pthread.h" +#include "internals.h" +#include "spinlock.h" +#include "restart.h" + +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP +static void __pthread_acquire(int * spinlock); + +static inline void __pthread_release(int * spinlock) +{ + WRITE_MEMORY_BARRIER(); + *spinlock = __LT_SPINLOCK_INIT; + __asm __volatile ("" : "=m" (*spinlock) : "0" (*spinlock)); +} +#endif + + +/* The status field of a spinlock is a pointer whose least significant + bit is a locked flag. + + Thus the field values have the following meanings: + + status == 0: spinlock is free + status == 1: spinlock is taken; no thread is waiting on it + + (status & 1) == 1: spinlock is taken and (status & ~1L) is a + pointer to the first waiting thread; other + waiting threads are linked via the p_nextlock + field. + (status & 1) == 0: same as above, but spinlock is not taken. + + The waiting list is not sorted by priority order. + Actually, we always insert at top of list (sole insertion mode + that can be performed without locking). + For __pthread_unlock, we perform a linear search in the list + to find the highest-priority, oldest waiting thread. + This is safe because there are no concurrent __pthread_unlock + operations -- only the thread that locked the mutex can unlock it. */ + + +void internal_function __pthread_lock(struct _pthread_fastlock * lock, + pthread_descr self) +{ +#if defined HAS_COMPARE_AND_SWAP + long oldstatus, newstatus; + int successful_seizure, spurious_wakeup_count; + int spin_count; +#endif + +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + __pthread_acquire(&lock->__spinlock); + return; + } +#endif + +#if defined HAS_COMPARE_AND_SWAP + /* First try it without preparation. Maybe it's a completely + uncontested lock. */ + if (lock->__status == 0 && __compare_and_swap (&lock->__status, 0, 1)) + return; + + spurious_wakeup_count = 0; + spin_count = 0; + +again: + + /* On SMP, try spinning to get the lock. */ + + if (__pthread_smp_kernel) { + int max_count = lock->__spinlock * 2 + 10; + + if (max_count > MAX_ADAPTIVE_SPIN_COUNT) + max_count = MAX_ADAPTIVE_SPIN_COUNT; + + for (spin_count = 0; spin_count < max_count; spin_count++) { + if (((oldstatus = lock->__status) & 1) == 0) { + if(__compare_and_swap(&lock->__status, oldstatus, oldstatus | 1)) + { + if (spin_count) + lock->__spinlock += (spin_count - lock->__spinlock) / 8; + READ_MEMORY_BARRIER(); + return; + } + } +#ifdef BUSY_WAIT_NOP + BUSY_WAIT_NOP; +#endif + __asm __volatile ("" : "=m" (lock->__status) : "0" (lock->__status)); + } + + lock->__spinlock += (spin_count - lock->__spinlock) / 8; + } + + /* No luck, try once more or suspend. */ + + do { + oldstatus = lock->__status; + successful_seizure = 0; + + if ((oldstatus & 1) == 0) { + newstatus = oldstatus | 1; + successful_seizure = 1; + } else { + if (self == NULL) + self = thread_self(); + newstatus = (long) self | 1; + } + + if (self != NULL) { + THREAD_SETMEM(self, p_nextlock, (pthread_descr) (oldstatus & ~1L)); + /* Make sure the store in p_nextlock completes before performing + the compare-and-swap */ + MEMORY_BARRIER(); + } + } while(! __compare_and_swap(&lock->__status, oldstatus, newstatus)); + + /* Suspend with guard against spurious wakeup. + This can happen in pthread_cond_timedwait_relative, when the thread + wakes up due to timeout and is still on the condvar queue, and then + locks the queue to remove itself. At that point it may still be on the + queue, and may be resumed by a condition signal. */ + + if (!successful_seizure) { + for (;;) { + suspend(self); + if (self->p_nextlock != NULL) { + /* Count resumes that don't belong to us. */ + spurious_wakeup_count++; + continue; + } + break; + } + goto again; + } + + /* Put back any resumes we caught that don't belong to us. */ + while (spurious_wakeup_count--) + restart(self); + + READ_MEMORY_BARRIER(); +#endif +} + +int __pthread_unlock(struct _pthread_fastlock * lock) +{ +#if defined HAS_COMPARE_AND_SWAP + long oldstatus; + pthread_descr thr, * ptr, * maxptr; + int maxprio; +#endif + +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + __pthread_release(&lock->__spinlock); + return 0; + } +#endif + +#if defined HAS_COMPARE_AND_SWAP + WRITE_MEMORY_BARRIER(); + +again: + while ((oldstatus = lock->__status) == 1) { + if (__compare_and_swap_with_release_semantics(&lock->__status, + oldstatus, 0)) + return 0; + } + + /* Find thread in waiting queue with maximal priority */ + ptr = (pthread_descr *) &lock->__status; + thr = (pthread_descr) (oldstatus & ~1L); + maxprio = 0; + maxptr = ptr; + + /* Before we iterate over the wait queue, we need to execute + a read barrier, otherwise we may read stale contents of nodes that may + just have been inserted by other processors. One read barrier is enough to + ensure we have a stable list; we don't need one for each pointer chase + through the list, because we are the owner of the lock; other threads + can only add nodes at the front; if a front node is consistent, + the ones behind it must also be. */ + + READ_MEMORY_BARRIER(); + + while (thr != 0) { + if (thr->p_priority >= maxprio) { + maxptr = ptr; + maxprio = thr->p_priority; + } + ptr = &(thr->p_nextlock); + thr = *ptr; + } + + /* Remove max prio thread from waiting list. */ + if (maxptr == (pthread_descr *) &lock->__status) { + /* If max prio thread is at head, remove it with compare-and-swap + to guard against concurrent lock operation. This removal + also has the side effect of marking the lock as released + because the new status comes from thr->p_nextlock whose + least significant bit is clear. */ + thr = (pthread_descr) (oldstatus & ~1L); + if (! __compare_and_swap_with_release_semantics + (&lock->__status, oldstatus, (long)(thr->p_nextlock))) + goto again; + } else { + /* No risk of concurrent access, remove max prio thread normally. + But in this case we must also flip the least significant bit + of the status to mark the lock as released. */ + thr = *maxptr; + *maxptr = thr->p_nextlock; + + /* Ensure deletion from linked list completes before we + release the lock. */ + WRITE_MEMORY_BARRIER(); + + do { + oldstatus = lock->__status; + } while (!__compare_and_swap_with_release_semantics(&lock->__status, + oldstatus, oldstatus & ~1L)); + } + + /* Wake up the selected waiting thread. Woken thread can check + its own p_nextlock field for NULL to detect that it has been removed. No + barrier is needed here, since restart() and suspend() take + care of memory synchronization. */ + + thr->p_nextlock = NULL; + restart(thr); + + return 0; +#endif +} + +/* + * Alternate fastlocks do not queue threads directly. Instead, they queue + * these wait queue node structures. When a timed wait wakes up due to + * a timeout, it can leave its wait node in the queue (because there + * is no safe way to remove from the quue). Some other thread will + * deallocate the abandoned node. + */ + + +struct wait_node { + struct wait_node *next; /* Next node in null terminated linked list */ + pthread_descr thr; /* The thread waiting with this node */ + int abandoned; /* Atomic flag */ +}; + +static long wait_node_free_list; +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP +static int wait_node_free_list_spinlock; +#endif + +/* Allocate a new node from the head of the free list using an atomic + operation, or else using malloc if that list is empty. A fundamental + assumption here is that we can safely access wait_node_free_list->next. + That's because we never free nodes once we allocate them, so a pointer to a + node remains valid indefinitely. */ + +static struct wait_node *wait_node_alloc(void) +{ +#if defined HAS_COMPARE_AND_SWAP + long oldvalue, newvalue; +#endif + +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + struct wait_node *new_node = 0; + + __pthread_acquire(&wait_node_free_list_spinlock); + if (wait_node_free_list != 0) { + new_node = (struct wait_node *) wait_node_free_list; + wait_node_free_list = (long) new_node->next; + } + WRITE_MEMORY_BARRIER(); + wait_node_free_list_spinlock = 0; + + if (new_node == 0) + return malloc(sizeof *wait_node_alloc()); + + return new_node; + } +#endif + +#if defined HAS_COMPARE_AND_SWAP + do { + oldvalue = wait_node_free_list; + + if (oldvalue == 0) + return malloc(sizeof *wait_node_alloc()); + + /* Ensure we don't read stale next link through oldvalue pointer. */ + READ_MEMORY_BARRIER(); + newvalue = (long) ((struct wait_node *) oldvalue)->next; + } while (! __compare_and_swap(&wait_node_free_list, oldvalue, newvalue)); + + return (struct wait_node *) oldvalue; +#endif +} + +/* Return a node to the head of the free list using an atomic + operation. */ + +static void wait_node_free(struct wait_node *wn) +{ +#if defined HAS_COMPARE_AND_SWAP + long oldvalue, newvalue; +#endif + +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + __pthread_acquire(&wait_node_free_list_spinlock); + wn->next = (struct wait_node *) wait_node_free_list; + wait_node_free_list = (long) wn; + WRITE_MEMORY_BARRIER(); + wait_node_free_list_spinlock = 0; + return; + } +#endif + +#if defined HAS_COMPARE_AND_SWAP + do { + oldvalue = wait_node_free_list; + wn->next = (struct wait_node *) oldvalue; + newvalue = (long) wn; + /* Ensure node contents are written before we swap it into the list. */ + WRITE_MEMORY_BARRIER(); + } while (! __compare_and_swap(&wait_node_free_list, oldvalue, newvalue)); +#endif +} + +#if defined HAS_COMPARE_AND_SWAP + +/* Remove a wait node from the specified queue. It is assumed + that the removal takes place concurrently with only atomic insertions at the + head of the queue. */ + +static void wait_node_dequeue(struct wait_node **pp_head, + struct wait_node **pp_node, + struct wait_node *p_node) +{ + /* If the node is being deleted from the head of the + list, it must be deleted using atomic compare-and-swap. + Otherwise it can be deleted in the straightforward way. */ + + if (pp_node == pp_head) { + /* We don't need a read barrier between these next two loads, + because it is assumed that the caller has already ensured + the stability of *p_node with respect to p_node. */ + + long oldvalue = (long) p_node; + long newvalue = (long) p_node->next; + + if (__compare_and_swap((long *) pp_node, oldvalue, newvalue)) + return; + + /* Oops! Compare and swap failed, which means the node is + no longer first. We delete it using the ordinary method. But we don't + know the identity of the node which now holds the pointer to the node + being deleted, so we must search from the beginning. */ + + for (pp_node = pp_head; p_node != *pp_node; ) { + pp_node = &(*pp_node)->next; + READ_MEMORY_BARRIER(); /* Stabilize *pp_node for next iteration. */ + } + } + + *pp_node = p_node->next; + return; +} + +#endif + +void __pthread_alt_lock(struct _pthread_fastlock * lock, + pthread_descr self) +{ +#if defined HAS_COMPARE_AND_SWAP + long oldstatus, newstatus; +#endif + struct wait_node wait_node; + +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + int suspend_needed = 0; + __pthread_acquire(&lock->__spinlock); + + if (lock->__status == 0) + lock->__status = 1; + else { + if (self == NULL) + self = thread_self(); + + wait_node.abandoned = 0; + wait_node.next = (struct wait_node *) lock->__status; + wait_node.thr = self; + lock->__status = (long) &wait_node; + suspend_needed = 1; + } + + __pthread_release(&lock->__spinlock); + + if (suspend_needed) + suspend (self); + return; + } +#endif + +#if defined HAS_COMPARE_AND_SWAP + do { + oldstatus = lock->__status; + if (oldstatus == 0) { + newstatus = 1; + } else { + if (self == NULL) + self = thread_self(); + wait_node.thr = self; + newstatus = (long) &wait_node; + } + wait_node.abandoned = 0; + wait_node.next = (struct wait_node *) oldstatus; + /* Make sure the store in wait_node.next completes before performing + the compare-and-swap */ + MEMORY_BARRIER(); + } while(! __compare_and_swap(&lock->__status, oldstatus, newstatus)); + + /* Suspend. Note that unlike in __pthread_lock, we don't worry + here about spurious wakeup. That's because this lock is not + used in situations where that can happen; the restart can + only come from the previous lock owner. */ + + if (oldstatus != 0) + suspend(self); + + READ_MEMORY_BARRIER(); +#endif +} + +/* Timed-out lock operation; returns 0 to indicate timeout. */ + +int __pthread_alt_timedlock(struct _pthread_fastlock * lock, + pthread_descr self, const struct timespec *abstime) +{ + long oldstatus = 0; +#if defined HAS_COMPARE_AND_SWAP + long newstatus; +#endif + struct wait_node *p_wait_node = wait_node_alloc(); + + /* Out of memory, just give up and do ordinary lock. */ + if (p_wait_node == 0) { + __pthread_alt_lock(lock, self); + return 1; + } + +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + __pthread_acquire(&lock->__spinlock); + + if (lock->__status == 0) + lock->__status = 1; + else { + if (self == NULL) + self = thread_self(); + + p_wait_node->abandoned = 0; + p_wait_node->next = (struct wait_node *) lock->__status; + p_wait_node->thr = self; + lock->__status = (long) p_wait_node; + oldstatus = 1; /* force suspend */ + } + + __pthread_release(&lock->__spinlock); + goto suspend; + } +#endif + +#if defined HAS_COMPARE_AND_SWAP + do { + oldstatus = lock->__status; + if (oldstatus == 0) { + newstatus = 1; + } else { + if (self == NULL) + self = thread_self(); + p_wait_node->thr = self; + newstatus = (long) p_wait_node; + } + p_wait_node->abandoned = 0; + p_wait_node->next = (struct wait_node *) oldstatus; + /* Make sure the store in wait_node.next completes before performing + the compare-and-swap */ + MEMORY_BARRIER(); + } while(! __compare_and_swap(&lock->__status, oldstatus, newstatus)); +#endif + +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + suspend: +#endif + + /* If we did not get the lock, do a timed suspend. If we wake up due + to a timeout, then there is a race; the old lock owner may try + to remove us from the queue. This race is resolved by us and the owner + doing an atomic testandset() to change the state of the wait node from 0 + to 1. If we succeed, then it's a timeout and we abandon the node in the + queue. If we fail, it means the owner gave us the lock. */ + + if (oldstatus != 0) { + if (timedsuspend(self, abstime) == 0) { + if (!testandset(&p_wait_node->abandoned)) + return 0; /* Timeout! */ + + /* Eat oustanding resume from owner, otherwise wait_node_free() below + will race with owner's wait_node_dequeue(). */ + suspend(self); + } + } + + wait_node_free(p_wait_node); + + READ_MEMORY_BARRIER(); + + return 1; /* Got the lock! */ +} + +void __pthread_alt_unlock(struct _pthread_fastlock *lock) +{ + struct wait_node *p_node, **pp_node, *p_max_prio, **pp_max_prio; + struct wait_node ** const pp_head = (struct wait_node **) &lock->__status; + int maxprio; + + WRITE_MEMORY_BARRIER(); + +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + __pthread_acquire(&lock->__spinlock); + } +#endif + + while (1) { + + /* If no threads are waiting for this lock, try to just + atomically release it. */ +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + if (lock->__status == 0 || lock->__status == 1) { + lock->__status = 0; + break; + } + } +#endif + +#if defined TEST_FOR_COMPARE_AND_SWAP + else +#endif + +#if defined HAS_COMPARE_AND_SWAP + { + long oldstatus = lock->__status; + if (oldstatus == 0 || oldstatus == 1) { + if (__compare_and_swap_with_release_semantics (&lock->__status, oldstatus, 0)) + break; + else + continue; + } + } +#endif + + /* Process the entire queue of wait nodes. Remove all abandoned + wait nodes and put them into the global free queue, and + remember the one unabandoned node which refers to the thread + having the highest priority. */ + + pp_max_prio = pp_node = pp_head; + p_max_prio = p_node = *pp_head; + maxprio = INT_MIN; + + READ_MEMORY_BARRIER(); /* Prevent access to stale data through p_node */ + + while (p_node != (struct wait_node *) 1) { + int prio; + + if (p_node->abandoned) { + /* Remove abandoned node. */ +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + *pp_node = p_node->next; +#endif +#if defined TEST_FOR_COMPARE_AND_SWAP + else +#endif +#if defined HAS_COMPARE_AND_SWAP + wait_node_dequeue(pp_head, pp_node, p_node); +#endif + wait_node_free(p_node); + /* Note that the next assignment may take us to the beginning + of the queue, to newly inserted nodes, if pp_node == pp_head. + In that case we need a memory barrier to stabilize the first of + these new nodes. */ + p_node = *pp_node; + if (pp_node == pp_head) + READ_MEMORY_BARRIER(); /* No stale reads through p_node */ + continue; + } else if ((prio = p_node->thr->p_priority) >= maxprio) { + /* Otherwise remember it if its thread has a higher or equal priority + compared to that of any node seen thus far. */ + maxprio = prio; + pp_max_prio = pp_node; + p_max_prio = p_node; + } + + /* This canno6 jump backward in the list, so no further read + barrier is needed. */ + pp_node = &p_node->next; + p_node = *pp_node; + } + + /* If all threads abandoned, go back to top */ + if (maxprio == INT_MIN) + continue; + + ASSERT (p_max_prio != (struct wait_node *) 1); + + /* Now we want to to remove the max priority thread's wait node from + the list. Before we can do this, we must atomically try to change the + node's abandon state from zero to nonzero. If we succeed, that means we + have the node that we will wake up. If we failed, then it means the + thread timed out and abandoned the node in which case we repeat the + whole unlock operation. */ + + if (!testandset(&p_max_prio->abandoned)) { +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + *pp_max_prio = p_max_prio->next; +#endif +#if defined TEST_FOR_COMPARE_AND_SWAP + else +#endif +#if defined HAS_COMPARE_AND_SWAP + wait_node_dequeue(pp_head, pp_max_prio, p_max_prio); +#endif + restart(p_max_prio->thr); + break; + } + } + +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + __pthread_release(&lock->__spinlock); + } +#endif +} + + +/* Compare-and-swap emulation with a spinlock */ + +#ifdef TEST_FOR_COMPARE_AND_SWAP +int __pthread_has_cas = 0; +#endif + +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + +int __pthread_compare_and_swap(long * ptr, long oldval, long newval, + int * spinlock) +{ + int res; + + __pthread_acquire(spinlock); + + if (*ptr == oldval) { + *ptr = newval; res = 1; + } else { + res = 0; + } + + __pthread_release(spinlock); + + return res; +} + +/* This function is called if the inlined test-and-set + in __pthread_compare_and_swap() failed */ + +/* The retry strategy is as follows: + - We test and set the spinlock MAX_SPIN_COUNT times, calling + sched_yield() each time. This gives ample opportunity for other + threads with priority >= our priority to make progress and + release the spinlock. + - If a thread with priority < our priority owns the spinlock, + calling sched_yield() repeatedly is useless, since we're preventing + the owning thread from making progress and releasing the spinlock. + So, after MAX_SPIN_LOCK attemps, we suspend the calling thread + using nanosleep(). This again should give time to the owning thread + for releasing the spinlock. + Notice that the nanosleep() interval must not be too small, + since the kernel does busy-waiting for short intervals in a realtime + process (!). The smallest duration that guarantees thread + suspension is currently 2ms. + - When nanosleep() returns, we try again, doing MAX_SPIN_COUNT + sched_yield(), then sleeping again if needed. */ + +static void __pthread_acquire(int * spinlock) +{ + int cnt = 0; + struct timespec tm; + + READ_MEMORY_BARRIER(); + + while (testandset(spinlock)) { + if (cnt < MAX_SPIN_COUNT) { + sched_yield(); + cnt++; + } else { + tm.tv_sec = 0; + tm.tv_nsec = SPIN_SLEEP_DURATION; + nanosleep(&tm, NULL); + cnt = 0; + } + } +} + +#endif diff --git a/newlib/libc/sys/linux/linuxthreads/spinlock.h b/newlib/libc/sys/linux/linuxthreads/spinlock.h new file mode 100644 index 000000000..0ec40c57c --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/spinlock.h @@ -0,0 +1,218 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +#include <bits/initspin.h> + + +/* There are 2 compare and swap synchronization primitives with + different semantics: + + 1. compare_and_swap, which has acquire semantics (i.e. it + completes befor subsequent writes.) + 2. compare_and_swap_with_release_semantics, which has release + semantics (it completes after previous writes.) + + For those platforms on which they are the same. HAS_COMPARE_AND_SWAP + should be defined. For those platforms on which they are different, + HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS has to be defined. */ + +#ifndef HAS_COMPARE_AND_SWAP +#ifdef HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS +#define HAS_COMPARE_AND_SWAP +#endif +#endif + +#if defined(TEST_FOR_COMPARE_AND_SWAP) + +extern int __pthread_has_cas; +extern int __pthread_compare_and_swap(long * ptr, long oldval, long newval, + int * spinlock); + +static inline int compare_and_swap(long * ptr, long oldval, long newval, + int * spinlock) +{ + if (__builtin_expect (__pthread_has_cas, 1)) + return __compare_and_swap(ptr, oldval, newval); + else + return __pthread_compare_and_swap(ptr, oldval, newval, spinlock); +} + +#elif defined(HAS_COMPARE_AND_SWAP) + +#ifdef IMPLEMENT_TAS_WITH_CAS +#define testandset(p) !__compare_and_swap((long int *) p, 0, 1) +#endif + +#ifdef HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS + +static inline int +compare_and_swap_with_release_semantics (long * ptr, long oldval, + long newval, int * spinlock) +{ + return __compare_and_swap_with_release_semantics (ptr, oldval, + newval); +} + +#endif + +static inline int compare_and_swap(long * ptr, long oldval, long newval, + int * spinlock) +{ + return __compare_and_swap(ptr, oldval, newval); +} + +#else + +extern int __pthread_compare_and_swap(long * ptr, long oldval, long newval, + int * spinlock); + +static inline int compare_and_swap(long * ptr, long oldval, long newval, + int * spinlock) +{ + return __pthread_compare_and_swap(ptr, oldval, newval, spinlock); +} + +#endif + +#ifndef HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS +#define compare_and_swap_with_release_semantics compare_and_swap +#define __compare_and_swap_with_release_semantics __compare_and_swap +#endif + +/* Internal locks */ + +extern void internal_function __pthread_lock(struct _pthread_fastlock * lock, + pthread_descr self); +extern int __pthread_unlock(struct _pthread_fastlock *lock); + +static inline void __pthread_init_lock(struct _pthread_fastlock * lock) +{ + lock->__status = 0; + lock->__spinlock = __LT_SPINLOCK_INIT; +} + +static inline int __pthread_trylock (struct _pthread_fastlock * lock) +{ +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + return (testandset(&lock->__spinlock) ? EBUSY : 0); + } +#endif + +#if defined HAS_COMPARE_AND_SWAP + do { + if (lock->__status != 0) return EBUSY; + } while(! __compare_and_swap(&lock->__status, 0, 1)); + return 0; +#endif +} + +/* Variation of internal lock used for pthread_mutex_t, supporting + timed-out waits. Warning: do not mix these operations with the above ones + over the same lock object! */ + +extern void __pthread_alt_lock(struct _pthread_fastlock * lock, + pthread_descr self); + +extern int __pthread_alt_timedlock(struct _pthread_fastlock * lock, + pthread_descr self, const struct timespec *abstime); + +extern void __pthread_alt_unlock(struct _pthread_fastlock *lock); + +static inline void __pthread_alt_init_lock(struct _pthread_fastlock * lock) +{ + lock->__status = 0; + lock->__spinlock = __LT_SPINLOCK_INIT; +} + +static inline int __pthread_alt_trylock (struct _pthread_fastlock * lock) +{ +#if defined TEST_FOR_COMPARE_AND_SWAP + if (!__pthread_has_cas) +#endif +#if !defined HAS_COMPARE_AND_SWAP || defined TEST_FOR_COMPARE_AND_SWAP + { + int res = EBUSY; + + if (testandset(&lock->__spinlock) == 0) + { + if (lock->__status == 0) + { + lock->__status = 1; + WRITE_MEMORY_BARRIER(); + res = 0; + } + lock->__spinlock = __LT_SPINLOCK_INIT; + } + return res; + } +#endif + +#if defined HAS_COMPARE_AND_SWAP + do { + if (lock->__status != 0) return EBUSY; + } while(! compare_and_swap(&lock->__status, 0, 1, &lock->__spinlock)); + return 0; +#endif +} + +/* Operations on pthread_atomic, which is defined in internals.h */ + +static inline long atomic_increment(struct pthread_atomic *pa) +{ + long oldval; + + do { + oldval = pa->p_count; + } while (!compare_and_swap(&pa->p_count, oldval, oldval + 1, &pa->p_spinlock)); + + return oldval; +} + + +static inline long atomic_decrement(struct pthread_atomic *pa) +{ + long oldval; + + do { + oldval = pa->p_count; + } while (!compare_and_swap(&pa->p_count, oldval, oldval - 1, &pa->p_spinlock)); + + return oldval; +} + + +static inline void +__pthread_set_own_extricate_if (pthread_descr self, pthread_extricate_if *peif) +{ + /* Only store a non-null peif if the thread has cancellation enabled. + Otherwise pthread_cancel will unconditionally call the extricate handler, + and restart the thread giving rise to forbidden spurious wakeups. */ + if (peif == NULL + || THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) + { + /* If we are removing the extricate interface, we need to synchronize + against pthread_cancel so that it does not continue with a pointer + to a deallocated pthread_extricate_if struct! The thread lock + is (ab)used for this synchronization purpose. */ + if (peif == NULL) + __pthread_lock (THREAD_GETMEM(self, p_lock), self); + THREAD_SETMEM(self, p_extricate, peif); + if (peif == NULL) + __pthread_unlock (THREAD_GETMEM(self, p_lock)); + } +} diff --git a/newlib/libc/sys/linux/linuxthreads/sysctl.c b/newlib/libc/sys/linux/linuxthreads/sysctl.c new file mode 100644 index 000000000..2512f17f1 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/sysctl.c @@ -0,0 +1,43 @@ +/* Read or write system information. Linux version. + Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <errno.h> +#include <sys/sysctl.h> + +#include <machine/syscall.h> + +static _syscall1(int,_sysctl,struct __sysctl_args *,args) + +int +__sysctl (int *name, int nlen, void *oldval, size_t *oldlenp, + void *newval, size_t newlen) +{ + struct __sysctl_args args = + { + name: name, + nlen: nlen, + oldval: oldval, + oldlenp: oldlenp, + newval: newval, + newlen: newlen + }; + + return _sysctl(&args); +} +weak_alias (__sysctl, sysctl) diff --git a/newlib/libc/sys/linux/linuxthreads/td_init.c b/newlib/libc/sys/linux/linuxthreads/td_init.c new file mode 100644 index 000000000..6c4dfc623 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_init.c @@ -0,0 +1,32 @@ +/* Initialization function of thread debugger support library. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + +int __td_debug; + + +td_err_e +td_init (void) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_log.c b/newlib/libc/sys/linux/linuxthreads/td_log.c new file mode 100644 index 000000000..2007eaacc --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_log.c @@ -0,0 +1,32 @@ +/* Noop, left for historical reasons. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_log (void) +{ + /* This interface is deprecated in the Sun interface. We provide it + for compatibility but don't do anyhting ourself. We might in + future do some logging if this seems reasonable. */ + LOG (__FUNCTION__); + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_symbol_list.c b/newlib/libc/sys/linux/linuxthreads/td_symbol_list.c new file mode 100644 index 000000000..e64d298f9 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_symbol_list.c @@ -0,0 +1,55 @@ +/* Return list of symbols the library can request. + Copyright (C) 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <assert.h> +#include <gnu/lib-names.h> +#include "thread_dbP.h" + + +static const char *symbol_list_arr[] = +{ + [PTHREAD_THREADS_EVENTS] = "__pthread_threads_events", + [PTHREAD_LAST_EVENT] = "__pthread_last_event", + [PTHREAD_HANDLES_NUM] = "__pthread_handles_num", + [PTHREAD_HANDLES] = "__pthread_handles", + [PTHREAD_KEYS] = "pthread_keys", + [LINUXTHREADS_PTHREAD_THREADS_MAX] = "__linuxthreads_pthread_threads_max", + [LINUXTHREADS_PTHREAD_KEYS_MAX] = "__linuxthreads_pthread_keys_max", + [LINUXTHREADS_PTHREAD_SIZEOF_DESCR] = "__linuxthreads_pthread_sizeof_descr", + [LINUXTHREADS_CREATE_EVENT] = "__linuxthreads_create_event", + [LINUXTHREADS_DEATH_EVENT] = "__linuxthreads_death_event", + [LINUXTHREADS_REAP_EVENT] = "__linuxthreads_reap_event", + [NUM_MESSAGES] = NULL +}; + + +const char ** +td_symbol_list (void) +{ + return symbol_list_arr; +} + + +int +td_lookup (struct ps_prochandle *ps, int idx, psaddr_t *sym_addr) +{ + assert (idx >= 0 && idx < NUM_MESSAGES); + return ps_pglobal_lookup (ps, LIBPTHREAD_SO, symbol_list_arr[idx], sym_addr); +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_clear_event.c b/newlib/libc/sys/linux/linuxthreads/td_ta_clear_event.c new file mode 100644 index 000000000..fc7fde135 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_clear_event.c @@ -0,0 +1,53 @@ +/* Globally disable events. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_clear_event (ta, event) + const td_thragent_t *ta; + td_thr_events_t *event; +{ + td_thr_events_t old_event; + int i; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Write the new value into the thread data structure. */ + if (ps_pdread (ta->ph, ta->pthread_threads_eventsp, + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Remove the set bits in. */ + for (i = 0; i < TD_EVENTSIZE; ++i) + old_event.event_bits[i] &= ~event->event_bits[i]; + + /* Write the new value into the thread data structure. */ + if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp, + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_delete.c b/newlib/libc/sys/linux/linuxthreads/td_ta_delete.c new file mode 100644 index 000000000..5d235630d --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_delete.c @@ -0,0 +1,58 @@ +/* Detach to target process. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stdlib.h> + +#include "thread_dbP.h" + + +td_err_e +td_ta_delete (td_thragent_t *ta) +{ + LOG (__FUNCTION__); + + /* Safety check. */ + if (ta == NULL || __td_agent_list == NULL) + return TD_BADTA; + + /* Remove the handle from the list. */ + if (ta == __td_agent_list->ta) + /* It's the first element of the list. */ + __td_agent_list = __td_agent_list->next; + else + { + /* We have to search for it. */ + struct agent_list *runp = __td_agent_list; + + while (runp->next != NULL && runp->next->ta != ta) + runp = runp->next; + + if (runp->next == NULL) + /* It's not a valid decriptor since it is not in the list. */ + return TD_BADTA; + + runp->next = runp->next->next; + } + + /* The handle was allocated in `td_ta_new'. */ + free (ta); + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_enable_stats.c b/newlib/libc/sys/linux/linuxthreads/td_ta_enable_stats.c new file mode 100644 index 000000000..5a6fef7ee --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_enable_stats.c @@ -0,0 +1,35 @@ +/* Enable collection of statistics for process. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_enable_stats (const td_thragent_t *ta, int enable) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_event_addr.c b/newlib/libc/sys/linux/linuxthreads/td_ta_event_addr.c new file mode 100644 index 000000000..4f0f7bbf1 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_event_addr.c @@ -0,0 +1,73 @@ +/* Get event address. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_event_addr (const td_thragent_t *ta, td_event_e event, td_notify_t *addr) +{ + td_err_e res = TD_NOEVENT; + int idx = -1; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + switch (event) + { + case TD_CREATE: + idx = LINUXTHREADS_CREATE_EVENT; + break; + + case TD_DEATH: + idx = LINUXTHREADS_DEATH_EVENT; + break; + + case TD_REAP: + idx = LINUXTHREADS_REAP_EVENT; + break; + + default: + /* Event cannot be handled. */ + break; + } + + /* Now get the address. */ + if (idx != -1) + { + psaddr_t taddr; + + if (td_lookup (ta->ph, idx, &taddr) == PS_OK) + { + /* Success, we got the address. */ + addr->type = NOTIFY_BPT; + addr->u.bptaddr = taddr; + + res = TD_OK; + } + else + res = TD_ERR; + } + + return res; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_event_getmsg.c b/newlib/libc/sys/linux/linuxthreads/td_ta_event_getmsg.c new file mode 100644 index 000000000..a63a3d0a7 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_event_getmsg.c @@ -0,0 +1,128 @@ +/* Retrieve event. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stddef.h> +#include <string.h> + +#include "thread_dbP.h" + + +td_err_e +td_ta_event_getmsg (const td_thragent_t *ta, td_event_msg_t *msg) +{ + /* XXX I cannot think of another way but using a static variable. */ + static td_thrhandle_t th; + td_eventbuf_t event; + psaddr_t addr; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Get the pointer to the thread descriptor with the last event. */ + if (ps_pdread (ta->ph, ta->pthread_last_event, + &addr, sizeof (void *)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* If the pointer is NULL no event occurred. */ + if (addr == 0) + return TD_NOMSG; + + /* Read the even structure from the target. */ + if (ps_pdread (ta->ph, + ((char *) addr + + offsetof (struct _pthread_descr_struct, p_eventbuf)), + &event, sizeof (td_eventbuf_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Check whether an event occurred. */ + if (event.eventnum == TD_EVENT_NONE) + { + /* Oh well, this means the last event was already read. So + we have to look for any other event. */ + struct pthread_handle_struct handles[ta->pthread_threads_max]; + int num; + int i; + + /* Read the number of currently active threads. */ + if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) + != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Now read the handles. */ + if (ps_pdread (ta->ph, ta->handles, handles, + ta->pthread_threads_max * sizeof (handles[0])) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + for (i = 0; i < ta->pthread_threads_max && num > 0; ++i) + { + if (handles[i].h_descr == NULL) + /* No entry here. */ + continue; + + /* First count this active thread. */ + --num; + + if (handles[i].h_descr == addr) + /* We already handled this. */ + continue; + + /* Read the event data for this thread. */ + if (ps_pdread (ta->ph, + ((char *) handles[i].h_descr + + offsetof (struct _pthread_descr_struct, + p_eventbuf)), + &event, sizeof (td_eventbuf_t)) != PS_OK) + return TD_ERR; + + if (event.eventnum != TD_EVENT_NONE) + { + /* We found a thread with an unreported event. */ + addr = handles[i].h_descr; + break; + } + } + + /* If we haven't found any other event signal this to the user. */ + if (event.eventnum == TD_EVENT_NONE) + return TD_NOMSG; + } + + /* Generate the thread descriptor. */ + th.th_ta_p = (td_thragent_t *) ta; + th.th_unique = addr; + + /* Fill the user's data structure. */ + msg->event = event.eventnum; + msg->th_p = &th; + msg->msg.data = (uintptr_t) event.eventdata; + + /* And clear the event message in the target. */ + memset (&event, '\0', sizeof (td_eventbuf_t)); + if (ps_pdwrite (ta->ph, + ((char *) addr + + offsetof (struct _pthread_descr_struct, p_eventbuf)), + &event, sizeof (td_eventbuf_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_get_nthreads.c b/newlib/libc/sys/linux/linuxthreads/td_ta_get_nthreads.c new file mode 100644 index 000000000..f275a25e7 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_get_nthreads.c @@ -0,0 +1,42 @@ +/* Get the number of threads in the process. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + +td_err_e +td_ta_get_nthreads (const td_thragent_t *ta, int *np) +{ + psaddr_t addr; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Access the variable `__pthread_handles_num'. */ + if (td_lookup (ta->ph, PTHREAD_HANDLES_NUM, &addr) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + if (ps_pdread (ta->ph, addr, np, sizeof (int)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_get_ph.c b/newlib/libc/sys/linux/linuxthreads/td_ta_get_ph.c new file mode 100644 index 000000000..e08d52137 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_get_ph.c @@ -0,0 +1,36 @@ +/* Get external process handle. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_get_ph (const td_thragent_t *ta, struct ps_prochandle **ph) +{ + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + *ph = ta->ph; + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_get_stats.c b/newlib/libc/sys/linux/linuxthreads/td_ta_get_stats.c new file mode 100644 index 000000000..9aa049c3e --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_get_stats.c @@ -0,0 +1,35 @@ +/* Retrieve statistics for process. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_get_stats (const td_thragent_t *ta, td_ta_stats_t *statsp) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_map_id2thr.c b/newlib/libc/sys/linux/linuxthreads/td_ta_map_id2thr.c new file mode 100644 index 000000000..5171a5bf1 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_map_id2thr.c @@ -0,0 +1,66 @@ +/* Map thread ID to thread handle. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th) +{ + struct pthread_handle_struct phc; + struct _pthread_descr_struct pds; + int pthread_threads_max; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Make the following expression a bit smaller. */ + pthread_threads_max = ta->pthread_threads_max; + + /* We can compute the entry in the handle array we want. */ + if (ps_pdread (ta->ph, ta->handles + pt % pthread_threads_max, &phc, + sizeof (struct pthread_handle_struct)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Test whether this entry is in use. */ + if (phc.h_descr == NULL) + return TD_BADTH; + + /* Next test: get the descriptor to see whether this is not an old + thread handle. */ + if (ps_pdread (ta->ph, phc.h_descr, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + if (pds.p_tid != pt) + return TD_BADTH; + + if (pds.p_terminated != 0) + return TD_NOTHR; + + /* Create the `td_thrhandle_t' object. */ + th->th_ta_p = (td_thragent_t *) ta; + th->th_unique = phc.h_descr; + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_map_lwp2thr.c b/newlib/libc/sys/linux/linuxthreads/td_ta_map_lwp2thr.c new file mode 100644 index 000000000..8ae5aec78 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_map_lwp2thr.c @@ -0,0 +1,81 @@ +/* Which thread is running on an lwp? + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) +{ + int pthread_threads_max = ta->pthread_threads_max; + size_t sizeof_descr = ta->sizeof_descr; + struct pthread_handle_struct phc[pthread_threads_max]; + size_t cnt; +#ifdef ALL_THREADS_STOPPED + int num; +#else +# define num 1 +#endif + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Read all the descriptors. */ + if (ps_pdread (ta->ph, ta->handles, phc, + sizeof (struct pthread_handle_struct) * pthread_threads_max) + != PS_OK) + return TD_ERR; /* XXX Other error value? */ + +#ifdef ALL_THREADS_STOPPED + /* Read the number of currently active threads. */ + if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ +#endif + + /* Get the entries one after the other and find out whether the ID + matches. */ + for (cnt = 0; cnt < pthread_threads_max && num > 0; ++cnt) + if (phc[cnt].h_descr != NULL) + { + struct _pthread_descr_struct pds; + +#ifdef ALL_THREADS_STOPPED + /* First count this active thread. */ + --num; +#endif + + if (ps_pdread (ta->ph, phc[cnt].h_descr, &pds, sizeof_descr) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + if ((pds.p_pid ?: ps_getpid (ta->ph)) == lwpid) + { + /* Found it. Now fill in the `td_thrhandle_t' object. */ + th->th_ta_p = (td_thragent_t *) ta; + th->th_unique = phc[cnt].h_descr; + + return TD_OK; + } + } + + return TD_NOLWP; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_new.c b/newlib/libc/sys/linux/linuxthreads/td_ta_new.c new file mode 100644 index 000000000..7bf687905 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_new.c @@ -0,0 +1,132 @@ +/* Attach to target process. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stddef.h> +#include <stdlib.h> + +#include "thread_dbP.h" + + +/* Datatype for the list of known thread agents. Normally there will + be exactly one so we don't spend much though on making it fast. */ +struct agent_list *__td_agent_list; + + +td_err_e +td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta) +{ + psaddr_t addr; + struct agent_list *elemp; + + LOG (__FUNCTION__); + + /* Get the global event mask. This is one of the variables which + are new in the thread library to enable debugging. If it is + not available we cannot debug. */ + if (td_lookup (ps, PTHREAD_THREADS_EVENTS, &addr) != PS_OK) + return TD_NOLIBTHREAD; + + /* Fill in the appropriate information. */ + *ta = (td_thragent_t *) malloc (sizeof (td_thragent_t)); + if (*ta == NULL) + return TD_MALLOC; + + /* Store the proc handle which we will pass to the callback functions + back into the debugger. */ + (*ta)->ph = ps; + + /* Remember the address. */ + (*ta)->pthread_threads_eventsp = (td_thr_events_t *) addr; + + /* Get the pointer to the variable pointing to the thread descriptor + with the last event. */ + if (td_lookup (ps, PTHREAD_LAST_EVENT, &(*ta)->pthread_last_event) != PS_OK) + { + free_return: + free (*ta); + return TD_ERR; + } + + /* Get the pointer to the variable containing the number of active + threads. */ + if (td_lookup (ps, PTHREAD_HANDLES_NUM, &(*ta)->pthread_handles_num) + != PS_OK) + goto free_return; + + /* See whether the library contains the necessary symbols. */ + if (td_lookup (ps, PTHREAD_HANDLES, &addr) != PS_OK) + goto free_return; + + (*ta)->handles = (struct pthread_handle_struct *) addr; + + + if (td_lookup (ps, PTHREAD_KEYS, &addr) != PS_OK) + goto free_return; + + /* Cast to the right type. */ + (*ta)->keys = (struct pthread_key_struct *) addr; + + /* Find out about the maximum number of threads. Old implementations + don't provide this information. In this case we assume that the + debug library is compiled with the same values. */ + if (td_lookup (ps, LINUXTHREADS_PTHREAD_THREADS_MAX, &addr) != PS_OK) + (*ta)->pthread_threads_max = PTHREAD_THREADS_MAX; + else + { + if (ps_pdread (ps, addr, &(*ta)->pthread_threads_max, sizeof (int)) + != PS_OK) + goto free_return; + } + + /* Similar for the maximum number of thread local data keys. */ + if (td_lookup (ps, LINUXTHREADS_PTHREAD_KEYS_MAX, &addr) != PS_OK) + (*ta)->pthread_keys_max = PTHREAD_KEYS_MAX; + else + { + if (ps_pdread (ps, addr, &(*ta)->pthread_keys_max, sizeof (int)) + != PS_OK) + goto free_return; + } + + /* And for the size of the second level arrays for the keys. */ + if (td_lookup (ps, LINUXTHREADS_PTHREAD_SIZEOF_DESCR, &addr) != PS_OK) + (*ta)->sizeof_descr = sizeof (struct _pthread_descr_struct); + else + { + if (ps_pdread (ps, addr, &(*ta)->sizeof_descr, sizeof (int)) != PS_OK) + goto free_return; + } + + /* Now add the new agent descriptor to the list. */ + elemp = (struct agent_list *) malloc (sizeof (struct agent_list)); + if (elemp == NULL) + { + /* Argh, now that everything else worked... */ + free (*ta); + return TD_MALLOC; + } + + /* We don't care for thread-safety here. */ + elemp->ta = *ta; + elemp->next = __td_agent_list; + __td_agent_list = elemp; + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_reset_stats.c b/newlib/libc/sys/linux/linuxthreads/td_ta_reset_stats.c new file mode 100644 index 000000000..9cc386cf8 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_reset_stats.c @@ -0,0 +1,35 @@ +/* Reset statistics. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_reset_stats (const td_thragent_t *ta) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_set_event.c b/newlib/libc/sys/linux/linuxthreads/td_ta_set_event.c new file mode 100644 index 000000000..0ea8fc119 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_set_event.c @@ -0,0 +1,53 @@ +/* Globally enable events. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_set_event (ta, event) + const td_thragent_t *ta; + td_thr_events_t *event; +{ + td_thr_events_t old_event; + int i; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + /* Write the new value into the thread data structure. */ + if (ps_pdread (ta->ph, ta->pthread_threads_eventsp, + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Or the new bits in. */ + for (i = 0; i < TD_EVENTSIZE; ++i) + old_event.event_bits[i] |= event->event_bits[i]; + + /* Write the new value into the thread data structure. */ + if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp, + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_setconcurrency.c b/newlib/libc/sys/linux/linuxthreads/td_ta_setconcurrency.c new file mode 100644 index 000000000..25c1c90c7 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_setconcurrency.c @@ -0,0 +1,35 @@ +/* Set suggested concurrency level for process. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_ta_setconcurrency (const td_thragent_t *ta, int level) +{ + /* This is something LinuxThreads does not support. */ + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + return TD_NOCAPAB; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_thr_iter.c b/newlib/libc/sys/linux/linuxthreads/td_ta_thr_iter.c new file mode 100644 index 000000000..4c6f3f4cb --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_thr_iter.c @@ -0,0 +1,142 @@ +/* Iterate over a process's threads. + Copyright (C) 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" +#include <alloca.h> + +static int +handle_descr (const td_thragent_t *ta, td_thr_iter_f *callback, + void *cbdata_p, td_thr_state_e state, int ti_pri, + size_t cnt, pthread_descr descr) +{ + struct _pthread_descr_struct pds; + size_t sizeof_descr = ta->sizeof_descr; + td_thrhandle_t th; + + if (ps_pdread (ta->ph, descr, &pds, sizeof_descr) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* The manager thread must be handled special. The descriptor + exists but the thread only gets created when the first + `pthread_create' call is issued. A clear indication that this + happened is when the p_pid field is non-zero. */ + if (cnt == 1 && pds.p_pid == 0) + return TD_OK; + + /* Now test whether this thread matches the specified + conditions. */ + + /* Only if the priority level is as high or higher. */ + if (pds.p_priority < ti_pri) + return TD_OK; + + /* Test the state. + XXX This is incomplete. */ + if (state != TD_THR_ANY_STATE) + return TD_OK; + + /* XXX For now we ignore threads which are not running anymore. + The reason is that gdb tries to get the registers and fails. + In future we should have a special mode of the thread library + in which we keep the process around until the actual join + operation happened. */ + if (pds.p_exited != 0) + return TD_OK; + + /* Yep, it matches. Call the callback function. */ + th.th_ta_p = (td_thragent_t *) ta; + th.th_unique = descr; + if (callback (&th, cbdata_p) != 0) + return TD_DBERR; + + /* All done successfully. */ + return TD_OK; +} + + +td_err_e +td_ta_thr_iter (const td_thragent_t *ta, td_thr_iter_f *callback, + void *cbdata_p, td_thr_state_e state, int ti_pri, + sigset_t *ti_sigmask_p, unsigned int ti_user_flags) +{ + int pthread_threads_max; + struct pthread_handle_struct *phc; + td_err_e result = TD_OK; + int cnt; +#ifdef ALL_THREADS_STOPPED + int num; +#else +# define num 1 +#endif + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + pthread_threads_max = ta->pthread_threads_max; + phc = (struct pthread_handle_struct *) alloca (sizeof (phc[0]) + * pthread_threads_max); + + /* First read only the main thread and manager thread information. */ + if (ps_pdread (ta->ph, ta->handles, phc, + sizeof (struct pthread_handle_struct) * 2) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Now handle these descriptors. */ + result = handle_descr (ta, callback, cbdata_p, state, ti_pri, 0, + phc[0].h_descr); + if (result != TD_OK) + return result; + result = handle_descr (ta, callback, cbdata_p, state, ti_pri, 1, + phc[1].h_descr); + if (result != TD_OK) + return result; + + /* Read all the descriptors. */ + if (ps_pdread (ta->ph, ta->handles + 2, &phc[2], + (sizeof (struct pthread_handle_struct) + * (pthread_threads_max - 2))) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + +#ifdef ALL_THREADS_STOPPED + /* Read the number of currently active threads. */ + if (ps_pdread (ta->ph, ta->pthread_handles_num, &num, sizeof (int)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ +#endif + + /* Now get all descriptors, one after the other. */ + for (cnt = 2; cnt < pthread_threads_max && num > 0; ++cnt) + if (phc[cnt].h_descr != NULL) + { +#ifdef ALL_THREADS_STOPPED + /* First count this active thread. */ + --num; +#endif + + result = handle_descr (ta, callback, cbdata_p, state, ti_pri, cnt, + phc[cnt].h_descr); + if (result != TD_OK) + break; + } + + return result; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_ta_tsd_iter.c b/newlib/libc/sys/linux/linuxthreads/td_ta_tsd_iter.c new file mode 100644 index 000000000..f29938564 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_ta_tsd_iter.c @@ -0,0 +1,55 @@ +/* Iterate over a process's thread-specific data. + Copyright (C) 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" +#include <alloca.h> + +td_err_e +td_ta_tsd_iter (const td_thragent_t *ta, td_key_iter_f *callback, + void *cbdata_p) +{ + struct pthread_key_struct *keys; + int pthread_keys_max; + int cnt; + + LOG (__FUNCTION__); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + pthread_keys_max = ta->pthread_keys_max; + keys = (struct pthread_key_struct *) alloca (sizeof (keys[0]) + * pthread_keys_max); + + /* Read all the information about the keys. */ + if (ps_pdread (ta->ph, ta->keys, keys, + sizeof (keys[0]) * pthread_keys_max) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Now get all descriptors, one after the other. */ + for (cnt = 0; cnt < pthread_keys_max; ++cnt) + if (keys[cnt].in_use + /* Return with an error if the callback returns a nonzero value. */ + && callback (cnt, keys[cnt].destr, cbdata_p) != 0) + return TD_DBERR; + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_clear_event.c b/newlib/libc/sys/linux/linuxthreads/td_thr_clear_event.c new file mode 100644 index 000000000..b75c0f0aa --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_clear_event.c @@ -0,0 +1,57 @@ +/* Disable specific event for thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stddef.h> + +#include "thread_dbP.h" + + +td_err_e +td_thr_clear_event (th, event) + const td_thrhandle_t *th; + td_thr_events_t *event; +{ + td_thr_events_t old_event; + int i; + + LOG (__FUNCTION__); + + /* Write the new value into the thread data structure. */ + if (ps_pdread (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, + p_eventbuf.eventmask)), + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Remove the set bits in. */ + for (i = 0; i < TD_EVENTSIZE; ++i) + old_event.event_bits[i] &= ~event->event_bits[i]; + + /* Write the new value into the thread data structure. */ + if (ps_pdwrite (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, + p_eventbuf.eventmask)), + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_dbresume.c b/newlib/libc/sys/linux/linuxthreads/td_thr_dbresume.c new file mode 100644 index 000000000..68d62afd4 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_dbresume.c @@ -0,0 +1,30 @@ +/* Resume execution of given thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_dbresume (const td_thrhandle_t *th) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_NOCAPAB; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_dbsuspend.c b/newlib/libc/sys/linux/linuxthreads/td_thr_dbsuspend.c new file mode 100644 index 000000000..0655a1756 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_dbsuspend.c @@ -0,0 +1,30 @@ +/* Suspend execution of given thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_dbsuspend (const td_thrhandle_t *th) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_NOCAPAB; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_event_enable.c b/newlib/libc/sys/linux/linuxthreads/td_thr_event_enable.c new file mode 100644 index 000000000..007f2a464 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_event_enable.c @@ -0,0 +1,41 @@ +/* Enable event process-wide. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stddef.h> + +#include "thread_dbP.h" + + +td_err_e +td_thr_event_enable (th, onoff) + const td_thrhandle_t *th; + int onoff; +{ + LOG (__FUNCTION__); + + /* Write the new value into the thread data structure. */ + if (ps_pdwrite (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, p_report_events)), + &onoff, sizeof (int)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_event_getmsg.c b/newlib/libc/sys/linux/linuxthreads/td_thr_event_getmsg.c new file mode 100644 index 000000000..95b05ff07 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_event_getmsg.c @@ -0,0 +1,60 @@ +/* Retrieve event. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stddef.h> +#include <string.h> + +#include "thread_dbP.h" + + +td_err_e +td_thr_event_getmsg (const td_thrhandle_t *th, td_event_msg_t *msg) +{ + td_eventbuf_t event; + + LOG (__FUNCTION__); + + /* Read the even structure from the target. */ + if (ps_pdread (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, p_eventbuf)), + &event, sizeof (td_eventbuf_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Check whether an event occurred. */ + if (event.eventnum == TD_EVENT_NONE) + /* Nothing. */ + return TD_NOMSG; + + /* Fill the user's data structure. */ + msg->event = event.eventnum; + msg->th_p = th; + msg->msg.data = (uintptr_t) event.eventdata; + + /* And clear the event message in the target. */ + memset (&event, '\0', sizeof (td_eventbuf_t)); + if (ps_pdwrite (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, p_eventbuf)), + &event, sizeof (td_eventbuf_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_get_info.c b/newlib/libc/sys/linux/linuxthreads/td_thr_get_info.c new file mode 100644 index 000000000..ed6b20f59 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_get_info.c @@ -0,0 +1,76 @@ +/* Get thread information. + Copyright (C) 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stddef.h> +#include <string.h> + +#include "thread_dbP.h" + + +td_err_e +td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop) +{ + struct _pthread_descr_struct pds; + + LOG (__FUNCTION__); + + /* Get the thread descriptor. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + th->th_ta_p->sizeof_descr) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Fill in information. Clear first to provide reproducable + results for the fields we do not fill in. */ + memset (infop, '\0', sizeof (td_thrinfo_t)); + + /* We have to handle the manager thread special since the thread + descriptor in older versions is not fully initialized. */ + if (pds.p_nr == 1) + { + infop->ti_tid = th->th_ta_p->pthread_threads_max * 2 + 1; + infop->ti_type = TD_THR_SYSTEM; + infop->ti_state = TD_THR_ACTIVE; + } + else + { + infop->ti_tid = pds.p_tid; + infop->ti_tls = (char *) pds.p_specific; + infop->ti_pri = pds.p_priority; + infop->ti_type = TD_THR_USER; + + if (! pds.p_terminated) + /* XXX For now there is no way to get more information. */ + infop->ti_state = TD_THR_ACTIVE; + else if (! pds.p_detached) + infop->ti_state = TD_THR_ZOMBIE; + else + infop->ti_state = TD_THR_UNKNOWN; + } + + /* Initialization which are the same in both cases. */ + infop->ti_lid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph); + infop->ti_ta_p = th->th_ta_p; + infop->ti_startfunc = pds.p_start_args.start_routine; + memcpy (&infop->ti_events, &pds.p_eventbuf.eventmask, + sizeof (td_thr_events_t)); + infop->ti_traceme = pds.p_report_events != 0; + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_getfpregs.c b/newlib/libc/sys/linux/linuxthreads/td_thr_getfpregs.c new file mode 100644 index 000000000..67d5cd1e2 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_getfpregs.c @@ -0,0 +1,49 @@ +/* Get a thread's floating-point register set. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_getfpregs (const td_thrhandle_t *th, prfpregset_t *regset) +{ + struct _pthread_descr_struct pds; + + LOG (__FUNCTION__); + + /* We have to get the state and the PID for this thread. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; + + /* If the thread already terminated we return all zeroes. */ + if (pds.p_terminated) + memset (regset, '\0', sizeof (*regset)); + /* Otherwise get the register content through the callback. */ + else + { + pid_t pid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph); + + if (ps_lgetfpregs (th->th_ta_p->ph, pid, regset) != PS_OK) + return TD_ERR; + } + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_getgregs.c b/newlib/libc/sys/linux/linuxthreads/td_thr_getgregs.c new file mode 100644 index 000000000..5a42b6770 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_getgregs.c @@ -0,0 +1,49 @@ +/* Get a thread's general register set. + Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_getgregs (const td_thrhandle_t *th, prgregset_t gregs) +{ + struct _pthread_descr_struct pds; + + LOG (__FUNCTION__); + + /* We have to get the state and the PID for this thread. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; + + /* If the thread already terminated we return all zeroes. */ + if (pds.p_terminated) + memset (gregs, '\0', sizeof (prgregset_t)); + /* Otherwise get the register content through the callback. */ + else + { + pid_t pid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph); + + if (ps_lgetregs (th->th_ta_p->ph, pid, gregs) != PS_OK) + return TD_ERR; + } + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_getxregs.c b/newlib/libc/sys/linux/linuxthreads/td_thr_getxregs.c new file mode 100644 index 000000000..615d88296 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_getxregs.c @@ -0,0 +1,30 @@ +/* Get a thread's extra state register set. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_getxregs (const td_thrhandle_t *th, void *xregs) +{ + /* XXX This might be platform specific. */ + LOG (__FUNCTION__); + return TD_NOXREGS; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_getxregsize.c b/newlib/libc/sys/linux/linuxthreads/td_thr_getxregsize.c new file mode 100644 index 000000000..ed55bbab7 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_getxregsize.c @@ -0,0 +1,30 @@ +/* Get the size of the extra state register set for this architecture. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_getxregsize (const td_thrhandle_t *th, int *sizep) +{ + /* XXX This might be platform specific. */ + LOG (__FUNCTION__); + return TD_NOXREGS; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_set_event.c b/newlib/libc/sys/linux/linuxthreads/td_thr_set_event.c new file mode 100644 index 000000000..f537cce05 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_set_event.c @@ -0,0 +1,57 @@ +/* Enable specific event for thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stddef.h> + +#include "thread_dbP.h" + + +td_err_e +td_thr_set_event (th, event) + const td_thrhandle_t *th; + td_thr_events_t *event; +{ + td_thr_events_t old_event; + int i; + + LOG (__FUNCTION__); + + /* Write the new value into the thread data structure. */ + if (ps_pdread (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, + p_eventbuf.eventmask)), + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Or the new bits in. */ + for (i = 0; i < TD_EVENTSIZE; ++i) + old_event.event_bits[i] |= event->event_bits[i]; + + /* Write the new value into the thread data structure. */ + if (ps_pdwrite (th->th_ta_p->ph, + ((char *) th->th_unique + + offsetof (struct _pthread_descr_struct, + p_eventbuf.eventmask)), + &old_event, sizeof (td_thrhandle_t)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_setfpregs.c b/newlib/libc/sys/linux/linuxthreads/td_thr_setfpregs.c new file mode 100644 index 000000000..d5e1ce35a --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_setfpregs.c @@ -0,0 +1,46 @@ +/* Set a thread's floating-point register set. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_setfpregs (const td_thrhandle_t *th, const prfpregset_t *fpregs) +{ + struct _pthread_descr_struct pds; + + LOG (__FUNCTION__); + + /* We have to get the state and the PID for this thread. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; + + /* Only set the registers if the thread hasn't yet terminated. */ + if (pds.p_terminated == 0) + { + pid_t pid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph); + + if (ps_lsetfpregs (th->th_ta_p->ph, pid, fpregs) != PS_OK) + return TD_ERR; + } + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_setgregs.c b/newlib/libc/sys/linux/linuxthreads/td_thr_setgregs.c new file mode 100644 index 000000000..8c7baa8e9 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_setgregs.c @@ -0,0 +1,46 @@ +/* Set a thread's general register set. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_setgregs (const td_thrhandle_t *th, prgregset_t gregs) +{ + struct _pthread_descr_struct pds; + + LOG (__FUNCTION__); + + /* We have to get the state and the PID for this thread. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; + + /* Only set the registers if the thread hasn't yet terminated. */ + if (pds.p_terminated == 0) + { + pid_t pid = pds.p_pid ?: ps_getpid (th->th_ta_p->ph); + + if (ps_lsetregs (th->th_ta_p->ph, pid, gregs) != PS_OK) + return TD_ERR; + } + + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_setprio.c b/newlib/libc/sys/linux/linuxthreads/td_thr_setprio.c new file mode 100644 index 000000000..c1e3ca5b1 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_setprio.c @@ -0,0 +1,30 @@ +/* Set a thread's priority. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_setprio (const td_thrhandle_t *th, int prio) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_setsigpending.c b/newlib/libc/sys/linux/linuxthreads/td_thr_setsigpending.c new file mode 100644 index 000000000..bec429ea1 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_setsigpending.c @@ -0,0 +1,31 @@ +/* Raise a signal for a thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_setsigpending (const td_thrhandle_t *th, unsigned char n, + const sigset_t *ss) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_setxregs.c b/newlib/libc/sys/linux/linuxthreads/td_thr_setxregs.c new file mode 100644 index 000000000..c1915e5e9 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_setxregs.c @@ -0,0 +1,30 @@ +/* Set a thread's extra state register set. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_setxregs (const td_thrhandle_t *ta, const void *addr) +{ + /* XXX This might have to be platform specific. */ + LOG (__FUNCTION__); + return TD_NOXREGS; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_sigsetmask.c b/newlib/libc/sys/linux/linuxthreads/td_thr_sigsetmask.c new file mode 100644 index 000000000..ef3ebcbb8 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_sigsetmask.c @@ -0,0 +1,30 @@ +/* Set a thread's signal mask. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_sigsetmask (const td_thrhandle_t *th, const sigset_t *ss) +{ + /* XXX We have to figure out what has to be done. */ + LOG (__FUNCTION__); + return TD_OK; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_tsd.c b/newlib/libc/sys/linux/linuxthreads/td_thr_tsd.c new file mode 100644 index 000000000..302033681 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_tsd.c @@ -0,0 +1,76 @@ +/* Get a thread-specific data pointer for a thread. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_tsd (const td_thrhandle_t *th, const thread_key_t tk, void **data) +{ + struct _pthread_descr_struct pds; + struct pthread_key_struct *keys = th->th_ta_p->keys; + struct pthread_key_struct key; + int pthread_keys_max = th->th_ta_p->pthread_keys_max; + int pthread_key_2ndlevel_size = th->th_ta_p->pthread_key_2ndlevel_size; + unsigned int idx1st; + unsigned int idx2nd; + void *p; + + LOG (__FUNCTION__); + + /* Get the thread descriptor. */ + if (ps_pdread (th->th_ta_p->ph, th->th_unique, &pds, + sizeof (struct _pthread_descr_struct)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Check correct value of key. */ + if (tk >= pthread_keys_max) + return TD_BADKEY; + + /* Get the key entry. */ + if (ps_pdread (th->th_ta_p->ph, keys, &key, + sizeof (struct pthread_key_struct)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Fail if this key is not at all used. */ + if (! key.in_use) + return TD_BADKEY; + + /* Compute the indeces. */ + idx1st = tk / pthread_key_2ndlevel_size; + idx2nd = tk % pthread_key_2ndlevel_size; + + /* Check the pointer to the second level array. */ + if (pds.p_specific[idx1st] == NULL) + return TD_NOTSD; + + /* Now get the real key. + XXX I don't know whether it's correct but there is currently no + easy way to determine whether a key was never set or the value + is NULL. We return an error whenever the value is NULL. */ + if (ps_pdread (th->th_ta_p->ph, &pds.p_specific[idx1st][idx2nd], &p, + sizeof (void *)) != PS_OK) + return TD_ERR; + + if (p != NULL) + *data = p; + + return p != NULL ? TD_OK : TD_NOTSD; +} diff --git a/newlib/libc/sys/linux/linuxthreads/td_thr_validate.c b/newlib/libc/sys/linux/linuxthreads/td_thr_validate.c new file mode 100644 index 000000000..354471071 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/td_thr_validate.c @@ -0,0 +1,57 @@ +/* Validate a thread handle. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include "thread_dbP.h" + + +td_err_e +td_thr_validate (const td_thrhandle_t *th) +{ + struct pthread_handle_struct *handles = th->th_ta_p->handles; + int pthread_threads_max = th->th_ta_p->pthread_threads_max; + int cnt; + + LOG (__FUNCTION__); + + /* Now get all descriptors, one after the other. */ + for (cnt = 0; cnt < pthread_threads_max; ++cnt, ++handles) + { + struct pthread_handle_struct phc; + + if (ps_pdread (th->th_ta_p->ph, handles, &phc, + sizeof (struct pthread_handle_struct)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + if (phc.h_descr != NULL && phc.h_descr == th->th_unique) + { + struct _pthread_descr_struct pds; + + if (ps_pdread (th->th_ta_p->ph, phc.h_descr, &pds, + th->th_ta_p->sizeof_descr) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* XXX There should be another test using the TID but this is + currently not available. */ + return pds.p_terminated != 0 ? TD_NOTHR : TD_OK; + } + } + + return TD_ERR; +} diff --git a/newlib/libc/sys/linux/linuxthreads/testrtsig.h b/newlib/libc/sys/linux/linuxthreads/testrtsig.h new file mode 100644 index 000000000..cf36ab08a --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/testrtsig.h @@ -0,0 +1,36 @@ +/* Test whether RT signals are really available. + Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <string.h> +#include <sys/utsname.h> + +#include "kernel-features.h" + +static int +kernel_has_rtsig (void) +{ +#if __ASSUME_REALTIME_SIGNALS + return 1; +#else + struct utsname name; + + return uname (&name) == 0 && __strverscmp (name.release, "2.1.70") >= 0; +#endif +} diff --git a/newlib/libc/sys/linux/linuxthreads/thread_db.h b/newlib/libc/sys/linux/linuxthreads/thread_db.h new file mode 100644 index 000000000..b192d1f2e --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/thread_db.h @@ -0,0 +1,439 @@ +/* Copyright (C) 1999, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _THREAD_DB_H +#define _THREAD_DB_H 1 + +/* This is the debugger interface for the LinuxThreads library. It is + modelled closely after the interface with same names in Solaris with + the goal to share the same code in the debugger. */ +#include <pthread.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/procfs.h> + + +/* Error codes of the library. */ +typedef enum +{ + TD_OK, /* No error. */ + TD_ERR, /* No further specified error. */ + TD_NOTHR, /* No matching thread found. */ + TD_NOSV, /* No matching synchronization handle found. */ + TD_NOLWP, /* No matching light-weighted process found. */ + TD_BADPH, /* Invalid process handle. */ + TD_BADTH, /* Invalid thread handle. */ + TD_BADSH, /* Invalid synchronization handle. */ + TD_BADTA, /* Invalid thread agent. */ + TD_BADKEY, /* Invalid key. */ + TD_NOMSG, /* No event available. */ + TD_NOFPREGS, /* No floating-point register content available. */ + TD_NOLIBTHREAD, /* Application not linked with thread library. */ + TD_NOEVENT, /* Requested event is not supported. */ + TD_NOCAPAB, /* Capability not available. */ + TD_DBERR, /* Internal debug library error. */ + TD_NOAPLIC, /* Operation is not applicable. */ + TD_NOTSD, /* No thread-specific data available. */ + TD_MALLOC, /* Out of memory. */ + TD_PARTIALREG, /* Not entire register set was read or written. */ + TD_NOXREGS /* X register set not available for given thread. */ +} td_err_e; + + +/* Possible thread states. TD_THR_ANY_STATE is a pseudo-state used to + select threads regardless of state in td_ta_thr_iter(). */ +typedef enum +{ + TD_THR_ANY_STATE, + TD_THR_UNKNOWN, + TD_THR_STOPPED, + TD_THR_RUN, + TD_THR_ACTIVE, + TD_THR_ZOMBIE, + TD_THR_SLEEP, + TD_THR_STOPPED_ASLEEP +} td_thr_state_e; + +/* Thread type: user or system. TD_THR_ANY_TYPE is a pseudo-type used + to select threads regardless of type in td_ta_thr_iter(). */ +typedef enum +{ + TD_THR_ANY_TYPE, + TD_THR_USER, + TD_THR_SYSTEM +} td_thr_type_e; + + +/* Types of the debugging library. */ + +/* Handle for a process. This type is opaque. */ +typedef struct td_thragent td_thragent_t; + +/* The actual thread handle type. This is also opaque. */ +typedef struct td_thrhandle +{ + td_thragent_t *th_ta_p; + psaddr_t th_unique; +} td_thrhandle_t; + + +/* Flags for `td_ta_thr_iter'. */ +#define TD_THR_ANY_USER_FLAGS 0xffffffff +#define TD_THR_LOWEST_PRIORITY -20 +#define TD_SIGNO_MASK NULL + + +#define TD_EVENTSIZE 2 +#define BT_UISHIFT 5 /* log base 2 of BT_NBIPUI, to extract word index */ +#define BT_NBIPUI (1 << BT_UISHIFT) /* n bits per uint */ +#define BT_UIMASK (BT_NBIPUI - 1) /* to extract bit index */ + +/* Bitmask of enabled events. */ +typedef struct td_thr_events +{ + uint32_t event_bits[TD_EVENTSIZE]; +} td_thr_events_t; + +/* Event set manipulation macros. */ +#define __td_eventmask(n) \ + (UINT32_C (1) << (((n) - 1) & BT_UIMASK)) +#define __td_eventword(n) \ + ((UINT32_C ((n) - 1)) >> BT_UISHIFT) + +#define td_event_emptyset(setp) \ + do { \ + int __i; \ + for (__i = TD_EVENTSIZE; __i > 0; --__i) \ + (setp)->event_bits[__i - 1] = 0; \ + } while (0) + +#define td_event_fillset(setp) \ + do { \ + int __i; \ + for (__i = TD_EVENTSIZE; __i > 0; --__i) \ + (setp)->event_bits[__i - 1] = UINT32_C (0xffffffff); \ + } while (0) + +#define td_event_addset(setp, n) \ + (((setp)->event_bits[__td_eventword (n)]) |= __td_eventmask (n)) +#define td_event_delset(setp, n) \ + (((setp)->event_bits[__td_eventword (n)]) &= ~__td_eventmask (n)) +#define td_eventismember(setp, n) \ + (__td_eventmask (n) & ((setp)->event_bits[__td_eventword (n)])) +#if TD_EVENTSIZE == 2 +# define td_eventisempty(setp) \ + (!((setp)->event_bits[0]) && !((setp)->event_bits[1])) +#else +# error "td_eventisempty must be changed to match TD_EVENTSIZE" +#endif + +/* Events reportable by the thread implementation. */ +typedef enum +{ + TD_ALL_EVENTS, /* Pseudo-event number. */ + TD_EVENT_NONE = TD_ALL_EVENTS, /* Depends on context. */ + TD_READY, /* Is executable now. */ + TD_SLEEP, /* Blocked in a synchronization obj. */ + TD_SWITCHTO, /* Now assigned to a process. */ + TD_SWITCHFROM, /* Not anymore assigned to a process. */ + TD_LOCK_TRY, /* Trying to get an unavailable lock. */ + TD_CATCHSIG, /* Signal posted to the thread. */ + TD_IDLE, /* Process getting idle. */ + TD_CREATE, /* New thread created. */ + TD_DEATH, /* Thread terminated. */ + TD_PREEMPT, /* Preempted. */ + TD_PRI_INHERIT, /* Inherited elevated priority. */ + TD_REAP, /* Reaped. */ + TD_CONCURRENCY, /* Number of processes changing. */ + TD_TIMEOUT, /* Conditional variable wait timed out. */ + TD_MIN_EVENT_NUM = TD_READY, + TD_MAX_EVENT_NUM = TD_TIMEOUT, + TD_EVENTS_ENABLE = 31 /* Event reporting enabled. */ +} td_event_e; + +/* Values representing the different ways events are reported. */ +typedef enum +{ + NOTIFY_BPT, /* User must insert breakpoint at u.bptaddr. */ + NOTIFY_AUTOBPT, /* Breakpoint at u.bptaddr is automatically + inserted. */ + NOTIFY_SYSCALL /* System call u.syscallno will be invoked. */ +} td_notify_e; + +/* Description how event type is reported. */ +typedef struct td_notify +{ + td_notify_e type; /* Way the event is reported. */ + union + { + psaddr_t bptaddr; /* Address of breakpoint. */ + int syscallno; /* Number of system call used. */ + } u; +} td_notify_t; + +/* Structure used to report event. */ +typedef struct td_event_msg +{ + td_event_e event; /* Event type being reported. */ + const td_thrhandle_t *th_p; /* Thread reporting the event. */ + union + { +# if 0 + td_synchandle_t *sh; /* Handle of synchronization object. */ +#endif + uintptr_t data; /* Event specific data. */ + } msg; +} td_event_msg_t; + +/* Structure containing event data available in each thread structure. */ +typedef struct +{ + td_thr_events_t eventmask; /* Mask of enabled events. */ + td_event_e eventnum; /* Number of last event. */ + void *eventdata; /* Data associated with event. */ +} td_eventbuf_t; + + +/* Gathered statistics about the process. */ +typedef struct td_ta_stats +{ + int nthreads; /* Total number of threads in use. */ + int r_concurrency; /* Concurrency level requested by user. */ + int nrunnable_num; /* Average runnable threads, numerator. */ + int nrunnable_den; /* Average runnable threads, denominator. */ + int a_concurrency_num; /* Achieved concurrency level, numerator. */ + int a_concurrency_den; /* Achieved concurrency level, denominator. */ + int nlwps_num; /* Average number of processes in use, + numerator. */ + int nlwps_den; /* Average number of processes in use, + denominator. */ + int nidle_num; /* Average number of idling processes, + numerator. */ + int nidle_den; /* Average number of idling processes, + denominator. */ +} td_ta_stats_t; + + +/* Since Sun's library is based on Solaris threads we have to define a few + types to map them to POSIX threads. */ +typedef pthread_t thread_t; +typedef pthread_key_t thread_key_t; + + +/* Callback for iteration over threads. */ +typedef int td_thr_iter_f (const td_thrhandle_t *, void *); + +/* Callback for iteration over thread local data. */ +typedef int td_key_iter_f (thread_key_t, void (*) (void *), void *); + + + +/* Forward declaration. This has to be defined by the user. */ +struct ps_prochandle; + + +/* Information about the thread. */ +typedef struct td_thrinfo +{ + td_thragent_t *ti_ta_p; /* Process handle. */ + unsigned int ti_user_flags; /* Unused. */ + thread_t ti_tid; /* Thread ID returned by + pthread_create(). */ + char *ti_tls; /* Pointer to thread-local data. */ + psaddr_t ti_startfunc; /* Start function passed to + pthread_create(). */ + psaddr_t ti_stkbase; /* Base of thread's stack. */ + long int ti_stksize; /* Size of thread's stack. */ + psaddr_t ti_ro_area; /* Unused. */ + int ti_ro_size; /* Unused. */ + td_thr_state_e ti_state; /* Thread state. */ + unsigned char ti_db_suspended; /* Nonzero if suspended by debugger. */ + td_thr_type_e ti_type; /* Type of the thread (system vs + user thread). */ + intptr_t ti_pc; /* Unused. */ + intptr_t ti_sp; /* Unused. */ + short int ti_flags; /* Unused. */ + int ti_pri; /* Thread priority. */ + lwpid_t ti_lid; /* Unused. */ + sigset_t ti_sigmask; /* Signal mask. */ + unsigned char ti_traceme; /* Nonzero if event reporting + enabled. */ + unsigned char ti_preemptflag; /* Unused. */ + unsigned char ti_pirecflag; /* Unused. */ + sigset_t ti_pending; /* Set of pending signals. */ + td_thr_events_t ti_events; /* Set of enabled events. */ +} td_thrinfo_t; + + + +/* Prototypes for exported library functions. */ + +/* Initialize the thread debug support library. */ +extern td_err_e td_init (void); + +/* Historical relict. Should not be used anymore. */ +extern td_err_e td_log (void); + +/* Return list of symbols the library can request. */ +extern const char **td_symbol_list (void); + +/* Generate new thread debug library handle for process PS. */ +extern td_err_e td_ta_new (struct ps_prochandle *__ps, td_thragent_t **__ta); + +/* Free resources allocated for TA. */ +extern td_err_e td_ta_delete (td_thragent_t *__ta); + +/* Get number of currently running threads in process associated with TA. */ +extern td_err_e td_ta_get_nthreads (const td_thragent_t *__ta, int *__np); + +/* Return process handle passed in `td_ta_new' for process associated with + TA. */ +extern td_err_e td_ta_get_ph (const td_thragent_t *__ta, + struct ps_prochandle **__ph); + +/* Map thread library handle PT to thread debug library handle for process + associated with TA and store result in *TH. */ +extern td_err_e td_ta_map_id2thr (const td_thragent_t *__ta, pthread_t __pt, + td_thrhandle_t *__th); + +/* Map process ID LWPID to thread debug library handle for process + associated with TA and store result in *TH. */ +extern td_err_e td_ta_map_lwp2thr (const td_thragent_t *__ta, lwpid_t __lwpid, + td_thrhandle_t *__th); + + +/* Call for each thread in a process associated with TA the callback function + CALLBACK. */ +extern td_err_e td_ta_thr_iter (const td_thragent_t *__ta, + td_thr_iter_f *__callback, void *__cbdata_p, + td_thr_state_e __state, int __ti_pri, + sigset_t *__ti_sigmask_p, + unsigned int __ti_user_flags); + +/* Call for each defined thread local data entry the callback function KI. */ +extern td_err_e td_ta_tsd_iter (const td_thragent_t *__ta, td_key_iter_f *__ki, + void *__p); + + +/* Get event address for EVENT. */ +extern td_err_e td_ta_event_addr (const td_thragent_t *__ta, + td_event_e __event, td_notify_t *__ptr); + +/* Enable EVENT in global mask. */ +extern td_err_e td_ta_set_event (const td_thragent_t *__ta, + td_thr_events_t *__event); + +/* Disable EVENT in global mask. */ +extern td_err_e td_ta_clear_event (const td_thragent_t *__ta, + td_thr_events_t *__event); + +/* Return information about last event. */ +extern td_err_e td_ta_event_getmsg (const td_thragent_t *__ta, + td_event_msg_t *msg); + + +/* Set suggested concurrency level for process associated with TA. */ +extern td_err_e td_ta_setconcurrency (const td_thragent_t *__ta, int __level); + + +/* Enable collecting statistics for process associated with TA. */ +extern td_err_e td_ta_enable_stats (const td_thragent_t *__ta, int __enable); + +/* Reset statistics. */ +extern td_err_e td_ta_reset_stats (const td_thragent_t *__ta); + +/* Retrieve statistics from process associated with TA. */ +extern td_err_e td_ta_get_stats (const td_thragent_t *__ta, + td_ta_stats_t *__statsp); + + +/* Validate that TH is a thread handle. */ +extern td_err_e td_thr_validate (const td_thrhandle_t *__th); + +/* Return information about thread TH. */ +extern td_err_e td_thr_get_info (const td_thrhandle_t *__th, + td_thrinfo_t *__infop); + +/* Retrieve floating-point register contents of process running thread TH. */ +extern td_err_e td_thr_getfpregs (const td_thrhandle_t *__th, + prfpregset_t *__regset); + +/* Retrieve general register contents of process running thread TH. */ +extern td_err_e td_thr_getgregs (const td_thrhandle_t *__th, + prgregset_t __gregs); + +/* Retrieve extended register contents of process running thread TH. */ +extern td_err_e td_thr_getxregs (const td_thrhandle_t *__th, void *__xregs); + +/* Get size of extended register set of process running thread TH. */ +extern td_err_e td_thr_getxregsize (const td_thrhandle_t *__th, int *__sizep); + +/* Set floating-point register contents of process running thread TH. */ +extern td_err_e td_thr_setfpregs (const td_thrhandle_t *__th, + const prfpregset_t *__fpregs); + +/* Set general register contents of process running thread TH. */ +extern td_err_e td_thr_setgregs (const td_thrhandle_t *__th, + prgregset_t __gregs); + +/* Set extended register contents of process running thread TH. */ +extern td_err_e td_thr_setxregs (const td_thrhandle_t *__th, + const void *__addr); + + +/* Enable reporting for EVENT for thread TH. */ +extern td_err_e td_thr_event_enable (const td_thrhandle_t *__th, int __event); + +/* Enable EVENT for thread TH. */ +extern td_err_e td_thr_set_event (const td_thrhandle_t *__th, + td_thr_events_t *__event); + +/* Disable EVENT for thread TH. */ +extern td_err_e td_thr_clear_event (const td_thrhandle_t *__th, + td_thr_events_t *__event); + +/* Get event message for thread TH. */ +extern td_err_e td_thr_event_getmsg (const td_thrhandle_t *__th, + td_event_msg_t *__msg); + + +/* Set priority of thread TH. */ +extern td_err_e td_thr_setprio (const td_thrhandle_t *__th, int __prio); + + +/* Set pending signals for thread TH. */ +extern td_err_e td_thr_setsigpending (const td_thrhandle_t *__th, + unsigned char __n, const sigset_t *__ss); + +/* Set signal mask for thread TH. */ +extern td_err_e td_thr_sigsetmask (const td_thrhandle_t *__th, + const sigset_t *__ss); + + +/* Return thread local data associated with key TK in thread TH. */ +extern td_err_e td_thr_tsd (const td_thrhandle_t *__th, + const thread_key_t __tk, void **__data); + + +/* Suspend execution of thread TH. */ +extern td_err_e td_thr_dbsuspend (const td_thrhandle_t *__th); + +/* Resume execution of thread TH. */ +extern td_err_e td_thr_dbresume (const td_thrhandle_t *__th); + +#endif /* thread_db.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/thread_dbP.h b/newlib/libc/sys/linux/linuxthreads/thread_dbP.h new file mode 100644 index 000000000..c695fa253 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/thread_dbP.h @@ -0,0 +1,105 @@ +/* Private header for thread debug library. */ +#ifndef _THREAD_DBP_H +#define _THREAD_DBP_H 1 + +#include <string.h> +#include "proc_service.h" +#include "thread_db.h" +#include "internals.h" + + +/* Indeces for the symbol names. */ +enum + { + PTHREAD_THREADS_EVENTS = 0, + PTHREAD_LAST_EVENT, + PTHREAD_HANDLES_NUM, + PTHREAD_HANDLES, + PTHREAD_KEYS, + LINUXTHREADS_PTHREAD_THREADS_MAX, + LINUXTHREADS_PTHREAD_KEYS_MAX, + LINUXTHREADS_PTHREAD_SIZEOF_DESCR, + LINUXTHREADS_CREATE_EVENT, + LINUXTHREADS_DEATH_EVENT, + LINUXTHREADS_REAP_EVENT, + NUM_MESSAGES + }; + + +/* Comment out the following for less verbose output. */ +#ifndef NDEBUG +# define LOG(c) if (__td_debug) __libc_write (2, c "\n", strlen (c "\n")) +extern int __td_debug; +#else +# define LOG(c) +#endif + + +/* Handle for a process. This type is opaque. */ +struct td_thragent +{ + /* Delivered by the debugger and we have to pass it back in the + proc callbacks. */ + struct ps_prochandle *ph; + + /* Some cached information. */ + + /* Address of the `__pthread_handles' array. */ + struct pthread_handle_struct *handles; + + /* Address of the `pthread_kyes' array. */ + struct pthread_key_struct *keys; + + /* Maximum number of threads. */ + int pthread_threads_max; + + /* Maximum number of thread-local data keys. */ + int pthread_keys_max; + + /* Size of 2nd level array for thread-local data keys. */ + int pthread_key_2ndlevel_size; + + /* Sizeof struct _pthread_descr_struct. */ + int sizeof_descr; + + /* Pointer to the `__pthread_threads_events' variable in the target. */ + psaddr_t pthread_threads_eventsp; + + /* Pointer to the `__pthread_last_event' variable in the target. */ + psaddr_t pthread_last_event; + + /* Pointer to the `__pthread_handles_num' variable. */ + psaddr_t pthread_handles_num; +}; + + +/* Type used internally to keep track of thread agent descriptors. */ +struct agent_list +{ + td_thragent_t *ta; + struct agent_list *next; +}; + +/* List of all known descriptors. */ +extern struct agent_list *__td_agent_list; + +/* Function used to test for correct thread agent pointer. */ +static inline int +ta_ok (const td_thragent_t *ta) +{ + struct agent_list *runp = __td_agent_list; + + if (ta == NULL) + return 0; + + while (runp != NULL && runp->ta != ta) + runp = runp->next; + + return runp != NULL; +} + + +/* Internal wrapper around ps_pglobal_lookup. */ +extern int td_lookup (struct ps_prochandle *ps, int idx, psaddr_t *sym_addr); + +#endif /* thread_dbP.h */ diff --git a/newlib/libc/sys/linux/linuxthreads/timer_create.c b/newlib/libc/sys/linux/linuxthreads/timer_create.c new file mode 100644 index 000000000..1dccd3036 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/timer_create.c @@ -0,0 +1,179 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kaz Kylheku <kaz@ashi.footprints.net>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <signal.h> +#include <pthread.h> +#include <time.h> +#include <unistd.h> + +#include "posix-timer.h" + + +/* Create new per-process timer using CLOCK. */ +int +timer_create (clock_id, evp, timerid) + clockid_t clock_id; + struct sigevent *evp; + timer_t *timerid; +{ + int retval = -1; + struct timer_node *newtimer = NULL; + struct thread_node *thread = NULL; + + if (clock_id != CLOCK_REALTIME +#ifdef _POSIX_CPUTIME + && clock_id != CLOCK_PROCESS_CPUTIME_ID +#endif +#ifdef _POSIX_THREAD_CPUTIME + && clock_id != CLOCK_THREAD_CPUTIME_ID +#endif + ) + { + __set_errno (EINVAL); + return -1; + } + + pthread_once (&__timer_init_once_control, __timer_init_once); + + if (__timer_init_failed) + { + __set_errno (ENOMEM); + return -1; + } + + pthread_mutex_lock (&__timer_mutex); + + newtimer = __timer_alloc (); + if (__builtin_expect (newtimer == NULL, 0)) + { + __set_errno (EAGAIN); + goto unlock_bail; + } + + if (evp != NULL) + newtimer->event = *evp; + else + { + newtimer->event.sigev_notify = SIGEV_SIGNAL; + newtimer->event.sigev_signo = SIGALRM; + newtimer->event.sigev_value.sival_int = timer_ptr2id (newtimer); + newtimer->event.sigev_notify_function = 0; + } + + newtimer->event.sigev_notify_attributes = &newtimer->attr; + newtimer->creator_pid = getpid (); + + switch (__builtin_expect (newtimer->event.sigev_notify, SIGEV_SIGNAL)) + { + case SIGEV_NONE: + /* This is a strange choice! */ + break; + + case SIGEV_SIGNAL: + /* We have a global thread for delivering timed signals. + If it is not running, try to start it up. */ + switch (clock_id) + { + case CLOCK_REALTIME: + default: + thread = &__timer_signal_thread_rclk; + break; +#ifdef _POSIX_CPUTIME + case CLOCK_PROCESS_CPUTIME_ID: + thread = &__timer_signal_thread_pclk; + break; +#endif +#ifdef _POSIX_THREAD_CPUTIME + case CLOCK_THREAD_CPUTIME_ID: + thread = &__timer_signal_thread_tclk; + break; +#endif + } + + if (! thread->exists) + { + if (__builtin_expect (__timer_thread_start (thread), + 1) < 0) + { + __set_errno (EAGAIN); + goto unlock_bail; + } + } + break; + + case SIGEV_THREAD: + /* Copy over thread attributes or set up default ones. */ + if (evp->sigev_notify_attributes) + newtimer->attr = *(pthread_attr_t *) evp->sigev_notify_attributes; + else + pthread_attr_init (&newtimer->attr); + + /* Ensure thread attributes call for deatched thread. */ + pthread_attr_setdetachstate (&newtimer->attr, PTHREAD_CREATE_DETACHED); + + /* Try to find existing thread having the right attributes. */ + thread = __timer_thread_find_matching (&newtimer->attr, clock_id); + + /* If no existing thread has these attributes, try to allocate one. */ + if (thread == NULL) + thread = __timer_thread_alloc (&newtimer->attr, clock_id); + + /* Out of luck; no threads are available. */ + if (__builtin_expect (thread == NULL, 0)) + { + __set_errno (EAGAIN); + goto unlock_bail; + } + + /* If the thread is not running already, try to start it. */ + if (! thread->exists + && __builtin_expect (! __timer_thread_start (thread), 0)) + { + __set_errno (EAGAIN); + goto unlock_bail; + } + break; + + default: + __set_errno (EINVAL); + goto unlock_bail; + } + + newtimer->clock = clock_id; + newtimer->abstime = 0; + newtimer->armed = 0; + newtimer->thread = thread; + + *timerid = timer_ptr2id (newtimer); + retval = 0; + + if (__builtin_expect (retval, 0) == -1) + { + unlock_bail: + if (thread != NULL) + __timer_thread_dealloc (thread); + if (newtimer != NULL) + __timer_dealloc (newtimer); + } + + pthread_mutex_unlock (&__timer_mutex); + + return retval; +} diff --git a/newlib/libc/sys/linux/linuxthreads/timer_delete.c b/newlib/libc/sys/linux/linuxthreads/timer_delete.c new file mode 100644 index 000000000..24f4ffed3 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/timer_delete.c @@ -0,0 +1,70 @@ +/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kaz Kylheku <kaz@ashi.footprints.net>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <assert.h> +#include <errno.h> +#include <pthread.h> +#include <time.h> + +#include "posix-timer.h" + + +/* Delete timer TIMERID. */ +int +timer_delete (timerid) + timer_t timerid; +{ + struct timer_node *timer; + int retval = -1; + + pthread_mutex_lock (&__timer_mutex); + + timer = timer_id2ptr (timerid); + if (! timer_valid (timer)) + /* Invalid timer ID or the timer is not in use. */ + __set_errno (EINVAL); + else + { + if (timer->armed && timer->thread != NULL) + { + struct thread_node *thread = timer->thread; + assert (thread != NULL); + + /* If thread is cancelled while waiting for handler to terminate, + the mutex is unlocked and timer_delete is aborted. */ + pthread_cleanup_push (__timer_mutex_cancel_handler, &__timer_mutex); + + /* If timer is currently being serviced, wait for it to finish. */ + while (thread->current_timer == timer) + pthread_cond_wait (&thread->cond, &__timer_mutex); + + pthread_cleanup_pop (0); + } + + /* Remove timer from whatever queue it may be on and deallocate it. */ + timer->inuse = TIMER_DELETED; + list_unlink_ip (&timer->links); + timer_delref (timer); + retval = 0; + } + + pthread_mutex_unlock (&__timer_mutex); + + return retval; +} diff --git a/newlib/libc/sys/linux/linuxthreads/timer_getoverr.c b/newlib/libc/sys/linux/linuxthreads/timer_getoverr.c new file mode 100644 index 000000000..204addc85 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/timer_getoverr.c @@ -0,0 +1,45 @@ +/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kaz Kylheku <kaz@ashi.footprints.net>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <pthread.h> +#include <time.h> + +#include "posix-timer.h" + + +/* Get expiration overrun for timer TIMERID. */ +int +timer_getoverrun (timerid) + timer_t timerid; +{ + struct timer_node *timer; + int retval = -1; + + pthread_mutex_lock (&__timer_mutex); + + if (! timer_valid (timer = timer_id2ptr (timerid))) + __set_errno (EINVAL); + else + retval = 0; /* TODO: overrun counting not supported */ + + pthread_mutex_unlock (&__timer_mutex); + + return retval; +} diff --git a/newlib/libc/sys/linux/linuxthreads/timer_gettime.c b/newlib/libc/sys/linux/linuxthreads/timer_gettime.c new file mode 100644 index 000000000..dbee9d915 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/timer_gettime.c @@ -0,0 +1,71 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kaz Kylheku <kaz@ashi.footprints.net>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <pthread.h> +#include <time.h> + +#include "posix-timer.h" + + +/* Get current value of timer TIMERID and store it in VLAUE. */ +int +timer_gettime (timerid, value) + timer_t timerid; + struct itimerspec *value; +{ + struct timer_node *timer; + struct timespec now, expiry; + int retval = -1, armed = 0, valid; + clock_t clock = 0; + + pthread_mutex_lock (&__timer_mutex); + + timer = timer_id2ptr (timerid); + valid = timer_valid (timer); + + if (valid) { + armed = timer->armed; + expiry = timer->expirytime; + clock = timer->clock; + value->it_interval = timer->value.it_interval; + } + + pthread_mutex_unlock (&__timer_mutex); + + if (valid) + { + if (armed) + { + clock_gettime (clock, &now); + timespec_sub (&value->it_value, &expiry, &now); + } + else + { + value->it_value.tv_sec = 0; + value->it_value.tv_nsec = 0; + } + + retval = 0; + } + else + __set_errno (EINVAL); + + return retval; +} diff --git a/newlib/libc/sys/linux/linuxthreads/timer_routines.c b/newlib/libc/sys/linux/linuxthreads/timer_routines.c new file mode 100644 index 000000000..65dc5dca5 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/timer_routines.c @@ -0,0 +1,584 @@ +/* Helper code for POSIX timer implementation on LinuxThreads. + Copyright (C) 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kaz Kylheku <kaz@ashi.footprints.net>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <assert.h> +#include <errno.h> +#include <pthread.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <sysdep.h> +#include <time.h> +#include <unistd.h> +#include <sys/syscall.h> + +#include "posix-timer.h" + + +/* Number of threads used. */ +#define THREAD_MAXNODES 16 + +/* Array containing the descriptors for the used threads. */ +static struct thread_node thread_array[THREAD_MAXNODES]; + +/* Static array with the structures for all the timers. */ +struct timer_node __timer_array[TIMER_MAX]; + +/* Global lock to protect operation on the lists. */ +pthread_mutex_t __timer_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Variable to protext initialization. */ +pthread_once_t __timer_init_once_control = PTHREAD_ONCE_INIT; + +/* Nonzero if initialization of timer implementation failed. */ +int __timer_init_failed; + +/* Node for the thread used to deliver signals. */ +struct thread_node __timer_signal_thread_rclk; +#ifdef _POSIX_CPUTIME +struct thread_node __timer_signal_thread_pclk; +#endif +#ifdef _POSIX_THREAD_CPUTIME +struct thread_node __timer_signal_thread_tclk; +#endif + +/* Lists to keep free and used timers and threads. */ +struct list_links timer_free_list; +struct list_links thread_free_list; +struct list_links thread_active_list; + + +#ifdef __NR_rt_sigqueueinfo +extern int __syscall_rt_sigqueueinfo (int, int, siginfo_t *); +#endif + + +/* List handling functions. */ +static inline void +list_init (struct list_links *list) +{ + list->next = list->prev = list; +} + +static inline void +list_append (struct list_links *list, struct list_links *newp) +{ + newp->prev = list->prev; + newp->next = list; + list->prev->next = newp; + list->prev = newp; +} + +static inline void +list_insbefore (struct list_links *list, struct list_links *newp) +{ + list_append (list, newp); +} + +/* + * Like list_unlink_ip, except that calling it on a node that + * is already unlinked is disastrous rather than a noop. + */ + +static inline void +list_unlink (struct list_links *list) +{ + struct list_links *lnext = list->next, *lprev = list->prev; + + lnext->prev = lprev; + lprev->next = lnext; +} + +static inline struct list_links * +list_first (struct list_links *list) +{ + return list->next; +} + +static inline struct list_links * +list_null (struct list_links *list) +{ + return list; +} + +static inline struct list_links * +list_next (struct list_links *list) +{ + return list->next; +} + +static inline int +list_isempty (struct list_links *list) +{ + return list->next == list; +} + + +/* Functions build on top of the list functions. */ +static inline struct thread_node * +thread_links2ptr (struct list_links *list) +{ + return (struct thread_node *) ((char *) list + - offsetof (struct thread_node, links)); +} + +static inline struct timer_node * +timer_links2ptr (struct list_links *list) +{ + return (struct timer_node *) ((char *) list + - offsetof (struct timer_node, links)); +} + + +/* Initialize a newly allocated thread structure. */ +static void +thread_init (struct thread_node *thread, const pthread_attr_t *attr, clockid_t clock_id) +{ + if (attr != NULL) + thread->attr = *attr; + else + { + pthread_attr_init (&thread->attr); + pthread_attr_setdetachstate (&thread->attr, PTHREAD_CREATE_DETACHED); + } + + thread->exists = 0; + list_init (&thread->timer_queue); + pthread_cond_init (&thread->cond, 0); + thread->current_timer = 0; + thread->captured = pthread_self (); + thread->clock_id = clock_id; +} + + +/* Initialize the global lists, and acquire global resources. Error + reporting is done by storing a non-zero value to the global variable + timer_init_failed. */ +static void +init_module (void) +{ + int i; + + list_init (&timer_free_list); + list_init (&thread_free_list); + list_init (&thread_active_list); + + for (i = 0; i < TIMER_MAX; ++i) + { + list_append (&timer_free_list, &__timer_array[i].links); + __timer_array[i].inuse = TIMER_FREE; + } + + for (i = 0; i < THREAD_MAXNODES; ++i) + list_append (&thread_free_list, &thread_array[i].links); + + thread_init (&__timer_signal_thread_rclk, 0, CLOCK_REALTIME); +#ifdef _POSIX_CPUTIME + thread_init (&__timer_signal_thread_pclk, 0, CLOCK_PROCESS_CPUTIME_ID); +#endif +#ifdef _POSIX_THREAD_CPUTIME + thread_init (&__timer_signal_thread_tclk, 0, CLOCK_THREAD_CPUTIME_ID); +#endif +} + + +/* This is a handler executed in a child process after a fork() + occurs. It reinitializes the module, resetting all of the data + structures to their initial state. The mutex is initialized in + case it was locked in the parent process. */ +static void +reinit_after_fork (void) +{ + init_module (); + pthread_mutex_init (&__timer_mutex, 0); +} + + +/* Called once form pthread_once in timer_init. This initializes the + module and ensures that reinit_after_fork will be executed in any + child process. */ +void +__timer_init_once (void) +{ + init_module (); +#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 3 + pthread_atfork (0, 0, reinit_after_fork); +#endif +} + + +/* Deinitialize a thread that is about to be deallocated. */ +static void +thread_deinit (struct thread_node *thread) +{ + assert (list_isempty (&thread->timer_queue)); + pthread_cond_destroy (&thread->cond); +} + + +/* Allocate a thread structure from the global free list. Global + mutex lock must be held by caller. The thread is moved to + the active list. */ +struct thread_node * +__timer_thread_alloc (const pthread_attr_t *desired_attr, clockid_t clock_id) +{ + struct list_links *node = list_first (&thread_free_list); + + if (node != list_null (&thread_free_list)) + { + struct thread_node *thread = thread_links2ptr (node); + list_unlink (node); + thread_init (thread, desired_attr, clock_id); + list_append (&thread_active_list, node); + return thread; + } + + return 0; +} + + +/* Return a thread structure to the global free list. Global lock + must be held by caller. */ +void +__timer_thread_dealloc (struct thread_node *thread) +{ + thread_deinit (thread); + list_unlink (&thread->links); + list_append (&thread_free_list, &thread->links); +} + + +/* Each of our threads which terminates executes this cleanup + handler. We never terminate threads ourselves; if a thread gets here + it means that the evil application has killed it. If the thread has + timers, these require servicing and so we must hire a replacement + thread right away. We must also unblock another thread that may + have been waiting for this thread to finish servicing a timer (see + timer_delete()). */ + +static void +thread_cleanup (void *val) +{ + if (val != NULL) + { + struct thread_node *thread = val; + + /* How did the signal thread get killed? */ + assert (thread != &__timer_signal_thread_rclk); +#ifdef _POSIX_CPUTIME + assert (thread != &__timer_signal_thread_pclk); +#endif +#ifdef _POSIX_THREAD_CPUTIME + assert (thread != &__timer_signal_thread_tclk); +#endif + + pthread_mutex_lock (&__timer_mutex); + + thread->exists = 0; + + /* We are no longer processing a timer event. */ + thread->current_timer = 0; + + if (list_isempty (&thread->timer_queue)) + __timer_thread_dealloc (thread); + else + (void) __timer_thread_start (thread); + + pthread_mutex_unlock (&__timer_mutex); + + /* Unblock potentially blocked timer_delete(). */ + pthread_cond_broadcast (&thread->cond); + } +} + + +/* Handle a timer which is supposed to go off now. */ +static void +thread_expire_timer (struct thread_node *self, struct timer_node *timer) +{ + self->current_timer = timer; /* Lets timer_delete know timer is running. */ + + pthread_mutex_unlock (&__timer_mutex); + + switch (__builtin_expect (timer->event.sigev_notify, SIGEV_SIGNAL)) + { + case SIGEV_NONE: + assert (! "timer_create should never have created such a timer"); + break; + + case SIGEV_SIGNAL: +#ifdef __NR_rt_sigqueueinfo + { + siginfo_t info; + + /* First, clear the siginfo_t structure, so that we don't pass our + stack content to other tasks. */ + memset (&info, 0, sizeof (siginfo_t)); + /* We must pass the information about the data in a siginfo_t + value. */ + info.si_signo = timer->event.sigev_signo; + info.si_code = SI_TIMER; + info.si_pid = timer->creator_pid; + info.si_uid = getuid (); + info.si_value = timer->event.sigev_value; + + INLINE_SYSCALL (rt_sigqueueinfo, 3, info.si_pid, info.si_signo, &info); + } +#else + if (pthread_kill (self->captured, timer->event.sigev_signo) != 0) + { + if (pthread_kill (self->id, timer->event.sigev_signo) != 0) + abort (); + } +#endif + break; + + case SIGEV_THREAD: + timer->event.sigev_notify_function (timer->event.sigev_value); + break; + + default: + assert (! "unknown event"); + break; + } + + pthread_mutex_lock (&__timer_mutex); + + self->current_timer = 0; + + pthread_cond_broadcast (&self->cond); +} + + +/* Thread function; executed by each timer thread. The job of this + function is to wait on the thread's timer queue and expire the + timers in chronological order as close to their scheduled time as + possible. */ +static void * +__attribute__ ((noreturn)) +thread_func (void *arg) +{ + struct thread_node *self = arg; + + /* Register cleanup handler, in case rogue application terminates + this thread. (This cannot happen to __timer_signal_thread, which + doesn't invoke application callbacks). */ + + pthread_cleanup_push (thread_cleanup, self); + + pthread_mutex_lock (&__timer_mutex); + + while (1) + { + struct list_links *first; + struct timer_node *timer = NULL; + + /* While the timer queue is not empty, inspect the first node. */ + first = list_first (&self->timer_queue); + if (first != list_null (&self->timer_queue)) + { + struct timespec now; + + timer = timer_links2ptr (first); + + /* This assumes that the elements of the list of one thread + are all for the same clock. */ + clock_gettime (timer->clock, &now); + + while (1) + { + /* If the timer is due or overdue, remove it from the queue. + If it's a periodic timer, re-compute its new time and + requeue it. Either way, perform the timer expiry. */ + if (timespec_compare (&now, &timer->expirytime) < 0) + break; + + list_unlink_ip (first); + + if (__builtin_expect (timer->value.it_interval.tv_sec, 0) != 0 + || timer->value.it_interval.tv_nsec != 0) + { + timespec_add (&timer->expirytime, &now, + &timer->value.it_interval); + __timer_thread_queue_timer (self, timer); + } + + thread_expire_timer (self, timer); + + first = list_first (&self->timer_queue); + if (first == list_null (&self->timer_queue)) + break; + + timer = timer_links2ptr (first); + } + } + + /* If the queue is not empty, wait until the expiry time of the + first node. Otherwise wait indefinitely. Insertions at the + head of the queue must wake up the thread by broadcasting + this condition variable. */ + if (timer != NULL) + pthread_cond_timedwait (&self->cond, &__timer_mutex, + &timer->expirytime); + else + pthread_cond_wait (&self->cond, &__timer_mutex); + } + /* This macro will never be executed since the while loop loops + forever - but we have to add it for proper nesting. */ + pthread_cleanup_pop (1); + +} + + +/* Enqueue a timer in wakeup order in the thread's timer queue. + Returns 1 if the timer was inserted at the head of the queue, + causing the queue's next wakeup time to change. */ + +int +__timer_thread_queue_timer (struct thread_node *thread, + struct timer_node *insert) +{ + struct list_links *iter; + int athead = 1; + + for (iter = list_first (&thread->timer_queue); + iter != list_null (&thread->timer_queue); + iter = list_next (iter)) + { + struct timer_node *timer = timer_links2ptr (iter); + + if (timespec_compare (&insert->expirytime, &timer->expirytime) < 0) + break; + athead = 0; + } + + list_insbefore (iter, &insert->links); + return athead; +} + + +/* Start a thread and associate it with the given thread node. Global + lock must be held by caller. */ +int +__timer_thread_start (struct thread_node *thread) +{ + int retval = 1; + + assert (!thread->exists); + thread->exists = 1; + + if (pthread_create (&thread->id, &thread->attr, thread_func, thread) != 0) + { + thread->exists = 0; + retval = -1; + } + + return retval; +} + + +void +__timer_thread_wakeup (struct thread_node *thread) +{ + pthread_cond_broadcast (&thread->cond); +} + + +/* Compare two pthread_attr_t thread attributes for exact equality. + Returns 1 if they are equal, otherwise zero if they are not equal or + contain illegal values. This version is LinuxThreads-specific for + performance reason. One could use the access functions to get the + values of all the fields of the attribute structure. */ +static int +thread_attr_compare (const pthread_attr_t *left, const pthread_attr_t *right) +{ + return (left->__detachstate == right->__detachstate + && left->__schedpolicy == right->__schedpolicy + && (left->__schedparam.sched_priority + == right->__schedparam.sched_priority) + && left->__inheritsched == right->__inheritsched + && left->__scope == right->__scope); +} + + +/* Search the list of active threads and find one which has matching + attributes. Global mutex lock must be held by caller. */ +struct thread_node * +__timer_thread_find_matching (const pthread_attr_t *desired_attr, + clockid_t desired_clock_id) +{ + struct list_links *iter = list_first (&thread_active_list); + + while (iter != list_null (&thread_active_list)) + { + struct thread_node *candidate = thread_links2ptr (iter); + + if (thread_attr_compare (desired_attr, &candidate->attr) + && desired_clock_id == candidate->clock_id) + { + list_unlink (iter); + return candidate; + } + + iter = list_next (iter); + } + + return NULL; +} + + +/* Grab a free timer structure from the global free list. The global + lock must be held by the caller. */ +struct timer_node * +__timer_alloc (void) +{ + struct list_links *node = list_first (&timer_free_list); + + if (node != list_null (&timer_free_list)) + { + struct timer_node *timer = timer_links2ptr (node); + list_unlink_ip (node); + timer->inuse = TIMER_INUSE; + timer->refcount = 1; + return timer; + } + + return NULL; +} + + +/* Return a timer structure to the global free list. The global lock + must be held by the caller. */ +void +__timer_dealloc (struct timer_node *timer) +{ + assert (timer->refcount == 0); + timer->thread = NULL; /* Break association between timer and thread. */ + timer->inuse = TIMER_FREE; + list_append (&timer_free_list, &timer->links); +} + + +/* Thread cancellation handler which unlocks a mutex. */ +void +__timer_mutex_cancel_handler (void *arg) +{ + pthread_mutex_unlock (arg); +} diff --git a/newlib/libc/sys/linux/linuxthreads/timer_settime.c b/newlib/libc/sys/linux/linuxthreads/timer_settime.c new file mode 100644 index 000000000..2f187fd18 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/timer_settime.c @@ -0,0 +1,137 @@ +/* Copyright (C) 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Kaz Kylheku <kaz@ashi.footprints.net>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <pthread.h> +#include <time.h> + +#include "posix-timer.h" + + +/* Set timer TIMERID to VALUE, returning old value in OVLAUE. */ +int +timer_settime (timerid, flags, value, ovalue) + timer_t timerid; + int flags; + const struct itimerspec *value; + struct itimerspec *ovalue; +{ + struct timer_node *timer; + struct thread_node *thread = NULL; + struct timespec now; + int have_now = 0, need_wakeup = 0; + int retval = -1; + + timer = timer_id2ptr (timerid); + if (timer == NULL) + { + __set_errno (EINVAL); + goto bail; + } + + if (value->it_interval.tv_nsec < 0 + || value->it_interval.tv_nsec >= 1000000000 + || value->it_value.tv_nsec < 0 + || value->it_value.tv_nsec >= 1000000000) + { + __set_errno (EINVAL); + goto bail; + } + + /* Will need to know current time since this is a relative timer; + might as well make the system call outside of the lock now! */ + + if ((flags & TIMER_ABSTIME) == 0) + { + clock_gettime (timer->clock, &now); + have_now = 1; + } + + pthread_mutex_lock (&__timer_mutex); + timer_addref (timer); + + /* One final check of timer validity; this one is possible only + until we have the mutex, because it accesses the inuse flag. */ + + if (! timer_valid(timer)) + { + __set_errno (EINVAL); + goto unlock_bail; + } + + if (ovalue != NULL) + { + ovalue->it_interval = timer->value.it_interval; + + if (timer->armed) + { + if (! have_now) + { + pthread_mutex_unlock (&__timer_mutex); + clock_gettime (timer->clock, &now); + have_now = 1; + pthread_mutex_lock (&__timer_mutex); + timer_addref (timer); + } + + timespec_sub (&ovalue->it_value, &timer->expirytime, &now); + } + else + { + ovalue->it_value.tv_sec = 0; + ovalue->it_value.tv_nsec = 0; + } + } + + timer->value = *value; + + list_unlink_ip (&timer->links); + timer->armed = 0; + + thread = timer->thread; + + /* A value of { 0, 0 } causes the timer to be stopped. */ + if (value->it_value.tv_sec != 0 + || __builtin_expect (value->it_value.tv_nsec != 0, 1)) + { + if ((flags & TIMER_ABSTIME) != 0) + /* The user specified the expiration time. */ + timer->expirytime = value->it_value; + else + timespec_add (&timer->expirytime, &now, &value->it_value); + + /* Only need to wake up the thread if timer is inserted + at the head of the queue. */ + if (thread != NULL) + need_wakeup = __timer_thread_queue_timer (thread, timer); + timer->armed = 1; + } + + retval = 0; + +unlock_bail: + timer_delref (timer); + pthread_mutex_unlock (&__timer_mutex); + +bail: + if (thread != NULL && need_wakeup) + __timer_thread_wakeup (thread); + + return retval; +} diff --git a/newlib/libc/sys/linux/linuxthreads/tst-cancel.c b/newlib/libc/sys/linux/linuxthreads/tst-cancel.c new file mode 100644 index 000000000..da32aaf5e --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/tst-cancel.c @@ -0,0 +1,213 @@ +/* Tests for cancelation handling. */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> + +int fd; + +pthread_barrier_t bar; + + +static void +cleanup (void *arg) +{ + int nr = (int) (long int) arg; + char s[30]; + char *cp = stpcpy (s, "cleanup "); + *cp++ = '0' + nr; + *cp++ = '\n'; + __libc_lseek (fd, 0, SEEK_END); + __libc_write (fd, s, cp - s); +} + + +static void * +t1 (void *arg) +{ + pthread_cleanup_push (cleanup, (void *) (long int) 1); + return NULL; + pthread_cleanup_pop (0); +} + + +static void +inner (int a) +{ + pthread_cleanup_push (cleanup, (void *) (long int) a); + if (a) + return; + pthread_cleanup_pop (0); +} + + +static void * +t2 (void *arg) +{ + pthread_cleanup_push (cleanup, (void *) (long int) 2); + inner ((int) (long int) arg); + return NULL; + pthread_cleanup_pop (0); +} + + +/* This does not work yet. */ +volatile int cleanupokcnt; + +static void +cleanupok (void *arg) +{ + ++cleanupokcnt; +} + + +static void * +t3 (void *arg) +{ + pthread_cleanup_push (cleanupok, (void *) (long int) 4); + inner ((int) (long int) arg); + pthread_exit (NULL); + pthread_cleanup_pop (0); +} + + +static void +innerok (int a) +{ + pthread_cleanup_push (cleanupok, (void *) (long int) a); + pthread_exit (NULL); + pthread_cleanup_pop (0); +} + + +static void * +t4 (void *arg) +{ + pthread_cleanup_push (cleanupok, (void *) (long int) 6); + innerok ((int) (long int) arg); + pthread_cleanup_pop (0); + return NULL; +} + + +int +main (int argc, char *argv[]) +{ + pthread_t td; + int err; + char *tmp; + const char *prefix; + const char template[] = "thtstXXXXXX"; + struct stat64 st; + int result = 0; + + prefix = argc > 1 ? argv[1] : ""; + tmp = (char *) alloca (strlen (prefix) + sizeof template); + strcpy (stpcpy (tmp, prefix), template); + + fd = mkstemp (tmp); + if (fd == -1) + { + printf ("cannot create temporary file: %m"); + exit (1); + } + unlink (tmp); + + err = pthread_barrier_init (&bar, NULL, 2); + if (err != 0 ) + { + printf ("cannot create barrier: %s\n", strerror (err)); + exit (1); + } + +#ifdef NOT_YET + err = pthread_create (&td, NULL, t1, NULL); + if (err != 0) + { + printf ("cannot create thread t1: %s\n", strerror (err)); + exit (1); + } + + err = pthread_join (td, NULL); + if (err != 0) + { + printf ("cannot join thread: %s\n", strerror (err)); + exit (1); + } + + err = pthread_create (&td, NULL, t2, (void *) 3); + if (err != 0) + { + printf ("cannot create thread t2: %s\n", strerror (err)); + exit (1); + } + + err = pthread_join (td, NULL); + if (err != 0) + { + printf ("cannot join thread: %s\n", strerror (err)); + exit (1); + } + + err = pthread_create (&td, NULL, t3, (void *) 5); + if (err != 0) + { + printf ("cannot create thread t3: %s\n", strerror (err)); + exit (1); + } + + err = pthread_join (td, NULL); + if (err != 0) + { + printf ("cannot join thread: %s\n", strerror (err)); + exit (1); + } +#endif + + err = pthread_create (&td, NULL, t4, (void *) 7); + if (err != 0) + { + printf ("cannot create thread t3: %s\n", strerror (err)); + exit (1); + } + + err = pthread_join (td, NULL); + if (err != 0) + { + printf ("cannot join thread: %s\n", strerror (err)); + exit (1); + } + + if (fstat64 (fd, &st) < 0) + { + printf ("cannot stat temporary file: %m\n"); + result = 1; + } + else if (st.st_size != 0) + { + char buf[512]; + puts ("some cleanup handlers ran:"); + fflush (stdout); + __lseek (fd, 0, SEEK_SET); + while (1) + { + ssize_t n = read (fd, buf, sizeof buf); + if (n <= 0) + break; + write (STDOUT_FILENO, buf, n); + } + result = 1; + } + + // if (cleanupokcnt != 3) will be three once t3 runs + if (cleanupokcnt != 2) + { + printf ("cleanupokcnt = %d\n", cleanupokcnt); + result = 1; + } + + return result; +} diff --git a/newlib/libc/sys/linux/linuxthreads/tst-context.c b/newlib/libc/sys/linux/linuxthreads/tst-context.c new file mode 100644 index 000000000..9066e837e --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/tst-context.c @@ -0,0 +1,109 @@ +#include <errno.h> +#include <error.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <ucontext.h> + +#include "pt-machine.h" + + +#define N 4 + +#ifdef FLOATING_STACKS +static char stacks[N][8192]; +static ucontext_t ctx[N][2]; +static volatile int failures; + +static void +fct (long int n) +{ + /* Just to use the thread local descriptor. */ + printf ("%ld: in %s now\n", n, __FUNCTION__); + errno = 0; +} + +static void * +threadfct (void *arg) +{ + int n = (int) (long int) arg; + + if (getcontext (&ctx[n][1]) != 0) + { + printf ("%d: cannot get context: %m\n", n); + exit (1); + } + + printf ("%d: %s: before makecontext\n", n, __FUNCTION__); + + ctx[n][1].uc_stack.ss_sp = stacks[n]; + ctx[n][1].uc_stack.ss_size = 8192; + ctx[n][1].uc_link = &ctx[n][0]; + makecontext (&ctx[n][1], (void (*) (void)) fct, 1, (long int) n); + + printf ("%d: %s: before swapcontext\n", n, __FUNCTION__); + + if (swapcontext (&ctx[n][0], &ctx[n][1]) != 0) + { + ++failures; + printf ("%d: %s: swapcontext failed\n", n, __FUNCTION__); + } + else + printf ("%d: back in %s\n", n, __FUNCTION__); + + return NULL; +} +#endif + + +#ifdef FLOATING_STACKS +static volatile int global; +#endif + +int +main (void) +{ +#ifndef FLOATING_STACKS + puts ("not supported"); + return 0; +#else + int n; + pthread_t th[N]; + ucontext_t mctx; + + puts ("making contexts"); + if (getcontext (&mctx) != 0) + { + if (errno == ENOSYS) + { + puts ("context handling not supported"); + exit (0); + } + + printf ("%s: getcontext: %m\n", __FUNCTION__); + exit (1); + } + + /* Play some tricks with this context. */ + if (++global == 1) + if (setcontext (&mctx) != 0) + { + printf ("%s: setcontext: %m\n", __FUNCTION__); + exit (1); + } + if (global != 2) + { + printf ("%s: 'global' not incremented twice\n", __FUNCTION__); + exit (1); + } + + for (n = 0; n < N; ++n) + if (pthread_create (&th[n], NULL, threadfct, (void *) n) != 0) + error (EXIT_FAILURE, errno, "cannot create all threads"); + + for (n = 0; n < N; ++n) + pthread_join (th[n], NULL); + + return failures; +#endif +} diff --git a/newlib/libc/sys/linux/linuxthreads/tststack.c b/newlib/libc/sys/linux/linuxthreads/tststack.c new file mode 100644 index 000000000..6789ff861 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/tststack.c @@ -0,0 +1,72 @@ +/* Tests for variable stack size handling. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +static void *f1 (void *); +static void *f2 (void *); + +int +main (void) +{ + pthread_attr_t attr; + pthread_t th1 = 0; + pthread_t th2 = 0; + void *res1; + void *res2; + + pthread_attr_init (&attr); + if (pthread_attr_setstacksize (&attr, 70*1024) != 0) + { + puts ("invalid stack size"); + return 1; + } + + pthread_create (&th1, NULL, f1, NULL); + pthread_create (&th2, &attr, f2, NULL); + + pthread_join (th1, &res1); + pthread_join (th2, &res2); + + printf ("res1 = %p\n", res1); + printf ("res2 = %p\n", res2); + + return res1 != (void *) 1 || res2 != (void *) 2; +} + +static void * +f1 (void *parm) +{ + printf ("This is `%s'\n", __FUNCTION__); + fflush (stdout); + + return (void *) 1; +} + +static void * +f2 (void *parm) +{ + printf ("This is `%s'\n", __FUNCTION__); + fflush (stdout); + sleep (1); + + return (void *) 2; +} diff --git a/newlib/libc/sys/linux/linuxthreads/unload.c b/newlib/libc/sys/linux/linuxthreads/unload.c new file mode 100644 index 000000000..c528df234 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/unload.c @@ -0,0 +1,45 @@ +/* Tests for non-unloading of libpthread. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> +#include <gnu/lib-names.h> + +int +main (void) +{ + void *p = dlopen (PREFIX LIBPTHREAD_SO, RTLD_LAZY); + + if (p == NULL) + { + puts ("failed to load " LIBPTHREAD_SO); + exit (1); + } + + if (dlclose (p) != 0) + { + puts ("dlclose (" LIBPTHREAD_SO ") failed"); + exit (1); + } + + puts ("seems to work"); + + exit (0); +} diff --git a/newlib/libc/sys/linux/linuxthreads/weaks.c b/newlib/libc/sys/linux/linuxthreads/weaks.c new file mode 100644 index 000000000..6e2cf4bf1 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/weaks.c @@ -0,0 +1,121 @@ +/* The weak pthread functions for Linux. + Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <shlib-compat.h> +#include <bp-sym.h> +#include "libc-symbols.h" + +extern int __pthread_return_0 (void); +extern int __pthread_return_1 (void); +extern void __pthread_return_void (void); +extern void weak_function pthread_exit (void *__retval) + __attribute__ ((noreturn)); + +/* Those are pthread functions which return 0 if successful. */ +weak_alias (__pthread_return_0, BP_SYM (__libc_pthread_attr_init_2_1)) +versioned_symbol (libpthread, BP_SYM (__libc_pthread_attr_init_2_1), + BP_SYM (pthread_attr_init), GLIBC_2_1); +#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) +weak_alias (__pthread_return_0, BP_SYM (__libc_pthread_attr_init_2_0)) +compat_symbol (libpthread, BP_SYM (__libc_pthread_attr_init_2_0), + BP_SYM (pthread_attr_init), GLIBC_2_0); +#endif +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_destroy)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setdetachstate)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getdetachstate)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setschedparam)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getschedparam)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setschedpolicy)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getschedpolicy)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setinheritsched)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getinheritsched)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setscope)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getscope)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setstackaddr)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getstackaddr)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setstacksize)) +weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getstacksize)) +weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_init)) +weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_destroy)) +weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_lock)) +weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_trylock)) +weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_unlock)) +weak_alias (__pthread_return_0, BP_SYM (pthread_mutexattr_init)) +weak_alias (__pthread_return_0, BP_SYM (pthread_mutexattr_destroy)) +weak_alias (__pthread_return_0, BP_SYM (pthread_mutexattr_settype)) +weak_alias (__pthread_return_0, BP_SYM (pthread_mutexattr_gettype)) +weak_alias (__pthread_return_0, BP_SYM (pthread_condattr_init)) +weak_alias (__pthread_return_0, BP_SYM (pthread_condattr_destroy)) +weak_alias (__pthread_return_0, BP_SYM (pthread_setschedparam)) +weak_alias (__pthread_return_0, BP_SYM (pthread_getschedparam)) +weak_alias (__pthread_return_0, BP_SYM (pthread_getcancelstate)) +weak_alias (__pthread_return_0, BP_SYM (pthread_setcancelstate)) +weak_alias (__pthread_return_0, BP_SYM (pthread_setcanceltype)) +weak_alias (__pthread_return_0, pthread_setconcurrency) +weak_alias (__pthread_return_0, pthread_getconcurrency) +weak_alias (__pthread_return_0, pthread_self) +weak_alias (__pthread_return_0, BP_SYM (pthread_cond_init)) +weak_alias (__pthread_return_0, BP_SYM (pthread_cond_destroy)) +weak_alias (__pthread_return_0, BP_SYM (pthread_cond_wait)) +weak_alias (__pthread_return_0, BP_SYM (pthread_cond_timedwait)) +weak_alias (__pthread_return_0, BP_SYM (pthread_cond_signal)) +weak_alias (__pthread_return_0, BP_SYM (pthread_cond_broadcast)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlock_init)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlock_destroy)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlock_rdlock)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlock_wrlock)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlock_tryrdlock)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlock_trywrlock)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlock_unlock)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlockattr_init)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlockattr_destroy)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlockattr_setpshared)) +weak_alias (__pthread_return_0, BP_SYM (pthread_rwlockattr_getpshared)) + + +/* Those are pthread functions which return 1 if successful. */ +weak_alias (__pthread_return_1, pthread_equal) + +/* pthread_exit () is a special case. */ +void +weak_function +pthread_exit (void *retval) +{ + exit (EXIT_SUCCESS); +} + +int +__pthread_return_0 (void) +{ + return 0; +} + +int +__pthread_return_1 (void) +{ + return 1; +} + +void +__pthread_return_void (void) +{ +} diff --git a/newlib/libc/sys/linux/linuxthreads/wrapsyscall.c b/newlib/libc/sys/linux/linuxthreads/wrapsyscall.c new file mode 100644 index 000000000..ec1bc2a90 --- /dev/null +++ b/newlib/libc/sys/linux/linuxthreads/wrapsyscall.c @@ -0,0 +1,251 @@ +/* Wrapper arpund system calls to provide cancelation points. + Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <fcntl.h> +#include <sys/mman.h> +#include <pthread.h> +#include <unistd.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdlib.h> +#include <termios.h> +#include <sys/resource.h> +#include <sys/wait.h> +#include <sys/socket.h> +#include "libc-symbols.h" + + +#ifndef SHARED +/* We need a hook to force this file to be linked in when static + libpthread is used. */ +const int __pthread_provide_wrappers = 0; +#endif + +#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2 +#define ELIX_2_PLUS +#endif + +#if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 3 +#define ELIX_3_PLUS +#endif + +#define CANCELABLE_SYSCALL(res_type, name, param_list, params) \ +res_type __libc_##name param_list; \ +res_type \ +__attribute__ ((weak)) \ +name param_list \ +{ \ + res_type result; \ + int oldtype; \ + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); \ + result = __libc_##name params; \ + pthread_setcanceltype (oldtype, NULL); \ + return result; \ +} + +#define CANCELABLE_SYSCALL_VA(res_type, name, param_list, params, last_arg) \ +res_type __libc_##name param_list; \ +res_type \ +__attribute__ ((weak)) \ +name param_list \ +{ \ + res_type result; \ + int oldtype; \ + va_list ap; \ + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); \ + va_start (ap, last_arg); \ + result = __libc_##name params; \ + va_end (ap); \ + pthread_setcanceltype (oldtype, NULL); \ + return result; \ +} + + +/* close(2). */ +CANCELABLE_SYSCALL (int, close, (int fd), (fd)) +strong_alias (close, __close) + + +/* fcntl(2). */ +CANCELABLE_SYSCALL_VA (int, fcntl, (int fd, int cmd, ...), + (fd, cmd, va_arg (ap, long int)), cmd) +strong_alias (fcntl, __fcntl) + + +/* fsync(2). */ +CANCELABLE_SYSCALL (int, fsync, (int fd), (fd)) + + +/* lseek(2). */ +CANCELABLE_SYSCALL (off_t, lseek, (int fd, off_t offset, int whence), + (fd, offset, whence)) +strong_alias (lseek, __lseek) + + +#ifdef ELIX_2_PLUS +/* lseek64(2). */ +CANCELABLE_SYSCALL (loff_t, lseek64, (int fd, loff_t offset, int whence), + (fd, offset, whence)) +#endif + + +/* msync(2). */ +CANCELABLE_SYSCALL (int, msync, (__ptr_t addr, size_t length, int flags), + (addr, length, flags)) + + +/* nanosleep(2). */ +CANCELABLE_SYSCALL (int, nanosleep, (const struct timespec *requested_time, + struct timespec *remaining), + (requested_time, remaining)) + + +/* open(2). */ +CANCELABLE_SYSCALL_VA (int, open, (const char *pathname, int flags, ...), + (pathname, flags, va_arg (ap, int)), flags) +strong_alias (open, __open) + + +#ifdef ELIX_2_PLUS +/* open64(3). */ +CANCELABLE_SYSCALL_VA (int, open64, (const char *pathname, int flags, ...), + (pathname, flags, va_arg (ap, int)), flags) +strong_alias (open64, __open64) +#endif + + +/* pause(2). */ +CANCELABLE_SYSCALL (int, pause, (void), ()) + + +/* pread(3). */ +CANCELABLE_SYSCALL (ssize_t, pread, (int fd, void *buf, size_t count, + off_t offset), + (fd, buf, count, offset)) + + +#ifdef ELIX_2_PLUS +/* pread64(3). */ +CANCELABLE_SYSCALL (ssize_t, pread64, (int fd, void *buf, size_t count, + loff_t offset), + (fd, buf, count, offset)) +strong_alias (pread64, __pread64) +#endif + + +/* pwrite(3). */ +CANCELABLE_SYSCALL (ssize_t, pwrite, (int fd, const void *buf, size_t n, + off_t offset), + (fd, buf, n, offset)) + + +#ifdef ELIX_2_PLUS +/* pwrite64(3). */ +CANCELABLE_SYSCALL (ssize_t, pwrite64, (int fd, const void *buf, size_t n, + loff_t offset), + (fd, buf, n, offset)) +strong_alias (pwrite64, __pwrite64) +#endif + + +/* read(2). */ +CANCELABLE_SYSCALL (ssize_t, read, (int fd, void *buf, size_t count), + (fd, buf, count)) +strong_alias (read, __read) + + +#ifdef ELIX_3_PLUS +/* system(3). */ +CANCELABLE_SYSCALL (int, system, (const char *line), (line)) +#endif + + +/* tcdrain(2). */ +CANCELABLE_SYSCALL (int, tcdrain, (int fd), (fd)) + + +#ifdef ELIX_3_PLUS +/* wait(2). */ +CANCELABLE_SYSCALL (__pid_t, wait, (int *stat_loc), (stat_loc)) +strong_alias (wait, __wait) +#endif + + +#ifdef ELIX_3_PLUS +/* waitpid(2). */ +CANCELABLE_SYSCALL (__pid_t, waitpid, (__pid_t pid, int *stat_loc, + int options), + (pid, stat_loc, options)) +#endif + +/* for libpthread usage */ +CANCELABLE_SYSCALL (__pid_t, __waitpid, (__pid_t pid, int *stat_loc, + int options), + (pid, stat_loc, options)) + +/* write(2). */ +CANCELABLE_SYSCALL (ssize_t, write, (int fd, const void *buf, size_t n), + (fd, buf, n)) +strong_alias (write, __write) + + +/* The following system calls are thread cancellation points specified + in XNS. */ + +/* accept(2). */ +CANCELABLE_SYSCALL (int, accept, (int fd, __SOCKADDR_ARG addr, + socklen_t *addr_len), + (fd, addr, addr_len)) + +/* connect(2). */ +CANCELABLE_SYSCALL (int, connect, (int fd, __CONST_SOCKADDR_ARG addr, + socklen_t len), + (fd, addr, len)) +strong_alias (connect, __connect) + +/* recv(2). */ +CANCELABLE_SYSCALL (ssize_t, recv, (int fd, __ptr_t buf, size_t n, int flags), + (fd, buf, n, flags)) + +/* recvfrom(2). */ +CANCELABLE_SYSCALL (ssize_t, recvfrom, (int fd, __ptr_t buf, size_t n, int flags, + __SOCKADDR_ARG addr, socklen_t *addr_len), + (fd, buf, n, flags, addr, addr_len)) + +/* recvmsg(2). */ +CANCELABLE_SYSCALL (ssize_t, recvmsg, (int fd, struct msghdr *message, int flags), + (fd, message, flags)) + +/* send(2). */ +CANCELABLE_SYSCALL (ssize_t, send, (int fd, const __ptr_t buf, size_t n, + int flags), + (fd, buf, n, flags)) +strong_alias (send, __send) + +/* sendmsg(2). */ +CANCELABLE_SYSCALL (ssize_t, sendmsg, (int fd, const struct msghdr *message, + int flags), + (fd, message, flags)) + +/* sendto(2). */ +CANCELABLE_SYSCALL (ssize_t, sendto, (int fd, const __ptr_t buf, size_t n, + int flags, __CONST_SOCKADDR_ARG addr, + socklen_t addr_len), + (fd, buf, n, flags, addr, addr_len)) |