Remove expired port:
2013-03-05 devel/linuxthreads: Broken for more than 6 month
This commit is contained in:
parent
21d085c862
commit
987c1e5571
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=320481
38 changed files with 1 additions and 9064 deletions
1
MOVED
1
MOVED
|
@ -4385,3 +4385,4 @@ x11-toolkits/ruby-wx||2013-06-07|Has expired: Does not work with Ruby 1.9
|
|||
sysutils/userspace-rcu|sysutils/liburcu|2013-06-07|Renamed correctly according to upstream
|
||||
mail/mixminion||2013-06-07|Has expired: This port requires python version, we haven't in the ports tree already
|
||||
devel/gprbuild-aux|devel/gprbuild|2013-06-10|Has expired: Deprecated in favour of devel/gprbuild
|
||||
devel/linuxthreads||2013-06-10|Has expired: Broken for more than 6 month
|
||||
|
|
|
@ -1147,7 +1147,6 @@
|
|||
SUBDIR += linux-f10-sdl12
|
||||
SUBDIR += linux-kmod-compat
|
||||
SUBDIR += linux_kdump
|
||||
SUBDIR += linuxthreads
|
||||
SUBDIR += lion
|
||||
SUBDIR += llvm
|
||||
SUBDIR += llvm-devel
|
||||
|
|
|
@ -1,280 +0,0 @@
|
|||
# Created by: Richard Seaman, Jr. <dick@tar.com>
|
||||
# $FreeBSD$
|
||||
|
||||
PORTNAME= linuxthreads
|
||||
PORTVERSION= 2.2.3
|
||||
PORTREVISION= 24
|
||||
CATEGORIES= devel
|
||||
MASTER_SITES= ${MASTER_SITE_GNU}
|
||||
MASTER_SITE_SUBDIR= glibc
|
||||
DISTNAME= glibc-linuxthreads-${PORTVERSION}
|
||||
|
||||
MAINTAINER= ports@FreeBSD.org
|
||||
COMMENT= POSIX pthreads implementation using rfork to generate kernel threads
|
||||
|
||||
USE_LDCONFIG= yes
|
||||
|
||||
DEPRECATED= Broken for more than 6 month
|
||||
EXPIRATION_DATE= 2013-03-05
|
||||
|
||||
.if defined(LINUXTHREADS_WRAP_API)
|
||||
USE_PERL5_BUILD=true
|
||||
.endif
|
||||
|
||||
.include <bsd.port.pre.mk>
|
||||
|
||||
BROKEN= does not build
|
||||
|
||||
# This port only works on i386 right now.
|
||||
ONLY_FOR_ARCHS= i386
|
||||
|
||||
USING_GCC4= true
|
||||
MAKE_ENV+= USING_GCC4=true
|
||||
|
||||
.if defined(LINUXTHREADS_INSTALL_LIBLTHREAD_PIC_ARCHIVE)
|
||||
MAKE_ENV+= INSTALL_LIBLTHREAD_PIC_ARCHIVE=yes
|
||||
.endif
|
||||
.if defined(LINUXTHREADS_MAX_STACK_SIZE)
|
||||
MAKE_ENV+= LINUXTHREADS_STACK_SIZE=${LINUXTHREADS_MAX_STACK_SIZE}
|
||||
.endif
|
||||
.if defined(LINUXTHREADS_MAX_THREADS)
|
||||
MAKE_ENV+= LINUXTHREADS_MAX_THREADS=${LINUXTHREADS_MAX_THREADS}
|
||||
.endif
|
||||
.if defined(LINUXTHREADS_DETECT_UNSAFE_EXIT)
|
||||
MAKE_ENV+= LINUXTHREADS_DETECT_UNSAFE_EXIT=yes
|
||||
.endif
|
||||
.if defined(LINUXTHREADS_WRAP_API)
|
||||
MAKE_ENV+= LINUXTHREADS_WRAP_API=yes
|
||||
MAKE_ENV+= LINUXTHREADS_WRAP_LD="sh ${FILESDIR}/ldwrap"
|
||||
.endif
|
||||
.if defined(LINUXTHREADS_NO_POSIX_PRIORITY_SCHEDULING)
|
||||
MAKE_ENV+= LINUXTHREADS_NO_POSIX_PRIORITY_SCHEDULING=yes
|
||||
.endif
|
||||
.if defined(LINUXTHREADS_ALT_RESTARTSIG)
|
||||
MAKE_ENV+= LINUXTHREADS_ALT_RESTARTSIG=${LINUXTHREADS_ALT_RESTARTSIG}
|
||||
.endif
|
||||
|
||||
threads_files := README.FreeBSD clone.S clone.h freebsd-compat.h getgr_r.c \
|
||||
gethostby_r.c getnetby_r.c getprotoby_r.c getpw_r.c getservby_r.c \
|
||||
lclone.c libc_calls.c libc_thread.c sched.c uthread_file.c \
|
||||
wraputhread.c localtime.c getlogin.c telldir.c ttyname.c
|
||||
|
||||
threads_files2 := _pthreadtypes.h
|
||||
|
||||
WRKSRC= ${WRKDIR}/${PKGNAME}
|
||||
SRC_BASE= /usr/src
|
||||
LIBSRC_BASE= ${SRC_BASE}/lib
|
||||
|
||||
pre-fetch:
|
||||
.if !defined(LINUXTHREADS_WITH_CONDWAIT_PATCH)
|
||||
@${ECHO}
|
||||
@${ECHO} You can use an experimental patch to reduce the number of
|
||||
@${ECHO} condition variable triggered context switches by defining
|
||||
@${ECHO} LINUXTHREADS_WITH_CONDWAIT_PATCH
|
||||
@${ECHO}
|
||||
.endif
|
||||
.if !defined(LINUXTHREADS_DETECT_UNSAFE_EXIT)
|
||||
@${ECHO}
|
||||
@${ECHO} "Some unsafe calls to exit() can be detected by defining"
|
||||
@${ECHO} "LINUXTHREADS_DETECT_UNSAFE_EXIT, see files/README.FreeBSD"
|
||||
@${ECHO} "for more info."
|
||||
@${ECHO}
|
||||
.endif
|
||||
.if !defined(LINUXTHREADS_MAX_STACK_SIZE)
|
||||
@${ECHO}
|
||||
@${ECHO} "The maximum stack size (default 2097152) can be overridden"
|
||||
@${ECHO} "by defining LINUXTHREADS_MAX_STACK_SIZE,"
|
||||
@${ECHO} "see files/README.FreeBSD for more info."
|
||||
@${ECHO}
|
||||
.endif
|
||||
.if !defined(LINUXTHREADS_MAX_THREADS)
|
||||
@${ECHO}
|
||||
@${ECHO} "The maximum number of threads (default 1024) can be"
|
||||
@${ECHO} "overriden by defining LINUXTHREADS_MAX_THREADS,"
|
||||
@${ECHO} "see files/README.FreeBSD for more info."
|
||||
@${ECHO}
|
||||
.endif
|
||||
.if !defined(LINUXTHREADS_WRAP_API)
|
||||
@${ECHO}
|
||||
@${ECHO} "Some conflicts with native threads can be avoided by defining"
|
||||
@${ECHO} "LINUXTHREADS_WRAP_API, see files/README.FreeBSD"
|
||||
@${ECHO} "for more info."
|
||||
@${ECHO}
|
||||
.endif
|
||||
.if !defined(LINUXTHREADS_NO_POSIX_PRIORITY_SCHEDULING)
|
||||
@${ECHO}
|
||||
@${ECHO} "Use of POSIX priority scheduling can be turned off by"
|
||||
@${ECHO} "defining LINUXTHREADS_NO_POSIX_PRIORITY_SCHEDULING,"
|
||||
@${ECHO} "see files/README.FreeBSD for more info."
|
||||
@${ECHO}
|
||||
.endif
|
||||
.if !defined(LINUXTHREADS_ALT_RESTARTSIG)
|
||||
@${ECHO}
|
||||
@${ECHO} "An alternate restart signal can be selected by"
|
||||
@${ECHO} "defining LINUXTHREADS_ALT_RESTARTSIG,"
|
||||
@${ECHO} "see files/README.FreeBSD for more info."
|
||||
@${ECHO}
|
||||
.endif
|
||||
@if ${TEST} -f /usr/src/gnu/lib/libgcc/Makefile; then \
|
||||
: ; \
|
||||
else \
|
||||
${ECHO_MSG} ">>The linuxthreads port needs source code for libgcc"; \
|
||||
${ECHO_MSG} ">>Please install FreeBSD source code in /usr/src"; \
|
||||
${FALSE}; \
|
||||
fi
|
||||
.if defined(USING_GCC3) || defined(USING_GCC4)
|
||||
@if ${TEST} -f /usr/src/gnu/lib/libstdc++/Makefile; then \
|
||||
: ; \
|
||||
else \
|
||||
${ECHO_MSG} ">>The linuxthreads port needs source code for libstdc++"; \
|
||||
${ECHO_MSG} ">>Please install FreeBSD source code in /usr/src"; \
|
||||
${FALSE}; \
|
||||
fi
|
||||
@if ${TEST} -f /usr/src/gnu/lib/libsupc++/Makefile; then \
|
||||
: ; \
|
||||
else \
|
||||
${ECHO_MSG} ">>The linuxthreads port needs source code for libsupc++"; \
|
||||
${ECHO_MSG} ">>Please install FreeBSD source code in /usr/src"; \
|
||||
${FALSE}; \
|
||||
fi
|
||||
.endif
|
||||
|
||||
post-extract:
|
||||
@${MV} ${WRKDIR}/linuxthreads ${WRKSRC}
|
||||
@${MV} ${WRKDIR}/linuxthreads_db ${WRKSRC}
|
||||
.for src in lockfile.c no-tsd.c oldsemaphore.c weaks.c \
|
||||
sysdeps/pthread/semaphore.h
|
||||
@${MV} ${WRKSRC}/$(src) ${WRKSRC}/$(src).unused
|
||||
.endfor
|
||||
@cd ${FILESDIR} ; \
|
||||
${CP} -p ${threads_files} ${WRKSRC}/.
|
||||
@${SED} -f ${FILESDIR}/strptime.sed \
|
||||
/usr/src/lib/libc/stdtime/strptime.c \
|
||||
> ${WRKSRC}/strptime.c
|
||||
@${MKDIR} ${WRKSRC}/sys
|
||||
@cd ${FILESDIR} ; \
|
||||
${CP} -p ${threads_files2} ${WRKSRC}/sys/.
|
||||
@${MKDIR} ${WRKSRC}/libgcc_r
|
||||
@${TEST} -f ${WRKSRC}/libgcc_r/Makefile || \
|
||||
${LN} -s ${FILESDIR}/Makefile.libgcc_r ${WRKSRC}/libgcc_r/Makefile
|
||||
@${SED} -e 's/^LIB=[ ]*gcc$$/LIB= lgcc_r/;' \
|
||||
-e 's/^SHLIB_NAME=[ ]*libgcc_s\.so\./SHLIB_NAME= liblgcc_s.so./' \
|
||||
-e 's=$${.CURDIR}=/usr/src/gnu/lib/libgcc=g' \
|
||||
/usr/src/gnu/lib/libgcc/Makefile \
|
||||
> ${WRKSRC}/libgcc_r/Makefile.inc.tmp && \
|
||||
${MV} ${WRKSRC}/libgcc_r/Makefile.inc.tmp \
|
||||
${WRKSRC}/libgcc_r/Makefile.inc
|
||||
.if defined(USING_GCC3) || defined(USING_GCC4)
|
||||
@${MKDIR} ${WRKSRC}/libstdc++
|
||||
@${TEST} -f ${WRKSRC}/libstdc++/Makefile || \
|
||||
${LN} -s ${FILESDIR}/Makefile.libstdc++ ${WRKSRC}/libstdc++/Makefile
|
||||
@${SED} -e 's/^LIB=[ ]*stdc\+\+$$/LIB= lstdc++/;' \
|
||||
-e 's=$${.CURDIR}=/usr/src/gnu/lib/libstdc++=g' \
|
||||
/usr/src/gnu/lib/libstdc++/Makefile \
|
||||
> ${WRKSRC}/libstdc++/Makefile.inc.tmp && \
|
||||
${MV} ${WRKSRC}/libstdc++/Makefile.inc.tmp \
|
||||
${WRKSRC}/libstdc++/Makefile.inc
|
||||
@${MKDIR} ${WRKSRC}/libsupc++
|
||||
@${TEST} -f ${WRKSRC}/libsupc++/Makefile || \
|
||||
${LN} -s ${FILESDIR}/Makefile.libsupc++ ${WRKSRC}/libsupc++/Makefile
|
||||
@${SED} -e 's/^LIB=[ ]*supc\+\+$$/LIB= lsupc++/;' \
|
||||
-e 's=$${.CURDIR}=/usr/src/gnu/lib/libsupc++=g' \
|
||||
/usr/src/gnu/lib/libsupc++/Makefile \
|
||||
> ${WRKSRC}/libsupc++/Makefile.inc.tmp && \
|
||||
${MV} ${WRKSRC}/libsupc++/Makefile.inc.tmp \
|
||||
${WRKSRC}/libsupc++/Makefile.inc
|
||||
.endif
|
||||
|
||||
.if defined(LINUXTHREADS_WITH_CONDWAIT_PATCH) || defined(LINUXTHREADS_WRAP_API)
|
||||
post-patch:
|
||||
.if defined(LINUXTHREADS_WITH_CONDWAIT_PATCH)
|
||||
@${ECHO_MSG} "===> Applying experimental patch condwait-patch"
|
||||
@if ${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/condwait-patch; then \
|
||||
${ECHO_MSG} "===> Patch condwait-patch applied successfully"; \
|
||||
else \
|
||||
${ECHO_MSG} ">>Patch condwait-patch failed to apply cleanly"; \
|
||||
${FALSE}; \
|
||||
fi
|
||||
.endif
|
||||
.if defined(LINUXTHREADS_WRAP_API)
|
||||
{PERL} -pi -e '$$func=$$1 if m/^extern\s+\S+\s+\*?(\S+)\s+\(/; $$alias="#ifdef COMPILING_WRAPUTHREAD\n\t__attribute__((weak, alias(\"_$$func\")))\n#endif\n"; $$wrap="#ifndef COMPILING_LINUXTHREADS\n\t__asm__(\"linuxthreads_$$func\")\n#endif\n"; $$alias="" if ( $$func =~ m/^(pthread_spin|_pthread_cleanup|pthread_rwlockattr_[gs]etkind_np|pthread_kill_other_threads_np)/ ); s=__THROW=\n$$wrap$$alias\t__THROW= unless m/^#/;' ${WRKSRC}/sysdeps/pthread/pthread.h ${WRKSRC}/sysdeps/unix/sysv/linux/bits/sigthread.h
|
||||
.endif
|
||||
.endif
|
||||
|
||||
pre-build:
|
||||
@cd ${WRKSRC}/libgcc_r ; \
|
||||
${SETENV} ${MAKE_ENV} ${MAKE}
|
||||
.if defined(USING_GCC3) || defined(USING_GCC4)
|
||||
cd ${WRKSRC}/libstdc++ ; \
|
||||
${SETENV} ${MAKE_ENV} ${MAKE}
|
||||
@cd ${WRKSRC}/libsupc++ ; \
|
||||
${SETENV} ${MAKE_ENV} ${MAKE}
|
||||
.endif
|
||||
|
||||
pre-su-install:
|
||||
${INSTALL} -d -o ${BINOWN} -g ${BINGRP} -m 0755 ${PREFIX}/lib
|
||||
@cd ${WRKSRC}/libgcc_r ; \
|
||||
${SETENV} ${MAKE_ENV} ${MAKE} install
|
||||
.if defined(USING_GCC3) || defined(USING_GCC4)
|
||||
@cd ${WRKSRC}/libstdc++ ; \
|
||||
${SETENV} ${MAKE_ENV} ${MAKE} install
|
||||
@cd ${WRKSRC}/libsupc++ ; \
|
||||
${SETENV} ${MAKE_ENV} ${MAKE} install
|
||||
.endif
|
||||
|
||||
post-install:
|
||||
${CAT} ${PKGMESSAGE}
|
||||
|
||||
.if defined(NO_PROFILE)
|
||||
PLIST_SUB= PROFILE:="@comment "
|
||||
.else
|
||||
PLIST_SUB= PROFILE:=""
|
||||
.endif
|
||||
.if defined(NO_PIC)
|
||||
PLIST_SUB+= PIC:="@comment "
|
||||
.else
|
||||
PLIST_SUB+= PIC:=""
|
||||
.endif
|
||||
.if defined(INSTALL_PIC_ARCHIVE)
|
||||
PLIST_SUB+= PICARCHIVE:=""
|
||||
.else
|
||||
PLIST_SUB+= PICARCHIVE:="@comment "
|
||||
.endif
|
||||
.if defined(INSTALL_PIC_ARCHIVE)
|
||||
PLIST_SUB+= LIBLGCC_R_PICARCHIVE:=""
|
||||
.else
|
||||
PLIST_SUB+= LIBLGCC_R_PICARCHIVE:="@comment "
|
||||
.endif
|
||||
.if defined(INSTALL_PIC_ARCHIVE) || defined(LINUXTHREADS_INSTALL_LIBLTHREAD_PIC_ARCHIVE)
|
||||
PLIST_SUB+= LIBLTHREADPICARCHIVE:=""
|
||||
.else
|
||||
PLIST_SUB+= LIBLTHREADPICARCHIVE:="@comment "
|
||||
.endif
|
||||
.if defined(USING_GCC4)
|
||||
PLIST_SUB+= GCC3OR4ONLY:=""
|
||||
PLIST_SUB+= GCC4ONLY:=""
|
||||
.if defined(LINUXTHREADS_WRAP_API)
|
||||
PLIST_SUB+= LTHREADSHMAJOR:="7"
|
||||
.else
|
||||
PLIST_SUB+= LTHREADSHMAJOR:="6"
|
||||
.endif
|
||||
.elif defined(USING_GCC3)
|
||||
PLIST_SUB+= GCC3OR4ONLY:=""
|
||||
PLIST_SUB+= GCC4ONLY:="@comment "
|
||||
.if defined(LINUXTHREADS_WRAP_API)
|
||||
PLIST_SUB+= LTHREADSHMAJOR:="5"
|
||||
.else
|
||||
PLIST_SUB+= LTHREADSHMAJOR:="3"
|
||||
.endif
|
||||
.else
|
||||
PLIST_SUB+= GCC3OR4ONLY:="@comment "
|
||||
PLIST_SUB+= GCC4ONLY:="@comment "
|
||||
.if defined(LINUXTHREADS_WRAP_API)
|
||||
PLIST_SUB+= LTHREADSHMAJOR:="4"
|
||||
.else
|
||||
PLIST_SUB+= LTHREADSHMAJOR:="2"
|
||||
.endif
|
||||
.endif
|
||||
PLIST_SUB+= LIBSTDCPPMAJOR:="6"
|
||||
|
||||
.include <bsd.port.post.mk>
|
|
@ -1,2 +0,0 @@
|
|||
SHA256 (glibc-linuxthreads-2.2.3.tar.gz) = 10e87b3f7690fa03904a53934eae17577a90fa9b53d348a116af2fcea6746e2a
|
||||
SIZE (glibc-linuxthreads-2.2.3.tar.gz) = 215313
|
|
@ -1,22 +0,0 @@
|
|||
# $FreeBSD: /tmp/pcvs/ports/devel/linuxthreads/files/Makefile.libgcc_r,v 1.6 2007-07-03 08:38:00 pav Exp $
|
||||
|
||||
PREFIX?= ${DESTDIR}/usr/local
|
||||
LIBDIR= ${PREFIX:S,^${DESTDIR},,}/lib
|
||||
SHLIBDIR= ${PREFIX:S,^${DESTDIR},,}/lib
|
||||
.if defined(USING_GCC4)
|
||||
INSTALL_PIC_ARCHIVE=yes
|
||||
.endif
|
||||
|
||||
CFLAGS+=-D_PTHREADS -I../ -D__USE_UNIX98
|
||||
CFLAGS+=-I../sysdeps/i386 -I../sysdeps/pthread -I../sysdeps/unix/sysv/linux
|
||||
CXXFLAGS= ${CXXINCLUDES} ${CFLAGS:C/-std=[a-z:0-9]+//}
|
||||
|
||||
installincludes:
|
||||
|
||||
.include "Makefile.inc"
|
||||
|
||||
#
|
||||
# Override various things that are set in the main Makefile.
|
||||
#
|
||||
|
||||
.undef SUBDIR
|
|
@ -1,19 +0,0 @@
|
|||
# $FreeBSD: /tmp/pcvs/ports/devel/linuxthreads/files/Makefile.libstdc++,v 1.3 2007-03-21 21:49:04 tegge Exp $
|
||||
|
||||
PREFIX?= ${DESTDIR}/usr/local
|
||||
LIBDIR= ${PREFIX:S,^${DESTDIR},,}/lib
|
||||
|
||||
CFLAGS+=-D_PTHREADS -I../ -D__USE_UNIX98
|
||||
CFLAGS+=-I../sysdeps/i386 -I../sysdeps/pthread -I../sysdeps/unix/sysv/linux
|
||||
CXXFLAGS= ${CXXINCLUDES} ${CFLAGS:C/-std=[a-z:0-9]+//}
|
||||
LDADD=../libgcc_r/liblgcc_r.a
|
||||
|
||||
installincludes:
|
||||
|
||||
.include "Makefile.inc"
|
||||
|
||||
#
|
||||
# Override various things that are set in the main Makefile.
|
||||
#
|
||||
|
||||
.undef SUBDIR
|
|
@ -1,19 +0,0 @@
|
|||
# $FreeBSD: /tmp/pcvs/ports/devel/linuxthreads/files/Makefile.libsupc++,v 1.3 2007-03-21 21:49:04 tegge Exp $
|
||||
|
||||
PREFIX?= ${DESTDIR}/usr/local
|
||||
LIBDIR= ${PREFIX:S,^${DESTDIR},,}/lib
|
||||
|
||||
CFLAGS+=-D_PTHREADS -I../ -D__USE_UNIX98
|
||||
CFLAGS+=-I../sysdeps/i386 -I../sysdeps/pthread -I../sysdeps/unix/sysv/linux
|
||||
CXXFLAGS= ${CXXINCLUDES} ${CFLAGS:C/-std=[a-z:0-9]+//}
|
||||
LDADD=../libgcc_r/liblgcc_r.a
|
||||
|
||||
installincludes:
|
||||
|
||||
.include "Makefile.inc"
|
||||
|
||||
#
|
||||
# Override various things that are set in the main Makefile.
|
||||
#
|
||||
|
||||
.undef SUBDIR
|
|
@ -1,161 +0,0 @@
|
|||
Some brief notes:
|
||||
|
||||
1) This package is intended to run on FreeBSD 5.0-current or FreeBSD 4.X, i386
|
||||
processors only.
|
||||
|
||||
Do not use libc_r with the linuxthreads port, and do not compile/link with the
|
||||
-pthread option (which pulls in libc_r). Rather, link with libc (which you will
|
||||
get by default).
|
||||
|
||||
Compile your applications that use the linuxthreads port with the following
|
||||
command line options:
|
||||
|
||||
-D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -llthread -llgcc_r
|
||||
|
||||
Note that the include (-I<path>) directive shown here should appear before any
|
||||
other include directive that would cause the compiler to find the FreeBSD file
|
||||
/usr/include/pthread.h. Using the FreeBSD pthread.h instead of the linuxthreads
|
||||
pthread.h will result in an app that fails in many odd and maybe spectacular
|
||||
ways.
|
||||
|
||||
In order to facilitate porting applications which expect a libpthread, you can
|
||||
create the following symlinks if you want:
|
||||
|
||||
ln -s /usr/local/lib/liblthread.a /usr/lib/libpthread.a
|
||||
ln -s /usr/local/lib/liblthread_p.a /usr/lib/libpthread_p.a
|
||||
ln -s /usr/local/lib/liblthread.so.2 /usr/lib/libpthread.so.2
|
||||
ln -s /usr/local/lib/liblthread.so.2 /usr/lib/libpthread.so
|
||||
/sbin/ldconfig -m /usr/lib
|
||||
|
||||
If you do this, you can instead use:
|
||||
|
||||
-D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -lpthread -llgcc_r
|
||||
|
||||
Another option is to create a custom gcc specs file that tells the linker which
|
||||
version of libgcc to use. To do this, create a file with the following in it:
|
||||
|
||||
--- (/foo/specs) cut here ---
|
||||
*libgcc:
|
||||
/usr/local/lib/liblgcc_r.a
|
||||
--- (/foo/specs) cut here ---
|
||||
|
||||
Then use the following command line options:
|
||||
|
||||
-B/foo/ -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -llthread
|
||||
|
||||
or if you created symlinks:
|
||||
|
||||
-B/foo/ -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads -lpthread
|
||||
|
||||
2) If you plan on having lots of threads, check the sysctl value of
|
||||
kern.maxproc. Each kernel thread counts against maxproc. You can increase
|
||||
maxproc by changing the MAXUSERS value in your kernel config file. maxproc is
|
||||
set at 20 + 16 * MAXUSERS.
|
||||
|
||||
3) Be aware of the following libc issues:
|
||||
|
||||
a) Not all libc calls are thread safe. In particular gmtime, localtime, etc
|
||||
are not thread safe. In general, where the pthreads spec calls for "_r"
|
||||
functions, these are either not provided, or if provided are not thread safe
|
||||
(in most cases) and the related libc calls are not thread safe. This differs
|
||||
somewhat from the FreeBSD libc_r library, where some, but not all, of these
|
||||
functions are both thread safe and have "_r" versions.
|
||||
|
||||
b) Not all of the libc calls that are supposed to be cancellation points are
|
||||
implemented as such. While linux threads has the cancel functions
|
||||
implemented, deferred cancellation will not work as required by POSIX
|
||||
1003.1c-1995, since the co-operation needed from libc is not complete.
|
||||
|
||||
c) The mutex wrapper functions only provide standard linuxthreads mutexes
|
||||
(i.e. non-recursive mutexes). This might lead to deadlocks if libc
|
||||
depends on recursive mutexes.
|
||||
|
||||
4) Be aware of the following libgcc issue:
|
||||
|
||||
FreeBSD 4.* (gcc 2.*):
|
||||
|
||||
__register_frame_info() and __get_eh_info() from libgcc.a are linked
|
||||
into shared libraries that use exceptions, e.g. libstdc++. Those
|
||||
functions are not compatible with linuxthreads due to pthread_mutex_t
|
||||
and pthread_once_t having different sizes and static initializers.
|
||||
Linking the shared linuxthreads library before any such library causes
|
||||
the liblgcc_r.a version of those functions to be used.
|
||||
|
||||
FreeBSD 5.* (gcc 3.*):
|
||||
|
||||
__register_frame_info() and __frame_state_for() from libgcc.a are
|
||||
linked into shared libraries that use exceptions, e.g. libstdc++.
|
||||
Those functions are not compatible with linuxthreads due to
|
||||
pthread_mutex_t and pthread_once_t having different sizes and static
|
||||
initializers. Linking the shared linuxthreads library before any such
|
||||
library causes the liblgcc_r.a version of those functions to be used.
|
||||
Use liblstdc++ and liblsupc++.
|
||||
|
||||
Experimental wrapper support:
|
||||
|
||||
If the linuxthreads library has been compiled with
|
||||
LINUXTHREADS_WRAP_API defined in the ports makefile then
|
||||
the API functions are internally prefixed with linuxthreads_
|
||||
to avoid conflict with native threads. Weak symbols without
|
||||
that prefix points to the wrapper functions (internally
|
||||
prefixed by _) that makes the linuxthreads functions available
|
||||
with the native threads API. Applications including the
|
||||
linuxthreads version of pthread.h will try to call the
|
||||
prefixed methods (e.g. linuxthreads_pthread_create) while
|
||||
applications including the native pthread.h will use the
|
||||
wrapper functions. This allows for some level of coexistence
|
||||
of libraries compiled with linuxthreads header file and
|
||||
libraries compiled with native threads header files as long
|
||||
as none of the pthread data types leaks out as function arguments
|
||||
or structure members.
|
||||
|
||||
5) Exit handling is broken.
|
||||
|
||||
If the linuxthreads library has been compiled with
|
||||
LINUXTHREADS_DETECT_UNSAFE_EXIT defined in the ports makefile then
|
||||
the library tries to avoid further calls to functions registered
|
||||
with atexit if not called from the main thread or if other threads
|
||||
were active. Since this implicitly indicates a failure to do
|
||||
proper cleanup, the exit code is then changed to 1.
|
||||
|
||||
If the linuxthreads library has been compiled without
|
||||
LINUXTHREADS_DETECT_UNSAFE_EXIT, then calls to exit() has a
|
||||
slightly higher probability of crashing or hanging the program when
|
||||
other threads are active. If another thread than the main thread
|
||||
performs the exit call, the exit code will appear to be 0.
|
||||
|
||||
If multiple threads calls exit then the application will likely
|
||||
crash.
|
||||
|
||||
If other threads has been joined by the main thread before it calls
|
||||
exit then exit handling should be fairly safe and the correct exit
|
||||
code can be detected by the parent process.
|
||||
|
||||
6) If the rate of sched_yield() calls is very high (due to
|
||||
malloc / spinlock interaction) then
|
||||
LINUXTHREADS_NO_POSIX_PRIORITY_SCHEDULING can be defined when
|
||||
compiling the linuxthreads library. This has the same effect
|
||||
as if the kernel was compiled without the _KPOSIX_PRIORITY_SCHEDULING
|
||||
option, but limited to the linuxthread library.
|
||||
|
||||
7) libraries using SIGUSR2 or SIGUSR1 will conflict with linuxthreads.
|
||||
SIGUSR1 is hardcoded in the FreeBSD kernel (cf. RFLINUXTHPN flag
|
||||
passed to rfork()), but the linuxthreads library can be changed to use
|
||||
another signal instead of SIGUSR2 by defining LINUXTHREADS_ALT_RESTARTSIG
|
||||
to the alternate signal number (e.g. 32).
|
||||
|
||||
8) By default, the maximum thread stack size is 2 MB, and the maximum
|
||||
number of threads is 1024. Layout of stacks are based on the
|
||||
maximum thread stack size. This means that 2 GB of the address space
|
||||
can be used by thread stacks, limiting what is left for other
|
||||
purposes (text, data, bss, heap, mmap). To shrink the address range
|
||||
used for thread stacks, the maximum thread stack size can be changed
|
||||
by defining LINUXTHREADS_MAX_STACK_SIZE to a suitable value, e.g.
|
||||
1048576. The maximum number of threads can be changed by defining
|
||||
LINUXTHREADS_MAX_THREADS to a suitable value, e.g. 2048.
|
||||
The product of the maximum thread stack size and the maximum number
|
||||
of threads should not exceed 2 GB. The maximum stack size must be
|
||||
a power of 2.
|
||||
|
||||
9) The complete FreeBSD source code matching the installed userland
|
||||
must be installed in /usr/src before building linuxthreads.
|
|
@ -1,45 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 2005 Yahoo! Technologies Norway AS
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LINUXTHREADS_SYS__PTHREADTYPES_H
|
||||
#define _LINUXTHREADS_SYS__PTHREADTYPES_H
|
||||
|
||||
#ifndef _SIZE_T_DECLARED
|
||||
typedef __size_t size_t;
|
||||
#define _SIZE_T_DECLARED
|
||||
#endif
|
||||
|
||||
#include <sched.h>
|
||||
|
||||
#ifdef _BITS_TYPES_H
|
||||
#include <bits/pthreadtypes.h>
|
||||
#else
|
||||
#define _BITS_TYPES_H
|
||||
#include <bits/pthreadtypes.h>
|
||||
#undef _BITS_TYPES_H
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,143 +0,0 @@
|
|||
.file "clone.S"
|
||||
#include <sys/syscall.h>
|
||||
#if __FreeBSD__ >= 5
|
||||
#include <machine/asm.h>
|
||||
#else
|
||||
#include "DEFS.h"
|
||||
#endif
|
||||
#include "SYS.h"
|
||||
#define KERNEL
|
||||
#define _KERNEL
|
||||
#include <sys/errno.h>
|
||||
#undef _KERNEL
|
||||
#undef KERNEL
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
/*
|
||||
* 8 12 16 20
|
||||
* _clone (__fn, __childstack, __flags, __arg);
|
||||
*
|
||||
* Here's the idea:
|
||||
* __childstack is the TOS for the new rforked thread
|
||||
* __flags are the rfork flags
|
||||
* __fn is the userland function go be started for the new thread
|
||||
* as in:
|
||||
*
|
||||
* int __fn (void * __arg)
|
||||
*
|
||||
*/
|
||||
.stabs "clone.S",100,0,0,Ltext0
|
||||
.text
|
||||
Ltext0:
|
||||
.type CNAME(_clone),@function
|
||||
.stabd 68,0,1
|
||||
ENTRY(_clone)
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
pushl %esi
|
||||
PIC_PROLOGUE
|
||||
|
||||
/*
|
||||
* Push thread info onto the new thread's stack
|
||||
*/
|
||||
movl 12(%ebp), %esi /* get stack addr */
|
||||
|
||||
subl $4, %esi
|
||||
andl $-16, %esi /* Align stack addr */
|
||||
movl 20(%ebp), %eax /* get __arg */
|
||||
movl %eax, (%esi)
|
||||
|
||||
subl $4, %esi
|
||||
movl 8(%ebp), %eax /* get __fn */
|
||||
movl %eax, (%esi)
|
||||
|
||||
.stabd 68,0,2
|
||||
/*
|
||||
* Prepare and execute rfork
|
||||
*/
|
||||
pushl 16(%ebp)
|
||||
pushl $0 /* fake return address */
|
||||
|
||||
leal SYS_rfork, %eax
|
||||
KERNCALL
|
||||
jb 2f
|
||||
|
||||
.stabd 68,0,3
|
||||
/*
|
||||
* Check to see if we are in the parent or child
|
||||
*/
|
||||
cmpl $0, %edx
|
||||
jnz 1f
|
||||
addl $8, %esp
|
||||
PIC_EPILOGUE
|
||||
popl %esi
|
||||
movl %ebp, %esp
|
||||
popl %ebp
|
||||
ret
|
||||
.p2align 2
|
||||
|
||||
/*
|
||||
* If we are in the child (new thread), then
|
||||
* set-up the call to the internal subroutine. If it
|
||||
* returns, then call _exit.
|
||||
*/
|
||||
.stabd 68,0,4
|
||||
1:
|
||||
movl %esi,%esp
|
||||
#ifdef DEBUG
|
||||
movl %esp, _stackaddr
|
||||
movl (%esp), %eax
|
||||
movl %eax, _stack
|
||||
movl 4(%esp), %eax
|
||||
movl %eax,_stack+4
|
||||
movl 8(%esp), %eax
|
||||
movl %eax,_stack+8
|
||||
#endif
|
||||
popl %eax
|
||||
#ifdef DEBUG
|
||||
movl %eax,_fcn
|
||||
#endif
|
||||
movl $0, %ebp
|
||||
call *%eax
|
||||
addl $8, %esp
|
||||
|
||||
/*
|
||||
* Exit system call
|
||||
*/
|
||||
call PIC_PLT(_exit)
|
||||
|
||||
.stabd 68,0,5
|
||||
2: addl $8, %esp
|
||||
PIC_EPILOGUE
|
||||
popl %esi
|
||||
movl %ebp, %esp
|
||||
popl %ebp
|
||||
PIC_PROLOGUE
|
||||
/* Copy of libc .cerror since libc .cerror must be called from libc */
|
||||
pushl %eax
|
||||
/* The caller must execute the PIC prologue before jumping to cerror. */
|
||||
call PIC_PLT(CNAME(__error))
|
||||
popl %ecx
|
||||
PIC_EPILOGUE
|
||||
movl %ecx,(%eax)
|
||||
movl $-1,%eax
|
||||
movl $-1,%edx
|
||||
ret
|
||||
|
||||
.stabs "_clone:f67",36,0,6,CNAME(_clone)
|
||||
Lfe1:
|
||||
.size CNAME(_clone),Lfe1-CNAME(_clone)
|
||||
|
||||
#ifdef DEBUG
|
||||
.data
|
||||
.globl _stack
|
||||
_stack: .long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0
|
||||
.globl _stackaddr
|
||||
_stackaddr: .long 0
|
||||
.globl _fcn
|
||||
_fcn: .long 0
|
||||
#endif
|
|
@ -1,42 +0,0 @@
|
|||
/* Definitions of constants and data structure for POSIX 1003.1b-1993
|
||||
scheduling interface.
|
||||
Copyright (C) 1996, 1997 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 CLONE_H
|
||||
#define CLONE_H
|
||||
|
||||
/* Cloning flags. */
|
||||
#define CSIGNAL 0x000000ff /* Signal mask to be sent at exit. */
|
||||
#define CLONE_VM 0x00000100 /* Set if VM shared between processes. */
|
||||
#define CLONE_FS 0x00000200 /* Set if fs info shared between processes.*/
|
||||
#define CLONE_FILES 0x00000400 /* Set if open files shared between processes*/
|
||||
#define CLONE_SIGHAND 0x00000800 /* Set if signal handlers shared. */
|
||||
#define CLONE_PID 0x00001000 /* Set if pid shared. */
|
||||
|
||||
/* Clone current process. */
|
||||
extern int __clone __P ((int (*__fn) (void *__arg), void *__child_stack,
|
||||
int __flags, void *__arg));
|
||||
|
||||
extern int _clone __P ((int (*__fn) (void *__arg), void *__child_stack,
|
||||
int __flags, void *__arg));
|
||||
|
||||
extern int clone __P ((int (*__fn) (void *__arg), void *__child_stack,
|
||||
int __flags, void *__arg));
|
||||
|
||||
#endif
|
|
@ -1,369 +0,0 @@
|
|||
diff -ru ../../work.nc/linuxthreads-2.2.3_19/condvar.c ./condvar.c
|
||||
--- ../../work.nc/linuxthreads-2.2.3_19/condvar.c Thu Apr 12 23:02:02 2001
|
||||
+++ ./condvar.c Tue Jan 10 18:14:20 2006
|
||||
@@ -55,6 +55,11 @@
|
||||
return did_remove;
|
||||
}
|
||||
|
||||
+extern int __pthread_mutex_condwait_completelock(pthread_mutex_t *mutex);
|
||||
+
|
||||
+#define CVA_AVAIL 1
|
||||
+#define CVA_EXTRA_RESTART 2
|
||||
+
|
||||
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
volatile pthread_descr self = thread_self();
|
||||
@@ -74,6 +79,7 @@
|
||||
|
||||
/* Register extrication interface */
|
||||
THREAD_SETMEM(self, p_condvar_avail, 0);
|
||||
+ THREAD_SETMEM(self, p_condwait_mutex, mutex);
|
||||
__pthread_set_own_extricate_if(self, &extr);
|
||||
|
||||
/* Atomically enqueue thread for waiting, but only if it is not
|
||||
@@ -102,10 +108,15 @@
|
||||
while (1)
|
||||
{
|
||||
suspend(self);
|
||||
- if (THREAD_GETMEM(self, p_condvar_avail) == 0
|
||||
+ if ((THREAD_GETMEM(self, p_condvar_avail) & CVA_AVAIL) == 0
|
||||
&& (THREAD_GETMEM(self, p_woken_by_cancel) == 0
|
||||
|| THREAD_GETMEM(self, p_cancelstate) != PTHREAD_CANCEL_ENABLE))
|
||||
{
|
||||
+ if ((THREAD_GETMEM(self, p_condvar_avail) &
|
||||
+ CVA_EXTRA_RESTART) == 0 &&
|
||||
+ !__compare_and_swap(&self->p_condvar_avail,
|
||||
+ 0, CVA_EXTRA_RESTART))
|
||||
+ break; /* CVA_AVAIL set by other thread */
|
||||
/* Count resumes that don't belong to us. */
|
||||
spurious_wakeup_count++;
|
||||
continue;
|
||||
@@ -121,15 +132,35 @@
|
||||
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);
|
||||
+ if (THREAD_GETMEM(self, p_condwait_mutex) == NULL) {
|
||||
+ if ((THREAD_GETMEM(self, p_condvar_avail) & CVA_EXTRA_RESTART) != 0) {
|
||||
+ if (spurious_wakeup_count > 0)
|
||||
+ spurious_wakeup_count--;
|
||||
+ else
|
||||
+ suspend(self);
|
||||
+ }
|
||||
+ __pthread_mutex_condwait_completelock(mutex);
|
||||
+ } else
|
||||
+ pthread_mutex_lock(mutex);
|
||||
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
|
||||
}
|
||||
|
||||
+ if (THREAD_GETMEM(self, p_condwait_mutex) == NULL &&
|
||||
+ (THREAD_GETMEM(self, p_condvar_avail) & CVA_EXTRA_RESTART) != 0) {
|
||||
+ if (spurious_wakeup_count > 0)
|
||||
+ spurious_wakeup_count--;
|
||||
+ else
|
||||
+ suspend(self);
|
||||
+ }
|
||||
+
|
||||
/* Put back any resumes we caught that don't belong to us. */
|
||||
while (spurious_wakeup_count--)
|
||||
restart(self);
|
||||
|
||||
- pthread_mutex_lock(mutex);
|
||||
+ if (THREAD_GETMEM(self, p_condwait_mutex) == NULL)
|
||||
+ __pthread_mutex_condwait_completelock(mutex);
|
||||
+ else
|
||||
+ pthread_mutex_lock(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -155,6 +186,7 @@
|
||||
|
||||
/* Register extrication interface */
|
||||
THREAD_SETMEM(self, p_condvar_avail, 0);
|
||||
+ THREAD_SETMEM(self, p_condwait_mutex, mutex);
|
||||
__pthread_set_own_extricate_if(self, &extr);
|
||||
|
||||
/* Enqueue to wait on the condition and check for cancellation. */
|
||||
@@ -196,10 +228,15 @@
|
||||
suspend(self);
|
||||
}
|
||||
|
||||
- if (THREAD_GETMEM(self, p_condvar_avail) == 0
|
||||
+ if ((THREAD_GETMEM(self, p_condvar_avail) & CVA_AVAIL) == 0
|
||||
&& (THREAD_GETMEM(self, p_woken_by_cancel) == 0
|
||||
|| THREAD_GETMEM(self, p_cancelstate) != PTHREAD_CANCEL_ENABLE))
|
||||
{
|
||||
+ if ((THREAD_GETMEM(self, p_condvar_avail) &
|
||||
+ CVA_EXTRA_RESTART) == 0 &&
|
||||
+ !__compare_and_swap(&self->p_condvar_avail,
|
||||
+ 0, CVA_EXTRA_RESTART))
|
||||
+ break; /* CVA_AVAIL set by other thread */
|
||||
/* Count resumes that don't belong to us. */
|
||||
spurious_wakeup_count++;
|
||||
continue;
|
||||
@@ -215,15 +252,35 @@
|
||||
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);
|
||||
+ if (THREAD_GETMEM(self, p_condwait_mutex) == NULL) {
|
||||
+ if ((THREAD_GETMEM(self, p_condvar_avail) & CVA_EXTRA_RESTART) != 0) {
|
||||
+ if (spurious_wakeup_count > 0)
|
||||
+ spurious_wakeup_count--;
|
||||
+ else
|
||||
+ suspend(self);
|
||||
+ }
|
||||
+ __pthread_mutex_condwait_completelock(mutex);
|
||||
+ } else
|
||||
+ pthread_mutex_lock(mutex);
|
||||
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
|
||||
}
|
||||
|
||||
+ if (THREAD_GETMEM(self, p_condwait_mutex) == NULL &&
|
||||
+ (THREAD_GETMEM(self, p_condvar_avail) & CVA_EXTRA_RESTART) != 0) {
|
||||
+ if (spurious_wakeup_count > 0)
|
||||
+ spurious_wakeup_count--;
|
||||
+ else
|
||||
+ suspend(self);
|
||||
+ }
|
||||
+
|
||||
/* Put back any resumes we caught that don't belong to us. */
|
||||
while (spurious_wakeup_count--)
|
||||
restart(self);
|
||||
|
||||
- pthread_mutex_lock(mutex);
|
||||
+ if (THREAD_GETMEM(self, p_condwait_mutex) == NULL)
|
||||
+ __pthread_mutex_condwait_completelock(mutex);
|
||||
+ else
|
||||
+ pthread_mutex_lock(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -237,14 +294,34 @@
|
||||
int pthread_cond_signal(pthread_cond_t *cond)
|
||||
{
|
||||
pthread_descr th;
|
||||
+ long oldcva;
|
||||
|
||||
__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);
|
||||
+ pthread_mutex_t *mutex = th->p_condwait_mutex;
|
||||
+ if ((th->p_condvar_avail & CVA_AVAIL) == 0 &&
|
||||
+ mutex != NULL &&
|
||||
+ (mutex->__m_kind == PTHREAD_MUTEX_ERRORCHECK_NP ||
|
||||
+ mutex->__m_kind == PTHREAD_MUTEX_TIMED_NP) &&
|
||||
+ __pthread_alt_condwait_queuelock(&mutex->__m_lock, th) == 0) {
|
||||
+ th->p_condwait_mutex = NULL;
|
||||
+ WRITE_MEMORY_BARRIER();
|
||||
+ do {
|
||||
+ READ_MEMORY_BARRIER();
|
||||
+ oldcva = th->p_condvar_avail;
|
||||
+ } while (!__compare_and_swap(&th->p_condvar_avail,
|
||||
+ oldcva,
|
||||
+ oldcva | CVA_AVAIL));
|
||||
+ WRITE_MEMORY_BARRIER();
|
||||
+ if ((oldcva & CVA_EXTRA_RESTART) != 0)
|
||||
+ restart(th);
|
||||
+ } else {
|
||||
+ th->p_condvar_avail = CVA_AVAIL;
|
||||
+ WRITE_MEMORY_BARRIER();
|
||||
+ restart(th);
|
||||
+ }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -252,6 +329,7 @@
|
||||
int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
{
|
||||
pthread_descr tosignal, th;
|
||||
+ long oldcva;
|
||||
|
||||
__pthread_lock(&cond->__c_lock, NULL);
|
||||
/* Copy the current state of the waiting queue and empty it */
|
||||
@@ -260,9 +338,28 @@
|
||||
__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);
|
||||
+ pthread_mutex_t *mutex = th->p_condwait_mutex;
|
||||
+ if ((th->p_condvar_avail & CVA_AVAIL) == 0 &&
|
||||
+ mutex != NULL &&
|
||||
+ (mutex->__m_kind == PTHREAD_MUTEX_ERRORCHECK_NP ||
|
||||
+ mutex->__m_kind == PTHREAD_MUTEX_TIMED_NP) &&
|
||||
+ __pthread_alt_condwait_queuelock(&mutex->__m_lock, th) == 0) {
|
||||
+ th->p_condwait_mutex = NULL;
|
||||
+ WRITE_MEMORY_BARRIER();
|
||||
+ do {
|
||||
+ READ_MEMORY_BARRIER();
|
||||
+ oldcva = th->p_condvar_avail;
|
||||
+ } while (!__compare_and_swap(&th->p_condvar_avail,
|
||||
+ oldcva,
|
||||
+ oldcva | CVA_AVAIL));
|
||||
+ WRITE_MEMORY_BARRIER();
|
||||
+ if ((oldcva & CVA_EXTRA_RESTART) != 0)
|
||||
+ restart(th);
|
||||
+ } else {
|
||||
+ th->p_condvar_avail = CVA_AVAIL;
|
||||
+ WRITE_MEMORY_BARRIER();
|
||||
+ restart(th);
|
||||
+ }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Only in .: condvar.c~
|
||||
diff -ru ../../work.nc/linuxthreads-2.2.3_19/internals.h ./internals.h
|
||||
--- ../../work.nc/linuxthreads-2.2.3_19/internals.h Tue Jan 10 17:13:14 2006
|
||||
+++ ./internals.h Tue Jan 10 17:33:30 2006
|
||||
@@ -125,6 +125,13 @@
|
||||
int pr_lock_count;
|
||||
} pthread_readlock_info;
|
||||
|
||||
+
|
||||
+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 */
|
||||
+};
|
||||
+
|
||||
struct _pthread_descr_struct {
|
||||
union {
|
||||
struct {
|
||||
@@ -176,7 +183,7 @@
|
||||
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 */
|
||||
+ long 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 */
|
||||
@@ -189,6 +196,8 @@
|
||||
hp_timing_t p_cpuclock_offset; /* Initial CPU clock for thread. */
|
||||
#endif
|
||||
/* New elements must be added at the end. */
|
||||
+ pthread_mutex_t *p_condwait_mutex;
|
||||
+ struct wait_node p_condwait_waitnode;
|
||||
} __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.
|
||||
Only in .: internals.h~
|
||||
diff -ru ../../work.nc/linuxthreads-2.2.3_19/mutex.c ./mutex.c
|
||||
--- ../../work.nc/linuxthreads-2.2.3_19/mutex.c Sun Jan 7 05:35:20 2001
|
||||
+++ ./mutex.c Tue Jan 10 17:13:46 2006
|
||||
@@ -92,6 +92,24 @@
|
||||
}
|
||||
strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)
|
||||
|
||||
+int __pthread_mutex_condwait_completelock(pthread_mutex_t *mutex)
|
||||
+{
|
||||
+ pthread_descr self;
|
||||
+
|
||||
+ switch(mutex->__m_kind) {
|
||||
+ case PTHREAD_MUTEX_ERRORCHECK_NP:
|
||||
+ self = thread_self();
|
||||
+ if (mutex->__m_owner == self) return EDEADLK;
|
||||
+ mutex->__m_owner = self;
|
||||
+ return 0;
|
||||
+ case PTHREAD_MUTEX_TIMED_NP:
|
||||
+ return 0;
|
||||
+ default:
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
int __pthread_mutex_lock(pthread_mutex_t * mutex)
|
||||
{
|
||||
pthread_descr self;
|
||||
diff -ru ../../work.nc/linuxthreads-2.2.3_19/spinlock.c ./spinlock.c
|
||||
--- ../../work.nc/linuxthreads-2.2.3_19/spinlock.c Tue Jan 10 17:13:14 2006
|
||||
+++ ./spinlock.c Tue Jan 10 17:13:46 2006
|
||||
@@ -231,12 +231,6 @@
|
||||
*/
|
||||
|
||||
|
||||
-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;
|
||||
@@ -359,6 +353,55 @@
|
||||
}
|
||||
|
||||
#endif
|
||||
+
|
||||
+int __pthread_alt_condwait_queuelock(struct _pthread_fastlock * lock,
|
||||
+ pthread_descr th)
|
||||
+{
|
||||
+#if defined HAS_COMPARE_AND_SWAP
|
||||
+ long oldstatus, newstatus;
|
||||
+#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);
|
||||
+
|
||||
+ if (lock->__status == 0) {
|
||||
+ WRITE_MEMORY_BARRIER();
|
||||
+ lock->__spinlock = __LT_SPINLOCK_INIT;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ th->p_condwait_waitnode.abandoned = 0;
|
||||
+ th->p_condwait_waitnode.next = (struct wait_node *) lock->__status;
|
||||
+ th->p_condwait_waitnode.thr = th;
|
||||
+ lock->__status = (long) &th->p_condwait_waitnode;
|
||||
+
|
||||
+ WRITE_MEMORY_BARRIER();
|
||||
+ lock->__spinlock = __LT_SPINLOCK_INIT;
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+#if defined HAS_COMPARE_AND_SWAP
|
||||
+ do {
|
||||
+ oldstatus = lock->__status;
|
||||
+ if (oldstatus == 0) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+ th->p_condwait_waitnode.thr = th;
|
||||
+ newstatus = (long) &th->p_condwait_waitnode;
|
||||
+ th->p_condwait_waitnode.abandoned = 0;
|
||||
+ th->p_condwait_waitnode.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));
|
||||
+ return 0;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
|
||||
void __pthread_alt_lock(struct _pthread_fastlock * lock,
|
||||
pthread_descr self)
|
||||
diff -ru ../../work.nc/linuxthreads-2.2.3_19/spinlock.h ./spinlock.h
|
||||
--- ../../work.nc/linuxthreads-2.2.3_19/spinlock.h Tue Jan 10 17:13:14 2006
|
||||
+++ ./spinlock.h Tue Jan 10 17:13:46 2006
|
||||
@@ -130,6 +130,9 @@
|
||||
timed-out waits. Warning: do not mix these operations with the above ones
|
||||
over the same lock object! */
|
||||
|
||||
+extern int __pthread_alt_condwait_queuelock(struct _pthread_fastlock * lock,
|
||||
+ pthread_descr th);
|
||||
+
|
||||
extern void __pthread_alt_lock(struct _pthread_fastlock * lock,
|
||||
pthread_descr self);
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
#include <poll.h>
|
||||
#include <bits/local_lim.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sched.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
|
||||
#if __FreeBSD__ >= 5
|
||||
#define __libc_accept __sys_accept
|
||||
#define __libc_close __sys_close
|
||||
#define __libc_connect __sys_connect
|
||||
#define __libc_fcntl __sys_fcntl
|
||||
#define __libc_fork __sys_fork
|
||||
#define __libc_fsync __sys_fsync
|
||||
#define __libc_nanosleep __sys_nanosleep
|
||||
#define __libc_open __sys_open
|
||||
#define __libc_read __sys_read
|
||||
#define __libc_waitpid __waitpid
|
||||
#define __libc_write __sys_write
|
||||
#define __libc_longjmp __longjmp
|
||||
#define __libc_siglongjmp __siglongjmp
|
||||
#define __libc_msync __sys_msync
|
||||
#define __libc_recvfrom __sys_recvfrom
|
||||
#define __libc_recvmsg __sys_recvmsg
|
||||
#define __libc_sendmsg __sys_sendmsg
|
||||
#define __libc_sendto __sys_sendto
|
||||
#define __libc_sigaction __sys_sigaction
|
||||
#define __libc_poll __sys_poll
|
||||
#define __libc_getpid __sys_getpid
|
||||
#else
|
||||
#define __libc_accept _accept
|
||||
#define __libc_close _close
|
||||
#define __libc_connect _connect
|
||||
#define __libc_fcntl _fcntl
|
||||
#define __libc_fork _fork
|
||||
#define __libc_fsync _fsync
|
||||
#define __libc_nanosleep _nanosleep
|
||||
#define __libc_open _open
|
||||
#define __libc_read _read
|
||||
#define __libc_waitpid __waitpid
|
||||
#define __libc_write _write
|
||||
#define __libc_longjmp __longjmp
|
||||
#define __libc_siglongjmp __siglongjmp
|
||||
#define __libc_msync _msync
|
||||
#define __libc_recvfrom _recvfrom
|
||||
#define __libc_recvmsg _recvmsg
|
||||
#define __libc_sendmsg _sendmsg
|
||||
#define __libc_sendto _sendto
|
||||
#define __libc_sigaction _sigaction
|
||||
#define __libc_poll _poll
|
||||
#define __libc_getpid _getpid
|
||||
#endif
|
||||
#define __libc_wait __wait
|
||||
#define __libc_system __system
|
||||
#define __getpid __libc_getpid
|
||||
#define __poll __libc_poll
|
||||
#define __libc_tcdrain __tcdrain
|
||||
#define __libc_pause __pause
|
||||
#define __libc_current_sigrtmin current_sigrtmin
|
||||
#define __libc_current_sigrtmax current_sigrtmax
|
||||
#define __libc_allocate_rtsig allocate_rtsig
|
||||
#define __getpagesize getpagesize
|
||||
int __sched_setparam(pid_t, const struct sched_param *);
|
||||
int __sched_getparam(pid_t, struct sched_param *);
|
||||
int __sched_setscheduler(pid_t, int, const struct sched_param *);
|
||||
int __sched_getscheduler(pid_t);
|
||||
int __sched_yield(void);
|
||||
int __sched_get_priority_max(int);
|
||||
int __sched_get_priority_min(int);
|
||||
int __sched_rr_get_interval(pid_t, struct timespec *);
|
||||
#define __gettimeofday _gettimeofday
|
||||
#define __jmp_buf jmp_buf
|
||||
#define _h_errno h_errno
|
||||
#define __ptr_t void *
|
||||
#define __pid_t pid_t
|
||||
|
||||
ssize_t __libc_write(int, const void *, size_t);
|
||||
ssize_t __libc_read(int, void *, size_t);
|
||||
pid_t __libc_waitpid(pid_t wpid, int *status, int options);
|
||||
int __libc_poll(struct pollfd *_pfd, unsigned int _nfsd, int _timeout);
|
||||
pid_t __libc_getpid(void);
|
||||
pid_t __libc_waitpid(pid_t, int *, int);
|
||||
int __libc_sigaction(int, const struct sigaction *, struct sigaction *);
|
||||
int __libc_fcntl(int, int, ...);
|
||||
int __libc_fsync(int);
|
||||
int __libc_msync(void *, size_t, int);
|
||||
int __libc_open(const char *, int, ...);
|
||||
int __libc_pause(void);
|
||||
ssize_t __libc_pwrite(int, const void *, size_t, off_t);
|
||||
ssize_t __libc_pread(int, void *, size_t, off_t);
|
||||
int __libc_tcdrain(int);
|
||||
pid_t __libc_wait(int *);
|
||||
int __libc_system(const char *);
|
||||
int __libc_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int __libc_connect(int, const struct sockaddr *, socklen_t);
|
||||
ssize_t __libc_recvfrom(int, void *, size_t, int, struct sockaddr *,
|
||||
socklen_t *);
|
||||
ssize_t __libc_recvmsg(int, struct msghdr *, int);
|
||||
ssize_t __libc_sendmsg(int, const struct msghdr *, int);
|
||||
ssize_t __libc_sendto(int, const void *,
|
||||
size_t, int, const struct sockaddr *, socklen_t);
|
||||
|
||||
#ifndef __P
|
||||
# define __P(args) args
|
||||
#endif
|
||||
|
||||
#ifndef __THROW
|
||||
#define __THROW
|
||||
#endif
|
||||
|
||||
#ifndef __restrict
|
||||
#define __restrict
|
||||
#endif
|
||||
|
||||
#define SHLIB_COMPAT(lib, old, new) 0
|
||||
|
||||
#define versioned_symbol(libname, realname, aliasname, libver) __strong_reference(realname,aliasname)
|
||||
|
||||
#define link_warning(symbol, warning) __warn_references(symbol, warning);
|
||||
|
||||
#ifndef __PMT
|
||||
# define __PMT(args) args
|
||||
#endif
|
||||
|
||||
# define strong_alias(name, aliasname) \
|
||||
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
|
||||
|
||||
# define weak_alias(name, aliasname) \
|
||||
extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
|
||||
|
||||
#define ENOTSUP EOPNOTSUPP
|
||||
|
||||
#define __builtin_expect(x,y) (x)
|
||||
#define internal_function
|
||||
|
||||
|
||||
#undef PAGE_SIZE
|
||||
#define PAGE_SIZE getpagesize()
|
||||
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#define MAP_GROWSDOWN MAP_STACK
|
||||
|
||||
#define __WCLONE WLINUXCLONE
|
||||
|
||||
#define SIGCONTEXT struct sigcontext *
|
||||
#define SIGCONTEXT_EXTRA_ARGS
|
||||
|
||||
# define __WAIT_STATUS_DEFN int *
|
||||
|
||||
# define __SOCKADDR_ARG struct sockaddr *
|
||||
# define __CONST_SOCKADDR_ARG __const struct sockaddr *
|
||||
|
||||
#define __ptr_t void *
|
||||
#define __pid_t pid_t
|
||||
|
||||
/* Test if longjmp to JMPBUF would unwind the frame
|
||||
containing a local variable at ADDRESS. */
|
||||
|
||||
/* XXXX check this for FreeBSD */
|
||||
/* i386 only */
|
||||
#define JB_SP 2
|
||||
#define _JMPBUF_UNWINDS(jmpbuf, address) \
|
||||
((void *) (address) < (void *) ((int *)(jmpbuf[0]._jb[JB_SP]))[1])
|
||||
|
||||
#define spinlock_t int
|
||||
#define _SPINLOCK_INITIALIZER 0
|
||||
#define _SPINLOCK(x) __pthread_acquire(x)
|
||||
#define _SPINUNLOCK(x) *(x) = 0
|
||||
/*#define TEST_FOR_COMPARE_AND_SWAP*/
|
||||
|
||||
#define __set_errno(val) errno = (val)
|
||||
|
||||
#define DEFAULT_PRIORITY 20
|
||||
|
||||
void __libc_longjmp __P((jmp_buf, int)) __dead2;
|
||||
void __libc_siglongjmp __P((sigjmp_buf, int)) __dead2;
|
||||
|
||||
int _gettimeofday __P((struct timeval *, struct timezone *));
|
||||
pid_t _getpid __P((void));
|
||||
int _sigaction __P((int, const struct sigaction *, struct sigaction *));
|
||||
int _poll __P((struct pollfd *_pfd, unsigned _nfds, int _timeout));
|
||||
|
||||
#include "clone.h"
|
||||
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1999 Richard Seaman, Jr.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Richard Seaman, Jr.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY RICHARD SEAMAN, Jr. AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include "pthread.h"
|
||||
|
||||
static pthread_mutex_t getgr_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int
|
||||
convert (struct group *ret, struct group *result,
|
||||
char *buf, int buflen)
|
||||
{
|
||||
int len;
|
||||
int count;
|
||||
char **gr_mem;
|
||||
char *buf1;
|
||||
|
||||
if (!buf) return -1;
|
||||
|
||||
*result = *ret;
|
||||
|
||||
result->gr_name = (char *) buf;
|
||||
/* This is the size. */
|
||||
len = strlen (ret->gr_name) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
strcpy (result->gr_name, ret->gr_name);
|
||||
|
||||
result->gr_passwd = (char *) buf;
|
||||
/* This is the size. */
|
||||
len = strlen (ret->gr_passwd) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
strcpy (result->gr_passwd, ret->gr_passwd);
|
||||
|
||||
count = 0;
|
||||
gr_mem = ret->gr_mem;
|
||||
while (*gr_mem){
|
||||
count++;
|
||||
gr_mem++;
|
||||
}
|
||||
len = sizeof (*gr_mem)*(count+1);
|
||||
if (len > buflen) return -1;
|
||||
buf1 = buf;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
gr_mem = ret->gr_mem;
|
||||
while (*gr_mem){
|
||||
len = strlen (*gr_mem) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buf1 = buf;
|
||||
strcpy (buf, *gr_mem);
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
buf1 += sizeof (buf1);
|
||||
gr_mem++;
|
||||
}
|
||||
buf1 = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getgrnam_r (const char *name, struct group *result,
|
||||
char *buffer, size_t buflen,
|
||||
struct group ** resptr)
|
||||
{
|
||||
struct group * p;
|
||||
int retval;
|
||||
|
||||
pthread_mutex_lock (&getgr_mutex);
|
||||
p = getgrnam (name);
|
||||
if (p == NULL) {
|
||||
*resptr = NULL;
|
||||
retval = ESRCH;
|
||||
} else
|
||||
if (convert (p, result, buffer, buflen) != 0) {
|
||||
*resptr = NULL;
|
||||
retval = ERANGE;
|
||||
} else {
|
||||
*resptr = result;
|
||||
retval = 0;
|
||||
}
|
||||
pthread_mutex_unlock (&getgr_mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int getgrgid_r (uid_t uid, struct group *result,
|
||||
char *buffer, size_t buflen,
|
||||
struct group ** resptr)
|
||||
{
|
||||
struct group * p;
|
||||
int retval;
|
||||
|
||||
pthread_mutex_lock (&getgr_mutex);
|
||||
p = getgrgid (uid);
|
||||
if (p == NULL) {
|
||||
*resptr = NULL;
|
||||
retval = ESRCH;
|
||||
} else
|
||||
if (convert (p, result, buffer, buflen) != 0) {
|
||||
*resptr = NULL;
|
||||
retval = ERANGE;
|
||||
} else {
|
||||
*resptr = result;
|
||||
retval = 0;
|
||||
}
|
||||
pthread_mutex_unlock (&getgr_mutex);
|
||||
return retval;
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
#include "pthread.h"
|
||||
#include <netdb.h>
|
||||
#include <osreldate.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __sparc__
|
||||
#define NEED_ALIGNED_ACCESS
|
||||
#endif
|
||||
|
||||
#if __FreeBSD_version < 502104
|
||||
|
||||
static pthread_mutex_t gethostby_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int
|
||||
convert (struct hostent *host, struct hostent *result,
|
||||
char *buf, int buflen, int *h_errnop)
|
||||
{
|
||||
int len, i;
|
||||
|
||||
if (!buf || !h_errnop) return -1;
|
||||
*h_errnop = h_errno;
|
||||
|
||||
*result = *host;
|
||||
result->h_name = (char *) buf;
|
||||
/* This is the size. */
|
||||
len = strlen (host->h_name) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
strcpy ((char *) result->h_name, host->h_name);
|
||||
|
||||
/* How many aliases and how big the buffer should be? There
|
||||
is always a NULL pointer. */
|
||||
for (len = sizeof (char *), i = 0; host->h_aliases [i]; i++)
|
||||
{
|
||||
/* It should be size of (char *) and the length of string
|
||||
plus 1. */
|
||||
len += strlen (host->h_aliases [i]) + 1 + sizeof (char *);
|
||||
}
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
|
||||
/* This is an array of char * for h_aliases. */
|
||||
#ifdef NEED_ALIGNED_ACCESS
|
||||
{
|
||||
int extra;
|
||||
extra = 4 - (((unsigned long) buf) & 3);
|
||||
if (extra != 4) {
|
||||
if (buflen < extra)
|
||||
return -1;
|
||||
buf = (char *) buf + extra;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
result->h_aliases = (char **) buf;
|
||||
buf += (i + 1) * sizeof (char *);
|
||||
|
||||
/* We copy the aliases now. */
|
||||
for (i = 0; host->h_aliases [i]; i++)
|
||||
{
|
||||
result->h_aliases [i] = (char *) buf;
|
||||
strcpy (result->h_aliases [i], host->h_aliases [i]);
|
||||
buf += strlen (host->h_aliases [i]) + 1;
|
||||
}
|
||||
/* This is the last one */
|
||||
result->h_aliases [i] = NULL;
|
||||
|
||||
#if BSD >= 43 || defined(h_addr)
|
||||
for (len = sizeof (char *), i = 0; host->h_addr_list [i]; i++)
|
||||
{
|
||||
/* It should be size of (char *) and the length of string
|
||||
plus 1. */
|
||||
len += host->h_length + sizeof (char *);
|
||||
}
|
||||
if (len > buflen) return -1;
|
||||
|
||||
/* This is an array of char * for h_addr_list. */
|
||||
#ifdef NEED_ALIGNED_ACCESS
|
||||
{
|
||||
int extra;
|
||||
extra = 4 - (((unsigned long) buf) & 0x3);
|
||||
if (extra != 4) {
|
||||
if (buflen < extra)
|
||||
return -1;
|
||||
buf = ((char *) buf) + extra;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
result->h_addr_list = (char **) buf;
|
||||
buf += (i + 1) * sizeof (char *);
|
||||
|
||||
/* We copy the h_addr_list now. */
|
||||
for (i = 0; host->h_addr_list [i]; i++)
|
||||
{
|
||||
result->h_addr_list [i] = (char *) buf;
|
||||
memcpy (result->h_addr_list [i], host->h_addr_list [i], host->h_length);
|
||||
buf += host->h_length;
|
||||
}
|
||||
/* This is the last one */
|
||||
result->h_addr_list [i] = NULL;
|
||||
#else
|
||||
len = strlen (host->h_addr) + 1 + sizeof (char *);
|
||||
if (len > buflen) return -1;
|
||||
|
||||
result->h_addr = (char *) buf;
|
||||
strcpy (result->h_addr, host->h_addr);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if __FreeBSD__ < 5 || __FreeBSD_version >= 501101
|
||||
struct hostent *
|
||||
gethostbyaddr_r (const char *addr, int length, int type,
|
||||
struct hostent *result, char *buffer, int buflen,
|
||||
int *h_errnop)
|
||||
{
|
||||
struct hostent *host;
|
||||
|
||||
pthread_mutex_lock (&gethostby_mutex);
|
||||
|
||||
host = gethostbyaddr (addr, length, type);
|
||||
if (!host ||
|
||||
convert (host, result, buffer, buflen, h_errnop) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&gethostby_mutex);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct hostent *
|
||||
gethostbyname_r (const char *name,
|
||||
struct hostent *result, char *buffer, int buflen,
|
||||
int *h_errnop)
|
||||
{
|
||||
struct hostent *host;
|
||||
|
||||
pthread_mutex_lock (&gethostby_mutex);
|
||||
|
||||
host = gethostbyname (name);
|
||||
if (!host ||
|
||||
convert (host, result, buffer, buflen, h_errnop) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&gethostby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostent_r (struct hostent *result, char *buffer, int buflen,
|
||||
int *h_errnop)
|
||||
{
|
||||
struct hostent *host;
|
||||
|
||||
pthread_mutex_lock (&gethostby_mutex);
|
||||
|
||||
host = gethostent ();
|
||||
if (!host ||
|
||||
convert (host, result, buffer, buflen, h_errnop) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&gethostby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* #if __FreeBSD_version < 502104 */
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/lib/libc/gen/getlogin.c,v 1.4.2.1 2001/03/05 09:06:50 obrien Exp $
|
||||
*/
|
||||
|
||||
#if __FreeBSD__ < 5
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getlogin.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <utmp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef _THREAD_SAFE
|
||||
#define THREAD_LOCK()
|
||||
#define THREAD_UNLOCK()
|
||||
#else
|
||||
#include <pthread.h>
|
||||
extern int __isthreaded;
|
||||
static pthread_mutex_t logname_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define THREAD_LOCK() if (__isthreaded) pthread_mutex_lock(&logname_mutex)
|
||||
#define THREAD_UNLOCK() if (__isthreaded) pthread_mutex_unlock(&logname_mutex)
|
||||
#endif /* _THREAD_SAFE */
|
||||
|
||||
int _logname_valid; /* known to setlogin() */
|
||||
int _getlogin(char *, unsigned int);
|
||||
|
||||
static char *
|
||||
getlogin_basic(int *status)
|
||||
{
|
||||
static char logname[MAXLOGNAME];
|
||||
|
||||
if (_logname_valid == 0) {
|
||||
#ifdef __NETBSD_SYSCALLS
|
||||
if (__getlogin(logname, sizeof(logname) - 1) < 0) {
|
||||
#else
|
||||
if (_getlogin(logname, sizeof(logname)) < 0) {
|
||||
#endif
|
||||
*status = errno;
|
||||
return (NULL);
|
||||
}
|
||||
_logname_valid = 1;
|
||||
}
|
||||
*status = 0;
|
||||
return (*logname ? logname : NULL);
|
||||
}
|
||||
|
||||
char *
|
||||
getlogin(void)
|
||||
{
|
||||
char *result;
|
||||
int status;
|
||||
|
||||
THREAD_LOCK();
|
||||
result = getlogin_basic(&status);
|
||||
THREAD_UNLOCK();
|
||||
return (result);
|
||||
}
|
||||
|
||||
int
|
||||
getlogin_r(char *logname, int namelen)
|
||||
{
|
||||
char *result;
|
||||
int len;
|
||||
int status;
|
||||
|
||||
THREAD_LOCK();
|
||||
result = getlogin_basic(&status);
|
||||
if (status == 0) {
|
||||
if ((len = strlen(result) + 1) > namelen)
|
||||
status = ERANGE;
|
||||
else
|
||||
strncpy(logname, result, len);
|
||||
}
|
||||
THREAD_UNLOCK();
|
||||
return (status);
|
||||
}
|
||||
#endif /* __FreeBSD__ < 5 */
|
|
@ -1,111 +0,0 @@
|
|||
#include "pthread.h"
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#if (__FreeBSD_version >= 700000 && __FreeBSD_version < 700016) || \
|
||||
__FreeBSD_version < 601103
|
||||
|
||||
static pthread_mutex_t getnetby_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int
|
||||
convert (struct netent *ret, struct netent *result,
|
||||
char *buf, int buflen)
|
||||
{
|
||||
int len, i;
|
||||
|
||||
if (!buf) return -1;
|
||||
|
||||
*result = *ret;
|
||||
result->n_name = (char *) buf;
|
||||
/* This is the size. */
|
||||
len = strlen (ret->n_name) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
strcpy (result->n_name, ret->n_name);
|
||||
|
||||
/* How many aliases and how big the buffer should be? There
|
||||
is always a NULL pointer. */
|
||||
for (len = sizeof (char *), i = 0; ret->n_aliases [i]; i++)
|
||||
{
|
||||
/* It should be size of (char *) and the length of string
|
||||
plus 1. */
|
||||
len += strlen (ret->n_aliases [i]) + 1 + sizeof (char *);
|
||||
}
|
||||
if (len > buflen) return -1;
|
||||
|
||||
/* This is an array of char * for n_aliases. */
|
||||
result->n_aliases = (char **) buf;
|
||||
buf += (i + 1) * sizeof (char *);
|
||||
|
||||
/* We copy the aliases now. */
|
||||
for (i = 0; ret->n_aliases [i]; i++)
|
||||
{
|
||||
result->n_aliases [i] = (char *) buf;
|
||||
strcpy (result->n_aliases [i], ret->n_aliases [i]);
|
||||
buf += strlen (ret->n_aliases [i]) + 1;
|
||||
}
|
||||
/* This is the last one */
|
||||
result->n_aliases [i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr_r (long net, int type,
|
||||
struct netent *result, char *buffer, int buflen)
|
||||
{
|
||||
struct netent *ret;
|
||||
|
||||
pthread_mutex_lock (&getnetby_mutex);
|
||||
|
||||
ret = getnetbyaddr (net, type);
|
||||
if (!ret ||
|
||||
convert (ret, result, buffer, buflen) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&getnetby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyname_r (const char *name,
|
||||
struct netent *result, char *buffer, int buflen)
|
||||
{
|
||||
struct netent *ret;
|
||||
|
||||
pthread_mutex_lock (&getnetby_mutex);
|
||||
|
||||
ret = getnetbyname (name);
|
||||
if (!ret ||
|
||||
convert (ret, result, buffer, buflen) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&getnetby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetent_r (struct netent *result, char *buffer, int buflen)
|
||||
{
|
||||
struct netent *ret;
|
||||
|
||||
pthread_mutex_lock (&getnetby_mutex);
|
||||
|
||||
ret = getnetent ();
|
||||
if (!ret ||
|
||||
convert (ret, result, buffer, buflen) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&getnetby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* #if __FreeBSD_version < 601103 */
|
|
@ -1,111 +0,0 @@
|
|||
#include "pthread.h"
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#if (__FreeBSD_version >= 700000 && __FreeBSD_version < 700016) || \
|
||||
__FreeBSD_version < 601103
|
||||
|
||||
static pthread_mutex_t getprotoby_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int
|
||||
convert (struct protoent *ret, struct protoent *result,
|
||||
char *buf, int buflen)
|
||||
{
|
||||
int len, i;
|
||||
|
||||
if (!buf) return -1;
|
||||
|
||||
*result = *ret;
|
||||
result->p_name = (char *) buf;
|
||||
/* This is the size. */
|
||||
len = strlen (ret->p_name) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
strcpy (result->p_name, ret->p_name);
|
||||
|
||||
/* How many aliases and how big the buffer should be? There
|
||||
is always a NULL pointer. */
|
||||
for (len = sizeof (char *), i = 0; ret->p_aliases [i]; i++)
|
||||
{
|
||||
/* It should be size of (char *) and the length of string
|
||||
plus 1. */
|
||||
len += strlen (ret->p_aliases [i]) + 1 + sizeof (char *);
|
||||
}
|
||||
if (len > buflen) return -1;
|
||||
|
||||
/* This is an array of char * for p_aliases. */
|
||||
result->p_aliases = (char **) buf;
|
||||
buf += (i + 1) * sizeof (char *);
|
||||
|
||||
/* We copy the aliases now. */
|
||||
for (i = 0; ret->p_aliases [i]; i++)
|
||||
{
|
||||
result->p_aliases [i] = (char *) buf;
|
||||
strcpy (result->p_aliases [i], ret->p_aliases [i]);
|
||||
buf += strlen (ret->p_aliases [i]) + 1;
|
||||
}
|
||||
/* This is the last one */
|
||||
result->p_aliases [i] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobynumber_r (int proto,
|
||||
struct protoent *result, char *buffer, int buflen)
|
||||
{
|
||||
struct protoent *ret;
|
||||
|
||||
pthread_mutex_lock (&getprotoby_mutex);
|
||||
|
||||
ret = getprotobynumber (proto);
|
||||
if (!ret ||
|
||||
convert (ret, result, buffer, buflen) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&getprotoby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobyname_r (const char *name,
|
||||
struct protoent *result, char *buffer, int buflen)
|
||||
{
|
||||
struct protoent *ret;
|
||||
|
||||
pthread_mutex_lock (&getprotoby_mutex);
|
||||
|
||||
ret = getprotobyname (name);
|
||||
if (!ret ||
|
||||
convert (ret, result, buffer, buflen) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&getprotoby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotoent_r (struct protoent *result, char *buffer, int buflen)
|
||||
{
|
||||
struct protoent *ret;
|
||||
|
||||
pthread_mutex_lock (&getprotoby_mutex);
|
||||
|
||||
ret = getprotoent ();
|
||||
if (!ret ||
|
||||
convert (ret, result, buffer, buflen) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&getprotoby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* #if __FreeBSD_version < 601103 */
|
|
@ -1,111 +0,0 @@
|
|||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <osreldate.h>
|
||||
#include "pthread.h"
|
||||
|
||||
#if __FreeBSD_version < 500112
|
||||
static pthread_mutex_t getpw_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int
|
||||
convert (struct passwd *ret, struct passwd *result,
|
||||
char *buf, int buflen)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (!buf) return -1;
|
||||
|
||||
*result = *ret;
|
||||
|
||||
result->pw_name = (char *) buf;
|
||||
/* This is the size. */
|
||||
len = strlen (ret->pw_name) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
strcpy (result->pw_name, ret->pw_name);
|
||||
|
||||
result->pw_passwd = (char *) buf;
|
||||
/* This is the size. */
|
||||
len = strlen (ret->pw_passwd) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
strcpy (result->pw_passwd, ret->pw_passwd);
|
||||
|
||||
result->pw_gecos = (char *) buf;
|
||||
/* This is the size. */
|
||||
len = strlen (ret->pw_gecos) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
strcpy (result->pw_gecos, ret->pw_gecos);
|
||||
|
||||
result->pw_dir = (char *) buf;
|
||||
/* This is the size. */
|
||||
len = strlen (ret->pw_dir) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
strcpy (result->pw_dir, ret->pw_dir);
|
||||
|
||||
result->pw_shell = (char *) buf;
|
||||
/* This is the size. */
|
||||
len = strlen (ret->pw_shell) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
buf += len;
|
||||
strcpy (result->pw_shell, ret->pw_shell);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getpwnam_r (const char *name, struct passwd *result,
|
||||
char *buffer, size_t buflen,
|
||||
struct passwd ** resptr)
|
||||
{
|
||||
struct passwd * p;
|
||||
int retval;
|
||||
|
||||
pthread_mutex_lock (&getpw_mutex);
|
||||
p = getpwnam (name);
|
||||
if (p == NULL) {
|
||||
*resptr = NULL;
|
||||
retval = ESRCH;
|
||||
} else
|
||||
if (convert (p, result, buffer, buflen) != 0) {
|
||||
*resptr = NULL;
|
||||
retval = ERANGE;
|
||||
} else {
|
||||
*resptr = result;
|
||||
retval = 0;
|
||||
}
|
||||
pthread_mutex_unlock (&getpw_mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int getpwuid_r (uid_t uid, struct passwd *result,
|
||||
char *buffer, size_t buflen,
|
||||
struct passwd ** resptr)
|
||||
{
|
||||
struct passwd * p;
|
||||
int retval;
|
||||
|
||||
pthread_mutex_lock (&getpw_mutex);
|
||||
p = getpwuid (uid);
|
||||
if (p == NULL) {
|
||||
*resptr = NULL;
|
||||
retval = ESRCH;
|
||||
} else
|
||||
if (convert (p, result, buffer, buflen) != 0) {
|
||||
*resptr = NULL;
|
||||
retval = ERANGE;
|
||||
} else {
|
||||
*resptr = result;
|
||||
retval = 0;
|
||||
}
|
||||
pthread_mutex_unlock (&getpw_mutex);
|
||||
return retval;
|
||||
}
|
||||
#endif
|
|
@ -1,119 +0,0 @@
|
|||
#include "pthread.h"
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#if (__FreeBSD_version >= 700000 && __FreeBSD_version < 700016) || \
|
||||
__FreeBSD_version < 601103
|
||||
|
||||
static pthread_mutex_t getservby_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static int
|
||||
convert (struct servent *ret, struct servent *result,
|
||||
char *buf, int buflen)
|
||||
{
|
||||
int len, i;
|
||||
|
||||
if (!buf) return -1;
|
||||
|
||||
*result = *ret;
|
||||
/* This is the size. */
|
||||
len = strlen (ret->s_name) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
result->s_name = (char *) buf;
|
||||
buf += len;
|
||||
strcpy (result->s_name, ret->s_name);
|
||||
|
||||
/* How many aliases and how big the buffer should be? There
|
||||
is always a NULL pointer. */
|
||||
for (len = sizeof (char *), i = 0; ret->s_aliases [i]; i++)
|
||||
{
|
||||
/* It should be size of (char *) and the length of string
|
||||
plus 1. */
|
||||
len += strlen (ret->s_aliases [i]) + 1 + sizeof (char *);
|
||||
}
|
||||
if (len > buflen) return -1;
|
||||
buflen -= len;
|
||||
|
||||
/* This is an array of char * for s_aliases. */
|
||||
result->s_aliases = (char **) buf;
|
||||
buf += (i + 1) * sizeof (char *);
|
||||
|
||||
/* We copy the aliases now. */
|
||||
for (i = 0; ret->s_aliases [i]; i++)
|
||||
{
|
||||
result->s_aliases [i] = (char *) buf;
|
||||
strcpy (result->s_aliases [i], ret->s_aliases [i]);
|
||||
buf += strlen (ret->s_aliases [i]) + 1;
|
||||
}
|
||||
/* This is the last one */
|
||||
result->s_aliases [i] = NULL;
|
||||
|
||||
/* s_proto */
|
||||
len = strlen (ret->s_proto) + 1;
|
||||
if (len > buflen) return -1;
|
||||
buf += len;
|
||||
result->s_proto = (char *) buf;
|
||||
strcpy (result->s_proto, ret->s_proto);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyport_r (int port, const char *proto,
|
||||
struct servent *result, char *buffer, int buflen)
|
||||
{
|
||||
struct servent *ret;
|
||||
|
||||
pthread_mutex_lock (&getservby_mutex);
|
||||
|
||||
ret = getservbyport (port, proto);
|
||||
if (!ret ||
|
||||
convert (ret, result, buffer, buflen) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&getservby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyname_r (const char *name, const char *proto,
|
||||
struct servent *result, char *buffer, int buflen)
|
||||
{
|
||||
struct servent *ret;
|
||||
|
||||
pthread_mutex_lock (&getservby_mutex);
|
||||
|
||||
ret = getservbyname (name, proto);
|
||||
if (!ret ||
|
||||
convert (ret, result, buffer, buflen) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&getservby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservent_r (struct servent *result, char *buffer, int buflen)
|
||||
{
|
||||
struct servent *ret;
|
||||
|
||||
pthread_mutex_lock (&getservby_mutex);
|
||||
|
||||
ret = getservent ();
|
||||
if (!ret ||
|
||||
convert (ret, result, buffer, buflen) != 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&getservby_mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* #if __FreeBSD_version < 601103 */
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1999 Richard Seaman, Jr.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Richard Seaman, Jr.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY RICHARD SEAMAN, Jr. AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <errno.h>
|
||||
#include <clone.h>
|
||||
|
||||
int clone (int (*__fn) (void *), void *__child_stack,
|
||||
int __flags, void *__arg) __attribute__ ((weak, alias("__clone")));
|
||||
|
||||
extern int __clone (int (*__fn) (void *), void *__child_stack,
|
||||
int __flags, void *__arg)
|
||||
{
|
||||
int bsd_flags;
|
||||
int exit_signal;
|
||||
|
||||
/* We don't have qn equivalent to CLONE_PID yet */
|
||||
if (__flags & CLONE_PID)
|
||||
return (-1);
|
||||
|
||||
if (__child_stack == (void *)0)
|
||||
return (-1);
|
||||
|
||||
/* RFTHREAD probably not necessary here, but it shouldn't hurt either */
|
||||
bsd_flags = RFPROC | RFTHREAD;
|
||||
|
||||
/* We only allow one alternative to SIGCHLD, and thats
|
||||
* SIGUSR1. This is less flexible than Linux, but
|
||||
* we don't really have a way to pass a one byte
|
||||
* exit signal to rfork, which is what Linux passes to
|
||||
* its clone syscall. OTOH, we haven't seen Linux use
|
||||
* a value other than 0 (which implies SIGCHLD), SIGCHLD,
|
||||
* or SIGUSER1 so far.
|
||||
*/
|
||||
exit_signal = ((unsigned int)__flags) & CSIGNAL;
|
||||
switch (exit_signal){
|
||||
case 0:
|
||||
case SIGCHLD:
|
||||
/* SIGCHLD is the default for BSD, so we don't have
|
||||
* to do anything special in this case.
|
||||
*/
|
||||
break;
|
||||
case SIGUSR1:
|
||||
bsd_flags |= RFLINUXTHPN;
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (__flags & CLONE_VM)
|
||||
bsd_flags |= RFMEM;
|
||||
if (__flags & CLONE_SIGHAND)
|
||||
bsd_flags |= RFSIGSHARE;
|
||||
if (!(__flags & CLONE_FILES))
|
||||
bsd_flags |= RFFDG;
|
||||
|
||||
/* _clone is in clone.S, and takes bsd style rfork flags */
|
||||
return (_clone (__fn, __child_stack, bsd_flags, __arg));
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# Gross hack. Wrapper for ld that renames various functions to avoid
|
||||
# conflicts between linuxthreads and native threads
|
||||
#
|
||||
echo "[ldwrap $@]"
|
||||
if test "$1" = "-o" -a "$2" != "wraputhread.o.tmp" -a "$2" != "wraputhread.Po.tmp" -a "$2" != "wraputhread.So.tmp"
|
||||
then
|
||||
target=$2
|
||||
shift
|
||||
shift
|
||||
ld -o $target.tmp "$@"
|
||||
objcopy \
|
||||
--redefine-sym _pthread_cleanup_pop=linuxthreads__pthread_cleanup_pop \
|
||||
--redefine-sym _pthread_cleanup_pop_restore=linuxthreads__pthread_cleanup_pop_restore \
|
||||
--redefine-sym _pthread_cleanup_push=linuxthreads__pthread_cleanup_push \
|
||||
--redefine-sym _pthread_cleanup_push_defer=linuxthreads__pthread_cleanup_push_defer \
|
||||
--redefine-sym pthread_atfork=linuxthreads_pthread_atfork \
|
||||
--redefine-sym pthread_attr_destroy=linuxthreads_pthread_attr_destroy \
|
||||
--redefine-sym pthread_attr_getdetachstate=linuxthreads_pthread_attr_getdetachstate \
|
||||
--redefine-sym pthread_attr_getguardsize=linuxthreads_pthread_attr_getguardsize \
|
||||
--redefine-sym pthread_attr_getinheritsched=linuxthreads_pthread_attr_getinheritsched \
|
||||
--redefine-sym pthread_attr_getschedparam=linuxthreads_pthread_attr_getschedparam \
|
||||
--redefine-sym pthread_attr_getschedpolicy=linuxthreads_pthread_attr_getschedpolicy \
|
||||
--redefine-sym pthread_attr_getscope=linuxthreads_pthread_attr_getscope \
|
||||
--redefine-sym pthread_attr_getstack=linuxthreads_pthread_attr_getstack \
|
||||
--redefine-sym pthread_attr_getstackaddr=linuxthreads_pthread_attr_getstackaddr \
|
||||
--redefine-sym pthread_attr_getstacksize=linuxthreads_pthread_attr_getstacksize \
|
||||
--redefine-sym pthread_attr_init=linuxthreads_pthread_attr_init \
|
||||
--redefine-sym pthread_attr_setdetachstate=linuxthreads_pthread_attr_setdetachstate \
|
||||
--redefine-sym pthread_attr_setguardsize=linuxthreads_pthread_attr_setguardsize \
|
||||
--redefine-sym pthread_attr_setinheritsched=linuxthreads_pthread_attr_setinheritsched \
|
||||
--redefine-sym pthread_attr_setschedparam=linuxthreads_pthread_attr_setschedparam \
|
||||
--redefine-sym pthread_attr_setschedpolicy=linuxthreads_pthread_attr_setschedpolicy \
|
||||
--redefine-sym pthread_attr_setscope=linuxthreads_pthread_attr_setscope \
|
||||
--redefine-sym pthread_attr_setstack=linuxthreads_pthread_attr_setstack \
|
||||
--redefine-sym pthread_attr_setstackaddr=linuxthreads_pthread_attr_setstackaddr \
|
||||
--redefine-sym pthread_attr_setstacksize=linuxthreads_pthread_attr_setstacksize \
|
||||
--redefine-sym pthread_barrier_destroy=linuxthreads_pthread_barrier_destroy \
|
||||
--redefine-sym pthread_barrier_init=linuxthreads_pthread_barrier_init \
|
||||
--redefine-sym pthread_barrier_wait=linuxthreads_pthread_barrier_wait \
|
||||
--redefine-sym pthread_barrierattr_destroy=linuxthreads_pthread_barrierattr_destroy \
|
||||
--redefine-sym pthread_barrierattr_getpshared=linuxthreads_pthread_barrierattr_getpshared \
|
||||
--redefine-sym pthread_barrierattr_init=linuxthreads_pthread_barrierattr_init \
|
||||
--redefine-sym pthread_barrierattr_setpshared=linuxthreads_pthread_barrierattr_setpshared \
|
||||
--redefine-sym pthread_cancel=linuxthreads_pthread_cancel \
|
||||
--redefine-sym pthread_cond_broadcast=linuxthreads_pthread_cond_broadcast \
|
||||
--redefine-sym pthread_cond_destroy=linuxthreads_pthread_cond_destroy \
|
||||
--redefine-sym pthread_cond_init=linuxthreads_pthread_cond_init \
|
||||
--redefine-sym pthread_cond_signal=linuxthreads_pthread_cond_signal \
|
||||
--redefine-sym pthread_cond_timedwait=linuxthreads_pthread_cond_timedwait \
|
||||
--redefine-sym pthread_cond_wait=linuxthreads_pthread_cond_wait \
|
||||
--redefine-sym pthread_condattr_destroy=linuxthreads_pthread_condattr_destroy \
|
||||
--redefine-sym pthread_condattr_getpshared=linuxthreads_pthread_condattr_getpshared \
|
||||
--redefine-sym pthread_condattr_init=linuxthreads_pthread_condattr_init \
|
||||
--redefine-sym pthread_condattr_setpshared=linuxthreads_pthread_condattr_setpshared \
|
||||
--redefine-sym pthread_create=linuxthreads_pthread_create \
|
||||
--redefine-sym pthread_detach=linuxthreads_pthread_detach \
|
||||
--redefine-sym pthread_equal=linuxthreads_pthread_equal \
|
||||
--redefine-sym pthread_exit=linuxthreads_pthread_exit \
|
||||
--redefine-sym pthread_getattr_np=linuxthreads_pthread_getattr_np \
|
||||
--redefine-sym pthread_getconcurrency=linuxthreads_pthread_getconcurrency \
|
||||
--redefine-sym pthread_getcpuclockid=linuxthreads_pthread_getcpuclockid \
|
||||
--redefine-sym pthread_getschedparam=linuxthreads_pthread_getschedparam \
|
||||
--redefine-sym pthread_getspecific=linuxthreads_pthread_getspecific \
|
||||
--redefine-sym pthread_join=linuxthreads_pthread_join \
|
||||
--redefine-sym pthread_key_create=linuxthreads_pthread_key_create \
|
||||
--redefine-sym pthread_key_delete=linuxthreads_pthread_key_delete \
|
||||
--redefine-sym pthread_kill=linuxthreads_pthread_kill \
|
||||
--redefine-sym pthread_kill_other_threads_np=linuxthreads_pthread_kill_other_threads_np \
|
||||
--redefine-sym pthread_mutex_destroy=linuxthreads_pthread_mutex_destroy \
|
||||
--redefine-sym pthread_mutex_init=linuxthreads_pthread_mutex_init \
|
||||
--redefine-sym pthread_mutex_lock=linuxthreads_pthread_mutex_lock \
|
||||
--redefine-sym pthread_mutex_timedlock=linuxthreads_pthread_mutex_timedlock \
|
||||
--redefine-sym pthread_mutex_trylock=linuxthreads_pthread_mutex_trylock \
|
||||
--redefine-sym pthread_mutex_unlock=linuxthreads_pthread_mutex_unlock \
|
||||
--redefine-sym pthread_mutexattr_destroy=linuxthreads_pthread_mutexattr_destroy \
|
||||
--redefine-sym pthread_mutexattr_getpshared=linuxthreads_pthread_mutexattr_getpshared \
|
||||
--redefine-sym pthread_mutexattr_gettype=linuxthreads_pthread_mutexattr_gettype \
|
||||
--redefine-sym pthread_mutexattr_init=linuxthreads_pthread_mutexattr_init \
|
||||
--redefine-sym pthread_mutexattr_setpshared=linuxthreads_pthread_mutexattr_setpshared \
|
||||
--redefine-sym pthread_mutexattr_settype=linuxthreads_pthread_mutexattr_settype \
|
||||
--redefine-sym pthread_once=linuxthreads_pthread_once \
|
||||
--redefine-sym pthread_rwlock_destroy=linuxthreads_pthread_rwlock_destroy \
|
||||
--redefine-sym pthread_rwlock_init=linuxthreads_pthread_rwlock_init \
|
||||
--redefine-sym pthread_rwlock_rdlock=linuxthreads_pthread_rwlock_rdlock \
|
||||
--redefine-sym pthread_rwlock_timedrdlock=linuxthreads_pthread_rwlock_timedrdlock \
|
||||
--redefine-sym pthread_rwlock_timedwrlock=linuxthreads_pthread_rwlock_timedwrlock \
|
||||
--redefine-sym pthread_rwlock_tryrdlock=linuxthreads_pthread_rwlock_tryrdlock \
|
||||
--redefine-sym pthread_rwlock_trywrlock=linuxthreads_pthread_rwlock_trywrlock \
|
||||
--redefine-sym pthread_rwlock_unlock=linuxthreads_pthread_rwlock_unlock \
|
||||
--redefine-sym pthread_rwlock_wrlock=linuxthreads_pthread_rwlock_wrlock \
|
||||
--redefine-sym pthread_rwlockattr_destroy=linuxthreads_pthread_rwlockattr_destroy \
|
||||
--redefine-sym pthread_rwlockattr_getkind_np=linuxthreads_pthread_rwlockattr_getkind_np \
|
||||
--redefine-sym pthread_rwlockattr_getpshared=linuxthreads_pthread_rwlockattr_getpshared \
|
||||
--redefine-sym pthread_rwlockattr_init=linuxthreads_pthread_rwlockattr_init \
|
||||
--redefine-sym pthread_rwlockattr_setkind_np=linuxthreads_pthread_rwlockattr_setkind_np \
|
||||
--redefine-sym pthread_rwlockattr_setpshared=linuxthreads_pthread_rwlockattr_setpshared \
|
||||
--redefine-sym pthread_self=linuxthreads_pthread_self \
|
||||
--redefine-sym pthread_setcancelstate=linuxthreads_pthread_setcancelstate \
|
||||
--redefine-sym pthread_setcanceltype=linuxthreads_pthread_setcanceltype \
|
||||
--redefine-sym pthread_setconcurrency=linuxthreads_pthread_setconcurrency \
|
||||
--redefine-sym pthread_setschedparam=linuxthreads_pthread_setschedparam \
|
||||
--redefine-sym pthread_setspecific=linuxthreads_pthread_setspecific \
|
||||
--redefine-sym pthread_sigmask=linuxthreads_pthread_sigmask \
|
||||
--redefine-sym pthread_spin_destroy=linuxthreads_pthread_spin_destroy \
|
||||
--redefine-sym pthread_spin_init=linuxthreads_pthread_spin_init \
|
||||
--redefine-sym pthread_spin_lock=linuxthreads_pthread_spin_lock \
|
||||
--redefine-sym pthread_spin_trylock=linuxthreads_pthread_spin_trylock \
|
||||
--redefine-sym pthread_spin_unlock=linuxthreads_pthread_spin_unlock \
|
||||
--redefine-sym pthread_testcancel=linuxthreads_pthread_testcancel \
|
||||
--redefine-sym pthread_yield=linuxthreads_pthread_yield \
|
||||
$target.tmp $target
|
||||
rm -f $target.tmp
|
||||
else
|
||||
exec ld "$@"
|
||||
fi
|
|
@ -1,157 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1998 Richard Seaman, Jr.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Richard Seaman, Jr.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY RICHARD SEAMAN, Jr. AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _THREAD_SAFE
|
||||
#define _THREAD_SAFE
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/ttycom.h>
|
||||
#include <osreldate.h>
|
||||
#include <time.h>
|
||||
#include "pthread.h"
|
||||
#include "internals.h"
|
||||
|
||||
#ifndef NEWLIBC
|
||||
|
||||
char * asctime (const struct tm *timeptr)
|
||||
{
|
||||
pthread_descr self = thread_self();
|
||||
|
||||
return (asctime_r(timeptr, self->time_buf));
|
||||
}
|
||||
|
||||
char * ctime(const time_t * const timep)
|
||||
{
|
||||
pthread_descr self = thread_self();
|
||||
|
||||
return (ctime_r(timep, self->time_buf));
|
||||
}
|
||||
|
||||
|
||||
struct tm *localtime (const time_t * const timep)
|
||||
{
|
||||
pthread_descr self = thread_self();
|
||||
|
||||
return (localtime_r(timep, &self->local_tm));
|
||||
}
|
||||
|
||||
struct tm * gmtime(const time_t * const timep)
|
||||
{
|
||||
pthread_descr self = thread_self();
|
||||
|
||||
return (gmtime_r(timep, &self->local_tm));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The following wrappers impement cancallation points */
|
||||
|
||||
|
||||
#if __STDC__
|
||||
int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
|
||||
#else
|
||||
int msgrcv(msqid, msgp, msgsz, msgtyp, msgflg)
|
||||
int msqid;
|
||||
void *msgp;
|
||||
size_t msgsz;
|
||||
long msgtyp;
|
||||
int msgflg;
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
int oldtype;
|
||||
|
||||
/* This is a cancellation point */
|
||||
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
|
||||
|
||||
ret = msgsys(3, msqid, msgp, msgsz, msgtyp, msgflg);
|
||||
|
||||
/* This is a cancellation point */
|
||||
pthread_setcanceltype (oldtype, NULL);
|
||||
return (ret);
|
||||
|
||||
}
|
||||
|
||||
#if __STDC__
|
||||
#if __FreeBSD_version > 500100
|
||||
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
|
||||
#else
|
||||
int msgsnd(int msqid, void *msgp, size_t msgsz, int msgflg)
|
||||
#endif
|
||||
#else
|
||||
int msgsnd(msqid, msgp, msgsz, msgflg)
|
||||
int msqid;
|
||||
#if __FreeBSD_version > 500100
|
||||
const void *msgp;
|
||||
#else
|
||||
void *msgp;
|
||||
#endif
|
||||
size_t msgsz;
|
||||
int msgflg;
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
int oldtype;
|
||||
|
||||
/* This is a cancellation point */
|
||||
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
|
||||
|
||||
ret = msgsys(2, msqid, msgp, msgsz, msgflg);
|
||||
|
||||
/* This is a cancellation point */
|
||||
pthread_setcanceltype (oldtype, NULL);
|
||||
return (ret);
|
||||
|
||||
}
|
||||
|
||||
#if __STDC__
|
||||
int tcdrain (int fd)
|
||||
#else
|
||||
int tcdrain (fd)
|
||||
int fd;
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
int oldtype;
|
||||
|
||||
/* This is a cancellation point */
|
||||
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
|
||||
|
||||
ret = ioctl(fd, TIOCDRAIN, 0);
|
||||
|
||||
/* This is a cancellation point */
|
||||
pthread_setcanceltype (oldtype, NULL);
|
||||
return (ret);
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1999 Richard Seaman, Jr.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Richard Seaman, Jr.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY RICHARD SEAMAN, Jr. AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _THREAD_SAFE
|
||||
#define _THREAD_SAFE
|
||||
#endif
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
#include "pthread.h"
|
||||
/* Our internal pthreads definitions are here. Set as needed */
|
||||
#if defined(COMPILING_UTHREADS)
|
||||
#include "pthread_private.h"
|
||||
#endif
|
||||
#if defined(LINUXTHREADS)
|
||||
#include <errno.h>
|
||||
#include "internals.h"
|
||||
#include "spinlock.h"
|
||||
#else
|
||||
/* Your internal definition here */
|
||||
#endif
|
||||
|
||||
/* These are from lib/libc/include */
|
||||
#if !defined(LINUXTHREADS)
|
||||
#include "spinlock.h"
|
||||
#endif
|
||||
|
||||
/* This is defined in lib/libc/stdlib/exit.c. It turns on thread safe
|
||||
* behavior in libc if non-zero.
|
||||
*/
|
||||
extern int __isthreaded;
|
||||
|
||||
/* Optional. In case our code is dependant on the existence of
|
||||
* the posix priority extentions kernel option.
|
||||
*/
|
||||
#if defined(LINUXTHREADS)
|
||||
#include <sys/sysctl.h>
|
||||
int _posix_priority_scheduling;
|
||||
#endif
|
||||
|
||||
void *lock_create (void *context);
|
||||
void rlock_acquire (void *lock);
|
||||
void wlock_acquire (void *lock);
|
||||
void lock_release (void *lock);
|
||||
void lock_destroy (void *lock);
|
||||
|
||||
|
||||
/* Use the constructor attribute so this gets run before main does */
|
||||
static void _pthread_initialize(void) __attribute__((constructor));
|
||||
|
||||
static void _pthread_initialize(void)
|
||||
{
|
||||
|
||||
#if defined(LINUXTHREADS)
|
||||
#if !defined(LINUXTHREADS_NO_POSIX_PRIORITY_SCHEDULING)
|
||||
int mib[2];
|
||||
size_t len;
|
||||
|
||||
len = sizeof (_posix_priority_scheduling);
|
||||
mib[0] = CTL_P1003_1B;
|
||||
mib[1] = CTL_P1003_1B_PRIORITY_SCHEDULING;
|
||||
if (-1 == sysctl (mib, 2, &_posix_priority_scheduling, &len, NULL, 0))
|
||||
_posix_priority_scheduling = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This turns on thread safe behaviour in libc when we link with it */
|
||||
__isthreaded = 1;
|
||||
|
||||
}
|
||||
|
||||
void _spinlock (int * spinlock)
|
||||
{
|
||||
__pthread_acquire(spinlock);
|
||||
}
|
||||
|
||||
|
||||
void _spinunlock(int *spinlock)
|
||||
{
|
||||
*spinlock = 0;
|
||||
}
|
||||
|
||||
void * lock_create (void *context)
|
||||
{
|
||||
pthread_rwlock_t *lock;
|
||||
|
||||
lock = malloc (sizeof (*lock));
|
||||
if (lock == NULL)
|
||||
return (NULL);
|
||||
|
||||
pthread_rwlock_init (lock, NULL);
|
||||
return (lock);
|
||||
}
|
||||
|
||||
void rlock_acquire (void *lock)
|
||||
{
|
||||
pthread_rwlock_rdlock ((pthread_rwlock_t *)lock);
|
||||
|
||||
}
|
||||
|
||||
void wlock_acquire (void *lock)
|
||||
{
|
||||
pthread_rwlock_wrlock ((pthread_rwlock_t *)lock);
|
||||
|
||||
}
|
||||
|
||||
void lock_release (void *lock)
|
||||
{
|
||||
pthread_rwlock_unlock ((pthread_rwlock_t *)lock);
|
||||
}
|
||||
|
||||
void lock_destroy (void *lock)
|
||||
{
|
||||
if (pthread_rwlock_destroy ((pthread_rwlock_t *)lock) == 0)
|
||||
free (lock);
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,21 +0,0 @@
|
|||
--- internals.h.orig Tue May 16 00:23:50 2006
|
||||
+++ internals.h Tue May 16 00:24:21 2006
|
||||
@@ -395,12 +395,14 @@
|
||||
#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). Some
|
||||
- architectures distinguish between full, read and write barriers. */
|
||||
+/* 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()
|
||||
+#define MEMORY_BARRIER() asm ("" : : : "memory")
|
||||
#endif
|
||||
#ifndef READ_MEMORY_BARRIER
|
||||
#define READ_MEMORY_BARRIER() MEMORY_BARRIER()
|
|
@ -1,149 +0,0 @@
|
|||
diff -ru ../../work.PRE4/linuxthreads-2.2.3_21/freebsd-compat.h ./freebsd-compat.h
|
||||
--- ../../work.PRE4/linuxthreads-2.2.3_21/freebsd-compat.h Sat Jun 8 20:18:05 2002
|
||||
+++ ./freebsd-compat.h Mon Mar 19 22:31:38 2007
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <sched.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
+#include <sys/errno.h>
|
||||
|
||||
|
||||
#if __FreeBSD__ >= 5
|
||||
@@ -77,6 +78,26 @@
|
||||
|
||||
ssize_t __libc_write(int, const void *, size_t);
|
||||
ssize_t __libc_read(int, void *, size_t);
|
||||
+static inline ssize_t
|
||||
+__libc_safe_write(int fd, const void *buf, size_t wsize)
|
||||
+{
|
||||
+ ssize_t written;
|
||||
+
|
||||
+ do {
|
||||
+ written = __libc_write(fd, buf, wsize);
|
||||
+ } while (written < 0 && errno == EINTR);
|
||||
+ return (written);
|
||||
+}
|
||||
+static inline ssize_t
|
||||
+__libc_safe_read(int fd, void *buf, size_t rsize)
|
||||
+{
|
||||
+ ssize_t got;
|
||||
+
|
||||
+ do {
|
||||
+ got = __libc_read(fd, buf, rsize);
|
||||
+ } while (got < 0 && errno == EINTR);
|
||||
+ return (got);
|
||||
+}
|
||||
pid_t __libc_waitpid(pid_t wpid, int *status, int options);
|
||||
int __libc_poll(struct pollfd *_pfd, unsigned int _nfsd, int _timeout);
|
||||
pid_t __libc_getpid(void);
|
||||
diff -ru ../../work.PRE4/linuxthreads-2.2.3_21/join.c ./join.c
|
||||
--- ../../work.PRE4/linuxthreads-2.2.3_21/join.c Mon Mar 19 22:29:45 2007
|
||||
+++ ./join.c Mon Mar 19 22:33:43 2007
|
||||
@@ -79,7 +79,7 @@
|
||||
if (self == __pthread_main_thread && __pthread_manager_request >= 0) {
|
||||
request.req_thread = self;
|
||||
request.req_kind = REQ_MAIN_THREAD_EXIT;
|
||||
- __libc_write(__pthread_manager_request, (char *)&request, sizeof(request));
|
||||
+ __libc_safe_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
|
||||
@@ -174,7 +174,7 @@
|
||||
request.req_thread = self;
|
||||
request.req_kind = REQ_FREE;
|
||||
request.req_args.free.thread_id = thread_id;
|
||||
- __libc_write(__pthread_manager_request,
|
||||
+ __libc_safe_write(__pthread_manager_request,
|
||||
(char *) &request, sizeof(request));
|
||||
}
|
||||
return 0;
|
||||
@@ -212,7 +212,7 @@
|
||||
request.req_thread = thread_self();
|
||||
request.req_kind = REQ_FREE;
|
||||
request.req_args.free.thread_id = thread_id;
|
||||
- __libc_write(__pthread_manager_request,
|
||||
+ __libc_safe_write(__pthread_manager_request,
|
||||
(char *) &request, sizeof(request));
|
||||
}
|
||||
return 0;
|
||||
diff -ru ../../work.PRE4/linuxthreads-2.2.3_21/manager.c ./manager.c
|
||||
--- ../../work.PRE4/linuxthreads-2.2.3_21/manager.c Mon Mar 19 22:29:45 2007
|
||||
+++ ./manager.c Mon Mar 19 22:33:49 2007
|
||||
@@ -132,7 +132,7 @@
|
||||
/* 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 = __libc_read(reqfd, (char *)&request, sizeof(request));
|
||||
+ n = __libc_safe_read(reqfd, (char *)&request, sizeof(request));
|
||||
ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG);
|
||||
ufd.fd = reqfd;
|
||||
ufd.events = POLLIN;
|
||||
@@ -152,7 +152,7 @@
|
||||
}
|
||||
/* Read and execute request */
|
||||
if (n == 1 && (ufd.revents & POLLIN)) {
|
||||
- n = __libc_read(reqfd, (char *)&request, sizeof(request));
|
||||
+ n = __libc_safe_read(reqfd, (char *)&request, sizeof(request));
|
||||
ASSERT(n == sizeof(request));
|
||||
switch(request.req_kind) {
|
||||
case REQ_CREATE:
|
||||
@@ -268,7 +268,7 @@
|
||||
if (__pthread_threads_debug && __pthread_sig_debug > 0) {
|
||||
request.req_thread = self;
|
||||
request.req_kind = REQ_DEBUG;
|
||||
- __libc_write(__pthread_manager_request,
|
||||
+ __libc_safe_write(__pthread_manager_request,
|
||||
(char *) &request, sizeof(request));
|
||||
suspend(self);
|
||||
}
|
||||
@@ -917,7 +917,7 @@
|
||||
struct pthread_request request;
|
||||
request.req_thread = 0;
|
||||
request.req_kind = REQ_KICK;
|
||||
- __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
|
||||
+ __libc_safe_write(__pthread_manager_request, (char *) &request, sizeof(request));
|
||||
}
|
||||
}
|
||||
|
||||
diff -ru ../../work.PRE4/linuxthreads-2.2.3_21/pthread.c ./pthread.c
|
||||
--- ../../work.PRE4/linuxthreads-2.2.3_21/pthread.c Mon Mar 19 22:29:45 2007
|
||||
+++ ./pthread.c Mon Mar 19 22:34:57 2007
|
||||
@@ -605,7 +605,7 @@
|
||||
}
|
||||
/* Synchronize debugging of the thread manager */
|
||||
request.req_kind = REQ_DEBUG;
|
||||
- __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
|
||||
+ __libc_safe_write(__pthread_manager_request, (char *) &request, sizeof(request));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -627,7 +627,7 @@
|
||||
request.req_args.create.arg = arg;
|
||||
sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
|
||||
&request.req_args.create.mask);
|
||||
- __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
|
||||
+ __libc_safe_write(__pthread_manager_request, (char *) &request, sizeof(request));
|
||||
suspend(self);
|
||||
retval = THREAD_GETMEM(self, p_retcode);
|
||||
if (__builtin_expect (retval, 0) == 0)
|
||||
@@ -759,7 +759,7 @@
|
||||
request.req_thread = self;
|
||||
request.req_kind = REQ_PROCESS_EXIT;
|
||||
request.req_args.exit.code = 0;
|
||||
- __libc_write(__pthread_manager_request,
|
||||
+ __libc_safe_write(__pthread_manager_request,
|
||||
(char *) &request, sizeof(request));
|
||||
suspend(self);
|
||||
/* Main thread should accumulate times for thread manager and its
|
||||
diff -ru ../../work.PRE4/linuxthreads-2.2.3_21/semaphore.c ./semaphore.c
|
||||
--- ../../work.PRE4/linuxthreads-2.2.3_21/semaphore.c Mon Mar 19 22:29:45 2007
|
||||
+++ ./semaphore.c Mon Mar 19 22:34:21 2007
|
||||
@@ -167,7 +167,7 @@
|
||||
}
|
||||
request.req_kind = REQ_POST;
|
||||
request.req_args.post = sem;
|
||||
- __libc_write(__pthread_manager_request,
|
||||
+ __libc_safe_write(__pthread_manager_request,
|
||||
(char *) &request, sizeof(request));
|
||||
}
|
||||
return 0;
|
|
@ -1,59 +0,0 @@
|
|||
--- spinlock.c.orig Tue Mar 27 04:52:56 2001
|
||||
+++ spinlock.c Tue Jan 10 09:44:39 2006
|
||||
@@ -72,8 +72,6 @@
|
||||
#endif
|
||||
|
||||
#if defined HAS_COMPARE_AND_SWAP
|
||||
-again:
|
||||
-
|
||||
/* On SMP, try spinning to get the lock. */
|
||||
|
||||
if (__pthread_smp_kernel) {
|
||||
@@ -94,6 +92,8 @@
|
||||
lock->__spinlock += (spin_count - lock->__spinlock) / 8;
|
||||
}
|
||||
|
||||
+again:
|
||||
+
|
||||
/* No luck, try once more or suspend. */
|
||||
|
||||
do {
|
||||
@@ -110,7 +110,7 @@
|
||||
}
|
||||
|
||||
if (self != NULL) {
|
||||
- THREAD_SETMEM(self, p_nextlock, (pthread_descr) (oldstatus & ~1L));
|
||||
+ THREAD_SETMEM(self, p_nextlock, (pthread_descr) oldstatus);
|
||||
/* Make sure the store in p_nextlock completes before performing
|
||||
the compare-and-swap */
|
||||
MEMORY_BARRIER();
|
||||
@@ -188,7 +188,7 @@
|
||||
multiprocessor Alphas) could perform such reordering even though
|
||||
the loads are dependent. */
|
||||
READ_MEMORY_BARRIER();
|
||||
- thr = *ptr;
|
||||
+ thr = (pthread_descr)((long)(thr->p_nextlock) & ~1L);
|
||||
}
|
||||
/* Prevent reordering of the load of lock->__status above and
|
||||
thr->p_nextlock below */
|
||||
@@ -198,17 +198,16 @@
|
||||
/* 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. */
|
||||
+ by clearing the least significant bit. */
|
||||
thr = (pthread_descr) (oldstatus & ~1L);
|
||||
if (! __compare_and_swap_with_release_semantics
|
||||
- (&lock->__status, oldstatus, (long)(thr->p_nextlock)))
|
||||
+ (&lock->__status, oldstatus, (long)(thr->p_nextlock) & ~1L))
|
||||
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;
|
||||
+ thr = (pthread_descr)((long)*maxptr & ~1L);
|
||||
*maxptr = thr->p_nextlock;
|
||||
|
||||
do {
|
|
@ -1,334 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Extensively modified and added to by Richard Seaman, Jr. <dick@tar.com>
|
||||
*
|
||||
*/
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "pthread.h"
|
||||
#include "internals.h"
|
||||
|
||||
int _sched_yield(void);
|
||||
int _sched_setparam(pid_t pid, const struct sched_param *param);
|
||||
int _sched_getparam(pid_t pid, struct sched_param *param);
|
||||
int _sched_setscheduler(pid_t pid, int policy,
|
||||
const struct sched_param *param);
|
||||
int _sched_getscheduler(pid_t pid);
|
||||
int _sched_get_priority_max(int policy);
|
||||
int _sched_get_priority_min(int policy);
|
||||
int _sched_rr_get_interval(pid_t pid, struct timespec *interval);
|
||||
|
||||
int __sched_setparam(pid_t pid, const struct sched_param *param);
|
||||
int __sched_setscheduler(pid_t pid, int policy,
|
||||
const struct sched_param *param);
|
||||
int __sched_getscheduler(pid_t pid);
|
||||
int __sched_get_priority_max(int policy);
|
||||
int __sched_get_priority_min(int policy);
|
||||
int __sched_getparam(pid_t pid, struct sched_param *param);
|
||||
int __sched_rr_get_interval(pid_t pid, struct timespec *interval);
|
||||
|
||||
extern int _posix_priority_scheduling;
|
||||
|
||||
int
|
||||
sched_yield(void)
|
||||
{
|
||||
if (_posix_priority_scheduling)
|
||||
return (_sched_yield());
|
||||
else
|
||||
syscall(SYS_yield);
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_FIXED_SCHED_FUNCTIONS
|
||||
int __sched_setparam(pid_t pid, const struct sched_param *param)
|
||||
{
|
||||
if (_posix_priority_scheduling)
|
||||
return (_sched_setparam(pid, param));
|
||||
else {
|
||||
errno = ENOSYS;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
int __sched_setscheduler(pid_t pid, int policy,
|
||||
const struct sched_param *param)
|
||||
{
|
||||
if (_posix_priority_scheduling) {
|
||||
return (_sched_setscheduler(pid, policy, param));
|
||||
} else {
|
||||
errno = ENOSYS;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
int __sched_getscheduler(pid_t pid)
|
||||
{
|
||||
if (_posix_priority_scheduling) {
|
||||
return (_sched_getscheduler(pid));
|
||||
} else {
|
||||
errno = ENOSYS;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
int __sched_get_priority_max(int policy)
|
||||
{
|
||||
if (_posix_priority_scheduling)
|
||||
return (_sched_get_priority_max (policy));
|
||||
else
|
||||
errno = ENOSYS;
|
||||
return (-1);
|
||||
}
|
||||
int __sched_get_priority_min(int policy)
|
||||
{
|
||||
if (_posix_priority_scheduling)
|
||||
return (_sched_get_priority_min (policy));
|
||||
else
|
||||
errno = ENOSYS;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int __sched_getparam(pid_t pid, struct sched_param *param)
|
||||
{
|
||||
if (_posix_priority_scheduling)
|
||||
return (_sched_getparam(pid, param));
|
||||
else {
|
||||
errno = ENOSYS;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
int __sched_rr_get_interval(pid_t pid, struct timespec *interval)
|
||||
{
|
||||
if (_posix_priority_scheduling)
|
||||
return (_sched_rr_get_interval(pid, interval));
|
||||
else {
|
||||
errno = ENOSYS;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
#include <sys/rtprio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Defines take from sys/posix4/ksched.c */
|
||||
#define p4prio_to_rtpprio(P) (RTP_PRIO_MAX - (P))
|
||||
#define rtpprio_to_p4prio(P) (RTP_PRIO_MAX - (P))
|
||||
#define P1B_PRIO_MIN rtpprio_to_p4prio(RTP_PRIO_MAX)
|
||||
#define P1B_PRIO_MAX rtpprio_to_p4prio(RTP_PRIO_MIN)
|
||||
#define p4prio_to_p_nice(P) (-(P + PRIO_MIN))
|
||||
#define p_nice_to_p4prio(P) (-(P - PRIO_MAX))
|
||||
#define P_NICE_PRIO_MIN p_nice_to_p4prio(PRIO_MAX)
|
||||
#define P_NICE_PRIO_MAX p_nice_to_p4prio(PRIO_MIN)
|
||||
|
||||
int _getpriority __P((int, int));
|
||||
int _setpriority __P((int, int, int));
|
||||
|
||||
int __sched_setparam(pid_t pid, const struct sched_param *param)
|
||||
{
|
||||
int policy = __sched_getscheduler (pid);
|
||||
|
||||
if (policy == -1)
|
||||
return (-1);
|
||||
return (__sched_setscheduler (pid, policy, param));
|
||||
}
|
||||
|
||||
int sched_setparam(pid_t pid, const struct sched_param *param)
|
||||
__attribute__ ((weak, alias("__sched_setparam")));
|
||||
|
||||
int __sched_setscheduler(pid_t pid, int policy,
|
||||
const struct sched_param *param)
|
||||
{
|
||||
struct rtprio rtp;
|
||||
int max, min;
|
||||
int ret;
|
||||
int curtype;
|
||||
|
||||
max = __sched_get_priority_max(policy);
|
||||
if (max == -1)
|
||||
return (-1);
|
||||
min = __sched_get_priority_min(policy);
|
||||
if (min == -1)
|
||||
return (-1);
|
||||
if (param->sched_priority > max ||
|
||||
param->sched_priority < min) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
switch (policy) {
|
||||
case SCHED_FIFO:
|
||||
rtp.type = RTP_PRIO_FIFO;
|
||||
rtp.prio = p4prio_to_rtpprio (param->sched_priority);
|
||||
return (rtprio (RTP_SET, pid, &rtp));
|
||||
|
||||
case SCHED_RR:
|
||||
rtp.type = RTP_PRIO_REALTIME;
|
||||
rtp.prio = p4prio_to_rtpprio (param->sched_priority);
|
||||
return (rtprio (RTP_SET, pid, &rtp));
|
||||
|
||||
case SCHED_OTHER:
|
||||
curtype = __sched_getscheduler (pid);
|
||||
if (curtype != SCHED_OTHER) {
|
||||
rtp.type = RTP_PRIO_NORMAL;
|
||||
rtp.prio = p4prio_to_rtpprio (0);
|
||||
ret = rtprio (RTP_SET, pid, &rtp);
|
||||
if (ret)
|
||||
return (ret);
|
||||
}
|
||||
return (_setpriority (PRIO_PROCESS, pid,
|
||||
p4prio_to_p_nice (param->sched_priority)));
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
int sched_setscheduler(pid_t pid, int policy,
|
||||
const struct sched_param *param)
|
||||
__attribute__ ((weak, alias("__sched_setscheduler")));
|
||||
|
||||
int __sched_getscheduler(pid_t pid)
|
||||
{
|
||||
int ret;
|
||||
struct rtprio rtp;
|
||||
|
||||
ret = rtprio (RTP_LOOKUP, pid, &rtp);
|
||||
if (!ret) {
|
||||
switch (rtp.type) {
|
||||
case RTP_PRIO_FIFO:
|
||||
ret = SCHED_FIFO;
|
||||
break;
|
||||
|
||||
case RTP_PRIO_REALTIME:
|
||||
ret = SCHED_RR;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = SCHED_OTHER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int sched_getscheduler(pid_t pid)
|
||||
__attribute__ ((weak, alias("__sched_getscheduler")));
|
||||
|
||||
int __sched_get_priority_max(int policy)
|
||||
{
|
||||
switch (policy)
|
||||
{
|
||||
case SCHED_FIFO:
|
||||
case SCHED_RR:
|
||||
return (P1B_PRIO_MAX);
|
||||
|
||||
case SCHED_OTHER:
|
||||
return(P_NICE_PRIO_MAX);
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
int sched_get_priority_max(int policy)
|
||||
__attribute__ ((weak, alias("__sched_get_priority_max")));
|
||||
|
||||
int __sched_get_priority_min(int policy)
|
||||
{
|
||||
switch (policy)
|
||||
{
|
||||
case SCHED_FIFO:
|
||||
case SCHED_RR:
|
||||
return (P1B_PRIO_MIN);
|
||||
|
||||
case SCHED_OTHER:
|
||||
return(P_NICE_PRIO_MIN);
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
int sched_get_priority_min(int policy)
|
||||
__attribute__ ((weak, alias("__sched_get_priority_min")));
|
||||
|
||||
|
||||
int __sched_getparam(pid_t pid, struct sched_param *param)
|
||||
{
|
||||
int ret = 0;
|
||||
struct rtprio rtp;
|
||||
|
||||
ret = rtprio (RTP_LOOKUP, pid, &rtp);
|
||||
if (!ret) {
|
||||
switch (rtp.type) {
|
||||
case RTP_PRIO_FIFO:
|
||||
case RTP_PRIO_REALTIME:
|
||||
param->sched_priority = rtpprio_to_p4prio(rtp.prio);
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = 0;
|
||||
ret = _getpriority (PRIO_PROCESS, pid);
|
||||
if (ret == -1 && errno != 0)
|
||||
return (-1);
|
||||
|
||||
param->sched_priority = p_nice_to_p4prio(ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
|
||||
}
|
||||
|
||||
int sched_getparam(pid_t pid, struct sched_param *param)
|
||||
__attribute__ ((weak, alias("__sched_getparam")));
|
||||
|
||||
int __sched_rr_get_interval(pid_t pid, struct timespec *interval)
|
||||
{
|
||||
if (_posix_priority_scheduling)
|
||||
return (_sched_rr_get_interval(pid, interval));
|
||||
else {
|
||||
errno = ENOSYS;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
int sched_rr_get_interval(pid_t pid, struct timespec *interval)
|
||||
__attribute__ ((weak, alias("__sched_rr_get_interval")));
|
||||
|
||||
#endif
|
|
@ -1,9 +0,0 @@
|
|||
1i\
|
||||
#if __FreeBSD__ == 4
|
||||
/.*MUTEX_STATIC.*/d
|
||||
/^#include "pthread_private.h"/d
|
||||
s/\&_gotgmt_mutexd/PTHREAD_MUTEX_INITIALIZER/
|
||||
s/\&logname_lock/PTHREAD_MUTEX_INITIALIZER/
|
||||
s/#include <libc_private.h>/extern int __isthreaded;/
|
||||
$a\
|
||||
#endif /* __FreeBSD__ == 4 */
|
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/lib/libc/gen/telldir.c,v 1.4.12.1 2001/03/05 09:39:59 obrien Exp $
|
||||
*/
|
||||
|
||||
#if __FreeBSD__ < 5
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* The option SINGLEUSE may be defined to say that a telldir
|
||||
* cookie may be used only once before it is freed. This option
|
||||
* is used to avoid having memory usage grow without bound.
|
||||
*/
|
||||
#define SINGLEUSE
|
||||
|
||||
/*
|
||||
* One of these structures is malloced to describe the current directory
|
||||
* position each time telldir is called. It records the current magic
|
||||
* cookie returned by getdirentries and the offset within the buffer
|
||||
* associated with that return value.
|
||||
*/
|
||||
struct ddloc {
|
||||
struct ddloc *loc_next;/* next structure in list */
|
||||
long loc_index; /* key associated with structure */
|
||||
long loc_seek; /* magic cookie returned by getdirentries */
|
||||
long loc_loc; /* offset of entry in buffer */
|
||||
const DIR* loc_dirp; /* directory which used this entry */
|
||||
};
|
||||
|
||||
#define NDIRHASH 32 /* Num of hash lists, must be a power of 2 */
|
||||
#define LOCHASH(i) ((i)&(NDIRHASH-1))
|
||||
|
||||
static long dd_loccnt; /* Index of entry for sequential readdir's */
|
||||
static struct ddloc *dd_hash[NDIRHASH]; /* Hash list heads for ddlocs */
|
||||
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
extern int __isthreaded;
|
||||
static pthread_mutex_t telldir_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define THREAD_LOCK() if (__isthreaded) pthread_mutex_lock(&telldir_mutex)
|
||||
#define THREAD_UNLOCK() if (__isthreaded) pthread_mutex_unlock(&telldir_mutex)
|
||||
#else
|
||||
#define THREAD_LOCK()
|
||||
#define THREAD_UNLOCK()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* return a pointer into a directory
|
||||
*/
|
||||
long
|
||||
telldir(dirp)
|
||||
const DIR *dirp;
|
||||
{
|
||||
int index;
|
||||
struct ddloc *lp;
|
||||
|
||||
if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL)
|
||||
return (-1);
|
||||
THREAD_LOCK();
|
||||
index = dd_loccnt++;
|
||||
lp->loc_index = index;
|
||||
lp->loc_seek = dirp->dd_seek;
|
||||
lp->loc_loc = dirp->dd_loc;
|
||||
lp->loc_dirp = dirp;
|
||||
lp->loc_next = dd_hash[LOCHASH(index)];
|
||||
dd_hash[LOCHASH(index)] = lp;
|
||||
THREAD_UNLOCK();
|
||||
return (index);
|
||||
}
|
||||
|
||||
/*
|
||||
* seek to an entry in a directory.
|
||||
* Only values returned by "telldir" should be passed to seekdir.
|
||||
*/
|
||||
void
|
||||
_seekdir(dirp, loc)
|
||||
DIR *dirp;
|
||||
long loc;
|
||||
{
|
||||
struct ddloc *lp;
|
||||
struct ddloc **prevlp;
|
||||
struct dirent *dp;
|
||||
|
||||
THREAD_LOCK();
|
||||
prevlp = &dd_hash[LOCHASH(loc)];
|
||||
lp = *prevlp;
|
||||
while (lp != NULL) {
|
||||
if (lp->loc_index == loc)
|
||||
break;
|
||||
prevlp = &lp->loc_next;
|
||||
lp = lp->loc_next;
|
||||
}
|
||||
if (lp == NULL) {
|
||||
THREAD_UNLOCK();
|
||||
return;
|
||||
}
|
||||
#ifdef SINGLEUSE
|
||||
*prevlp = lp->loc_next;
|
||||
#endif
|
||||
THREAD_UNLOCK();
|
||||
if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
|
||||
goto found;
|
||||
(void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET);
|
||||
dirp->dd_seek = lp->loc_seek;
|
||||
dirp->dd_loc = 0;
|
||||
while (dirp->dd_loc < lp->loc_loc) {
|
||||
dp = readdir(dirp);
|
||||
if (dp == NULL)
|
||||
break;
|
||||
}
|
||||
found:
|
||||
#ifdef SINGLEUSE
|
||||
free((caddr_t)lp);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim memory for telldir cookies which weren't used.
|
||||
*/
|
||||
void
|
||||
_reclaim_telldir(dirp)
|
||||
const DIR *dirp;
|
||||
{
|
||||
struct ddloc *lp;
|
||||
struct ddloc **prevlp;
|
||||
int i;
|
||||
|
||||
THREAD_LOCK();
|
||||
for (i = 0; i < NDIRHASH; i++) {
|
||||
prevlp = &dd_hash[i];
|
||||
lp = *prevlp;
|
||||
while (lp != NULL) {
|
||||
if (lp->loc_dirp == dirp) {
|
||||
*prevlp = lp->loc_next;
|
||||
free((caddr_t)lp);
|
||||
lp = *prevlp;
|
||||
continue;
|
||||
}
|
||||
prevlp = &lp->loc_next;
|
||||
lp = lp->loc_next;
|
||||
}
|
||||
}
|
||||
THREAD_UNLOCK();
|
||||
}
|
||||
#endif /* __FreeBSD__ < 5 */
|
|
@ -1,215 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/lib/libc/gen/ttyname.c,v 1.10.6.2 2002/10/15 19:46:46 fjoe Exp $
|
||||
*/
|
||||
|
||||
#if __FreeBSD__ < 5
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)ttyname.c 8.2 (Berkeley) 1/27/94";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <db.h>
|
||||
#include <string.h>
|
||||
#include <paths.h>
|
||||
|
||||
#ifdef _THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
static pthread_mutex_t ttyname_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_key_t ttyname_key;
|
||||
static int ttyname_init = 0;
|
||||
char *__ttyname_basic(int fd);
|
||||
|
||||
char *
|
||||
ttyname(int fd)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = __ttyname_basic(fd);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
char *
|
||||
__ttyname_r_basic(int fd, char *buf, size_t len)
|
||||
{
|
||||
register struct dirent *dirp;
|
||||
register DIR *dp;
|
||||
struct stat dsb;
|
||||
struct stat sb;
|
||||
char *rval;
|
||||
int minlen;
|
||||
|
||||
rval = NULL;
|
||||
|
||||
/* Must be a terminal. */
|
||||
if (!isatty(fd))
|
||||
return (rval);
|
||||
/* Must be a character device. */
|
||||
if (fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
|
||||
return (rval);
|
||||
/* Must have enough room */
|
||||
if (len <= sizeof(_PATH_DEV))
|
||||
return (rval);
|
||||
|
||||
if ((dp = opendir(_PATH_DEV)) != NULL) {
|
||||
memcpy(buf, _PATH_DEV, sizeof(_PATH_DEV));
|
||||
for (rval = NULL; (dirp = readdir(dp)) != NULL;) {
|
||||
if (dirp->d_fileno != sb.st_ino)
|
||||
continue;
|
||||
minlen = (len - (sizeof(_PATH_DEV) - 1)) < (dirp->d_namlen + 1) ?
|
||||
(len - (sizeof(_PATH_DEV) - 1)) : (dirp->d_namlen + 1);
|
||||
memcpy(buf + sizeof(_PATH_DEV) - 1, dirp->d_name, minlen);
|
||||
if (stat(buf, &dsb) || sb.st_dev != dsb.st_dev ||
|
||||
sb.st_ino != dsb.st_ino)
|
||||
continue;
|
||||
rval = buf;
|
||||
break;
|
||||
}
|
||||
(void) closedir(dp);
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
char *
|
||||
__ttyname_basic(int fd)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
pthread_mutex_lock(&ttyname_lock);
|
||||
if (ttyname_init == 0) {
|
||||
if (pthread_key_create(&ttyname_key, free)) {
|
||||
pthread_mutex_unlock(&ttyname_lock);
|
||||
return (NULL);
|
||||
}
|
||||
ttyname_init = 1;
|
||||
}
|
||||
pthread_mutex_unlock(&ttyname_lock);
|
||||
|
||||
/* Must have thread specific data field to put data */
|
||||
if ((buf = pthread_getspecific(ttyname_key)) == NULL) {
|
||||
if ((buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) {
|
||||
if (pthread_setspecific(ttyname_key, buf) != 0) {
|
||||
free(buf);
|
||||
return (NULL);
|
||||
}
|
||||
} else {
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
return (__ttyname_r_basic(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN));
|
||||
}
|
||||
|
||||
char *
|
||||
ttyname_r(int fd, char *buf, size_t len)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = __ttyname_r_basic(fd, buf, len);
|
||||
return (ret);
|
||||
}
|
||||
#else
|
||||
static char buf[sizeof(_PATH_DEV) + MAXNAMLEN] = _PATH_DEV;
|
||||
static char *oldttyname __P((int, struct stat *));
|
||||
|
||||
char *
|
||||
ttyname(fd)
|
||||
int fd;
|
||||
{
|
||||
struct stat sb;
|
||||
struct termios ttyb;
|
||||
DB *db;
|
||||
DBT data, key;
|
||||
struct {
|
||||
mode_t type;
|
||||
dev_t dev;
|
||||
} bkey;
|
||||
|
||||
/* Must be a terminal. */
|
||||
if (tcgetattr(fd, &ttyb) < 0)
|
||||
return (NULL);
|
||||
/* Must be a character device. */
|
||||
if (fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
|
||||
return (NULL);
|
||||
|
||||
if ( (db = dbopen(_PATH_DEVDB, O_RDONLY, 0, DB_HASH, NULL)) ) {
|
||||
memset(&bkey, 0, sizeof(bkey));
|
||||
bkey.type = S_IFCHR;
|
||||
bkey.dev = sb.st_rdev;
|
||||
key.data = &bkey;
|
||||
key.size = sizeof(bkey);
|
||||
if (!(db->get)(db, &key, &data, 0)) {
|
||||
bcopy(data.data,
|
||||
buf + sizeof(_PATH_DEV) - 1, data.size);
|
||||
(void)(db->close)(db);
|
||||
return (buf);
|
||||
}
|
||||
(void)(db->close)(db);
|
||||
}
|
||||
return (oldttyname(fd, &sb));
|
||||
}
|
||||
|
||||
static char *
|
||||
oldttyname(fd, sb)
|
||||
int fd;
|
||||
struct stat *sb;
|
||||
{
|
||||
register struct dirent *dirp;
|
||||
register DIR *dp;
|
||||
struct stat dsb;
|
||||
|
||||
if ((dp = opendir(_PATH_DEV)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
while ( (dirp = readdir(dp)) ) {
|
||||
if (dirp->d_fileno != sb->st_ino)
|
||||
continue;
|
||||
bcopy(dirp->d_name, buf + sizeof(_PATH_DEV) - 1,
|
||||
dirp->d_namlen + 1);
|
||||
if (stat(buf, &dsb) || sb->st_dev != dsb.st_dev ||
|
||||
sb->st_ino != dsb.st_ino)
|
||||
continue;
|
||||
(void)closedir(dp);
|
||||
return (buf);
|
||||
}
|
||||
(void)closedir(dp);
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
#endif /* __FreeBSD__ < 5 */
|
|
@ -1,408 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by John Birrell.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: uthread_file.c,v 1.7 1999/06/20 08:28:20 jb Exp $
|
||||
*
|
||||
* POSIX stdio FILE locking functions. These assume that the locking
|
||||
* is only required at FILE structure level, not at file descriptor
|
||||
* level too.
|
||||
*
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "pthread.h"
|
||||
#include "internals.h"
|
||||
#include "spinlock.h"
|
||||
#include "restart.h"
|
||||
|
||||
#if __FreeBSD__ == 4
|
||||
|
||||
/*
|
||||
* Weak symbols for externally visible functions in this file:
|
||||
*/
|
||||
#pragma weak flockfile=_flockfile
|
||||
#pragma weak ftrylockfile=_ftrylockfile
|
||||
#pragma weak funlockfile=_funlockfile
|
||||
|
||||
/*
|
||||
* The FILE lock structure. The FILE *fp is locked if the owner is
|
||||
* not NULL. If not locked, the file lock structure can be
|
||||
* reassigned to a different file by setting fp.
|
||||
*/
|
||||
struct file_lock {
|
||||
LIST_ENTRY(file_lock) entry; /* Entry if file list. */
|
||||
TAILQ_HEAD(lock_head, _pthread_descr_struct)
|
||||
l_head; /* Head of queue for threads */
|
||||
/* waiting on this lock. */
|
||||
FILE *fp; /* The target file. */
|
||||
pthread_descr owner; /* Thread that owns lock. */
|
||||
int count; /* Lock count for owner. */
|
||||
};
|
||||
|
||||
/*
|
||||
* The number of file lock lists into which the file pointer is
|
||||
* hashed. Ideally, the FILE structure size would have been increased,
|
||||
* but this causes incompatibility, so separate data structures are
|
||||
* required.
|
||||
*/
|
||||
#define NUM_HEADS 128
|
||||
|
||||
/*
|
||||
* This macro casts a file pointer to a long integer and right
|
||||
* shifts this by the number of bytes in a pointer. The shifted
|
||||
* value is then remaindered using the maximum number of hash
|
||||
* entries to produce and index into the array of static lock
|
||||
* structures. If there is a collision, a linear search of the
|
||||
* dynamic list of locks linked to each static lock is perfomed.
|
||||
*/
|
||||
#define file_idx(_p) ((((u_long) _p) >> sizeof(void *)) % NUM_HEADS)
|
||||
|
||||
/*
|
||||
* Global array of file locks. The first lock for each hash bucket is
|
||||
* allocated statically in the hope that there won't be too many
|
||||
* collisions that require a malloc and an element added to the list.
|
||||
*/
|
||||
struct static_file_lock {
|
||||
LIST_HEAD(file_list_head, file_lock) head;
|
||||
struct file_lock fl;
|
||||
} flh[NUM_HEADS];
|
||||
|
||||
/* Set to non-zero when initialisation is complete: */
|
||||
static int init_done = 0;
|
||||
|
||||
/* Lock for accesses to the hash table: */
|
||||
static spinlock_t hash_lock = _SPINLOCK_INITIALIZER;
|
||||
|
||||
/*
|
||||
* Find a lock structure for a FILE, return NULL if the file is
|
||||
* not locked:
|
||||
*/
|
||||
static
|
||||
struct file_lock *
|
||||
find_lock(int idx, FILE *fp)
|
||||
{
|
||||
struct file_lock *p;
|
||||
|
||||
/* Check if the file is locked using the static structure: */
|
||||
if (flh[idx].fl.fp == fp && flh[idx].fl.owner != NULL)
|
||||
/* Return a pointer to the static lock: */
|
||||
p = &flh[idx].fl;
|
||||
else {
|
||||
/* Point to the first dynamic lock: */
|
||||
p = flh[idx].head.lh_first;
|
||||
|
||||
/*
|
||||
* Loop through the dynamic locks looking for the
|
||||
* target file:
|
||||
*/
|
||||
while (p != NULL && (p->fp != fp || p->owner == NULL))
|
||||
/* Not this file, try the next: */
|
||||
p = p->entry.le_next;
|
||||
}
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Lock a file, assuming that there is no lock structure currently
|
||||
* assigned to it.
|
||||
*/
|
||||
static
|
||||
struct file_lock *
|
||||
do_lock(int idx, FILE *fp)
|
||||
{
|
||||
struct file_lock *p;
|
||||
|
||||
/* Check if the static structure is not being used: */
|
||||
if (flh[idx].fl.owner == NULL) {
|
||||
/* Return a pointer to the static lock: */
|
||||
p = &flh[idx].fl;
|
||||
}
|
||||
else {
|
||||
/* Point to the first dynamic lock: */
|
||||
p = flh[idx].head.lh_first;
|
||||
|
||||
/*
|
||||
* Loop through the dynamic locks looking for a
|
||||
* lock structure that is not being used:
|
||||
*/
|
||||
while (p != NULL && p->owner != NULL)
|
||||
/* This one is used, try the next: */
|
||||
p = p->entry.le_next;
|
||||
}
|
||||
|
||||
/*
|
||||
* If an existing lock structure has not been found,
|
||||
* allocate memory for a new one:
|
||||
*/
|
||||
if (p == NULL && (p = (struct file_lock *)
|
||||
malloc(sizeof(struct file_lock))) != NULL) {
|
||||
/* Add the new element to the list: */
|
||||
LIST_INSERT_HEAD(&flh[idx].head, p, entry);
|
||||
}
|
||||
|
||||
/* Check if there is a lock structure to acquire: */
|
||||
if (p != NULL) {
|
||||
/* Acquire the lock for the running thread: */
|
||||
p->fp = fp;
|
||||
p->owner = thread_self();
|
||||
p->count = 1;
|
||||
TAILQ_INIT(&p->l_head);
|
||||
}
|
||||
return(p);
|
||||
}
|
||||
|
||||
void
|
||||
_flockfile(FILE * fp)
|
||||
{
|
||||
int idx = file_idx(fp);
|
||||
struct file_lock *p;
|
||||
pthread_descr self = thread_self();
|
||||
|
||||
/* Check if this is a real file: */
|
||||
if (fp->_file >= 0) {
|
||||
/* Lock the hash table: */
|
||||
_SPINLOCK(&hash_lock);
|
||||
|
||||
/* Check if the static array has not been initialised: */
|
||||
if (!init_done) {
|
||||
/* Initialise the global array: */
|
||||
memset(flh,0,sizeof(flh));
|
||||
|
||||
/* Flag the initialisation as complete: */
|
||||
init_done = 1;
|
||||
}
|
||||
|
||||
/* Get a pointer to any existing lock for the file: */
|
||||
if ((p = find_lock(idx, fp)) == NULL) {
|
||||
/*
|
||||
* The file is not locked, so this thread can
|
||||
* grab the lock:
|
||||
*/
|
||||
p = do_lock(idx, fp);
|
||||
|
||||
/* Unlock the hash table: */
|
||||
_SPINUNLOCK(&hash_lock);
|
||||
|
||||
/*
|
||||
* The file is already locked, so check if the
|
||||
* running thread is the owner:
|
||||
*/
|
||||
} else if (p->owner == self) {
|
||||
/*
|
||||
* The running thread is already the
|
||||
* owner, so increment the count of
|
||||
* the number of times it has locked
|
||||
* the file:
|
||||
*/
|
||||
p->count++;
|
||||
|
||||
/* Unlock the hash table: */
|
||||
_SPINUNLOCK(&hash_lock);
|
||||
} else {
|
||||
/*
|
||||
* The file is locked for another thread.
|
||||
* Append this thread to the queue of
|
||||
* threads waiting on the lock.
|
||||
*/
|
||||
TAILQ_INSERT_TAIL(&p->l_head,self,qe);
|
||||
|
||||
/* Unlock the hash table: */
|
||||
_SPINUNLOCK(&hash_lock);
|
||||
|
||||
/* Wait on the FILE lock: */
|
||||
suspend (self);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
_ftrylockfile(FILE * fp)
|
||||
{
|
||||
int ret = -1;
|
||||
int idx = file_idx(fp);
|
||||
struct file_lock *p;
|
||||
pthread_descr self = thread_self();
|
||||
|
||||
/* Check if this is a real file: */
|
||||
if (fp->_file >= 0) {
|
||||
/* Lock the hash table: */
|
||||
_SPINLOCK(&hash_lock);
|
||||
|
||||
/* Get a pointer to any existing lock for the file: */
|
||||
if ((p = find_lock(idx, fp)) == NULL) {
|
||||
/*
|
||||
* The file is not locked, so this thread can
|
||||
* grab the lock:
|
||||
*/
|
||||
p = do_lock(idx, fp);
|
||||
|
||||
/*
|
||||
* The file is already locked, so check if the
|
||||
* running thread is the owner:
|
||||
*/
|
||||
} else if (p->owner == self) {
|
||||
/*
|
||||
* The running thread is already the
|
||||
* owner, so increment the count of
|
||||
* the number of times it has locked
|
||||
* the file:
|
||||
*/
|
||||
p->count++;
|
||||
} else {
|
||||
/*
|
||||
* The file is locked for another thread,
|
||||
* so this try fails.
|
||||
*/
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
/* Check if the lock was obtained: */
|
||||
if (p != NULL)
|
||||
/* Return success: */
|
||||
ret = 0;
|
||||
|
||||
/* Unlock the hash table: */
|
||||
_SPINUNLOCK(&hash_lock);
|
||||
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
_funlockfile(FILE * fp)
|
||||
{
|
||||
int idx = file_idx(fp);
|
||||
struct file_lock *p;
|
||||
pthread_descr self = thread_self();
|
||||
|
||||
/* Check if this is a real file: */
|
||||
if (fp->_file >= 0) {
|
||||
/*
|
||||
* Defer signals to protect the scheduling queues from
|
||||
* access by the signal handler:
|
||||
*/
|
||||
/* XXX RLC _thread_kern_sig_defer(); */
|
||||
|
||||
/* Lock the hash table: */
|
||||
_SPINLOCK(&hash_lock);
|
||||
|
||||
/*
|
||||
* Get a pointer to the lock for the file and check that
|
||||
* the running thread is the one with the lock:
|
||||
*/
|
||||
if ((p = find_lock(idx, fp)) != NULL &&
|
||||
p->owner == self) {
|
||||
/*
|
||||
* Check if this thread has locked the FILE
|
||||
* more than once:
|
||||
*/
|
||||
if (p->count > 1)
|
||||
/*
|
||||
* Decrement the count of the number of
|
||||
* times the running thread has locked this
|
||||
* file:
|
||||
*/
|
||||
p->count--;
|
||||
else {
|
||||
/*
|
||||
* The running thread will release the
|
||||
* lock now:
|
||||
*/
|
||||
p->count = 0;
|
||||
|
||||
/* Get the new owner of the lock: */
|
||||
if ((p->owner = TAILQ_FIRST(&p->l_head)) != NULL) {
|
||||
/* Pop the thread off the queue: */
|
||||
TAILQ_REMOVE(&p->l_head,p->owner,qe);
|
||||
|
||||
/*
|
||||
* This is the first lock for the new
|
||||
* owner:
|
||||
*/
|
||||
p->count = 1;
|
||||
|
||||
/* Allow the new owner to run: */
|
||||
restart(p->owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlock the hash table: */
|
||||
_SPINUNLOCK(&hash_lock);
|
||||
|
||||
/*
|
||||
* Undefer and handle pending signals, yielding if
|
||||
* necessary:
|
||||
*/
|
||||
/* XXX RLC _thread_kern_sig_undefer(); */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void __fresetlockfiles()
|
||||
{
|
||||
int idx;
|
||||
struct file_lock *p;
|
||||
|
||||
_SPINLOCK(&hash_lock);
|
||||
for (idx = 0; idx < NUM_HEADS; idx++) {
|
||||
|
||||
/* Zero the static lock */
|
||||
p = &flh[idx].fl;
|
||||
p->owner = NULL;
|
||||
p->fp = NULL;
|
||||
p->count = 0;
|
||||
TAILQ_INIT(&p->l_head);
|
||||
|
||||
/* Loop through the dynamic locks
|
||||
* and free them.
|
||||
*/
|
||||
|
||||
while (flh[idx].head.lh_first != NULL) {
|
||||
p = flh[idx].head.lh_first;
|
||||
LIST_REMOVE(p, entry);
|
||||
free (p);
|
||||
}
|
||||
}
|
||||
_SPINUNLOCK(&hash_lock);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void __fresetlockfiles()
|
||||
{
|
||||
/* XXX: Should do something */
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -1,15 +0,0 @@
|
|||
LinuxThreads is an POSIX pthreads implementation using "kernel threads". In
|
||||
this FreeBSD port, a kernel thread is started using rfork (whereas in the
|
||||
original Linux implementation a kernel thread is started using the Linux clone
|
||||
call).
|
||||
This implementation provides a so-called one-to-one mapping of threads to
|
||||
kernel schedulable entities. For more information see about the original
|
||||
LinuxThreads implementation see:
|
||||
|
||||
WWW: http://pauillac.inria.fr/~xleroy/linuxthreads/
|
||||
|
||||
Note that LinuxThreads has been integrated with the GNU C library (glibc) since
|
||||
version 2.0, so the above URL points to dated information.
|
||||
|
||||
The complete FreeBSD source code matching the installed userland
|
||||
must be installed in /usr/src before building linuxthreads.
|
|
@ -1,3 +0,0 @@
|
|||
Please see the README.FreeBSD file in the work directory for
|
||||
instructions on how to compile with linuxthreads, and for other
|
||||
issues and problems.
|
|
@ -1,38 +0,0 @@
|
|||
lib/liblthread.a
|
||||
%%PROFILE:%%lib/liblthread_p.a
|
||||
%%LIBLTHREADPICARCHIVE:%%lib/liblthread_pic.a
|
||||
%%PIC:%%lib/liblthread.so
|
||||
%%PIC:%%lib/liblthread.so.%%LTHREADSHMAJOR:%%
|
||||
lib/liblgcc_r.a
|
||||
lib/liblgcc_r_pic.a
|
||||
%%GCC4ONLY:%%lib/liblgcc_r_eh.a
|
||||
%%GCC4ONLY:%%lib/liblgcc_r_eh_p.a
|
||||
%%PROFILE:%%lib/liblgcc_r_p.a
|
||||
%%GCC4ONLY:%%lib/liblgcc_s.so
|
||||
%%GCC4ONLY:%%lib/liblgcc_s.so.1
|
||||
%%LIBLGCC_R_PICARCHIVE:%%lib/liblgcc_r_pic.a
|
||||
%%GCC3OR4ONLY:%%lib/liblstdc++.a
|
||||
%%GCC3OR4ONLY:%%%%PROFILE:%%lib/liblstdc++_p.a
|
||||
%%GCC3OR4ONLY:%%%%PICARCHIVE:%%lib/liblstdc++_pic.a
|
||||
%%GCC3OR4ONLY:%%%%PIC:%%lib/liblstdc++.so
|
||||
%%GCC3OR4ONLY:%%%%PIC:%%lib/liblstdc++.so.%%LIBSTDCPPMAJOR:%%
|
||||
%%GCC3OR4ONLY:%%lib/liblsupc++.a
|
||||
%%GCC3OR4ONLY:%%%%PROFILE:%%lib/liblsupc++_p.a
|
||||
%%GCC3OR4ONLY:%%%%PICARCHIVE:%%lib/liblsupc++_pic.a
|
||||
include/pthread/linuxthreads/pthread.h
|
||||
include/pthread/linuxthreads/semaphore.h
|
||||
include/pthread/linuxthreads/pt-machine.h
|
||||
include/pthread/linuxthreads/useldt.h
|
||||
include/pthread/linuxthreads/bits/initspin.h
|
||||
include/pthread/linuxthreads/bits/libc-lock.h
|
||||
include/pthread/linuxthreads/bits/libc-tsd.h
|
||||
include/pthread/linuxthreads/bits/pthreadtypes.h
|
||||
include/pthread/linuxthreads/bits/stdio-lock.h
|
||||
include/pthread/linuxthreads/bits/local_lim.h
|
||||
include/pthread/linuxthreads/bits/posix_opt.h
|
||||
include/pthread/linuxthreads/bits/sigthread.h
|
||||
include/pthread/linuxthreads/sys/_pthreadtypes.h
|
||||
@dirrm include/pthread/linuxthreads/sys
|
||||
@dirrm include/pthread/linuxthreads/bits
|
||||
@dirrm include/pthread/linuxthreads
|
||||
@dirrm include/pthread
|
Loading…
Reference in a new issue