mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 19:34:43 +01:00
Compare commits
84
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7dbb88eb2e | ||
|
|
481a5ea35f | ||
|
|
bb066eb657 | ||
|
|
ad52416410 | ||
|
|
e715b78ac0 | ||
|
|
982ed5af91 | ||
|
|
dd634cb516 | ||
|
|
9b9509b1a5 | ||
|
|
fd84825681 | ||
|
|
63faf15a9e | ||
|
|
78779d572b | ||
|
|
222a2708bb | ||
|
|
598a20cc0e | ||
|
|
8868d625ea | ||
|
|
c83451d3a7 | ||
|
|
92c839c9df | ||
|
|
6ca3b740c3 | ||
|
|
baa21206e0 | ||
|
|
5ecf0a2a4d | ||
|
|
f22d7eed1c | ||
|
|
21b71a3a96 | ||
|
|
f58a5b73fc | ||
|
|
3cd4e46ec7 | ||
|
|
17f9ac2b51 | ||
|
|
ca8cf52b9b | ||
|
|
df331583f7 | ||
|
|
b3f690998d | ||
|
|
a4f660fe50 | ||
|
|
c1e66e7e3f | ||
|
|
04df9af671 | ||
|
|
793916daeb | ||
|
|
f608fa17ae | ||
|
|
066a685df4 | ||
|
|
71cd182013 | ||
|
|
61ce60d1f9 | ||
|
|
448ad2be0e | ||
|
|
b86ef4fe5d | ||
|
|
9bef3237d9 | ||
|
|
3499ec30a3 | ||
|
|
ff8a3c7aa0 | ||
|
|
946bc5e31c | ||
|
|
7a8df2a679 | ||
|
|
85b084f74f | ||
|
|
d782b48b33 | ||
|
|
2c35c78a5f | ||
|
|
9f89821fc9 | ||
|
|
9869849933 | ||
|
|
e479892a32 | ||
|
|
48455098b0 | ||
|
|
befc6801c4 | ||
|
|
ec3ea865f0 | ||
|
|
446539c4d1 | ||
|
|
b550e2dffe | ||
|
|
f4d26baa51 | ||
|
|
e296f29988 | ||
|
|
d40dbb0c7b | ||
|
|
ff7c376de8 | ||
|
|
79ea91c806 | ||
|
|
66c21b6a13 | ||
|
|
32e46d4024 | ||
|
|
f855b04f89 | ||
|
|
25fa72ec65 | ||
|
|
5fb427aebf | ||
|
|
364e6ad2a4 | ||
|
|
c38e3aa7a9 | ||
|
|
60749595bc | ||
|
|
2c2b3b6b7e | ||
|
|
e6dc1d7d67 | ||
|
|
4b53300c0c | ||
|
|
8dcfd23ac5 | ||
|
|
918783a66c | ||
|
|
cfc1c85d6f | ||
|
|
c42206d987 | ||
|
|
9844500419 | ||
|
|
54203f5e47 | ||
|
|
ee12e83ecb | ||
|
|
dfd7377f55 | ||
|
|
86536f3f9a | ||
|
|
303048382c | ||
|
|
52eeaa89e0 | ||
|
|
3cfe1020d8 | ||
|
|
ac0e1c8df7 | ||
|
|
94d09e13f6 | ||
|
|
a348451bd8 |
No files matched your search
@@ -1,6 +1,35 @@
|
||||
# $FreeBSD$
|
||||
# @(#)COPYRIGHT 8.2 (Berkeley) 3/21/94
|
||||
|
||||
The compilation of software known as FreeBSD is distributed under the
|
||||
following terms:
|
||||
|
||||
Copyright (C) 1992-2004 The FreeBSD Project. 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 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 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.
|
||||
|
||||
The 4.4BSD and 4.4BSD-Lite software is distributed under the following
|
||||
terms:
|
||||
|
||||
All of the documentation and software included in the 4.4BSD and 4.4BSD-Lite
|
||||
Releases is copyrighted by The Regents of the University of California.
|
||||
|
||||
|
||||
+8
-14
@@ -46,19 +46,16 @@ SUBDIR+= share/info
|
||||
.if exists(${.CURDIR}/include)
|
||||
SUBDIR+= include
|
||||
.endif
|
||||
|
||||
# We must do lib and libexec before bin, because if installworld
|
||||
# installs a new /bin/sh, the 'make' command will *immediately*
|
||||
# use that new version. And the new (dynamically-linked) /bin/sh
|
||||
# will expect to find appropriate libraries in /lib and /libexec.
|
||||
.if exists(${.CURDIR}/lib)
|
||||
SUBDIR+= lib
|
||||
.endif
|
||||
|
||||
# When upgrading to a dynamically linked root, install the runtime
|
||||
# linker early into its new location before make(1) has a chance
|
||||
# to run the dynamically linked /bin/sh.
|
||||
.if !defined(NO_DYNAMICROOT) && !defined(NOPIC) && \
|
||||
(!defined(TARGET_ARCH) || ${TARGET_ARCH} == ${MACHINE_ARCH}) && \
|
||||
!defined(DISTDIR) && \
|
||||
(!defined(DESTDIR) || empty(DESTDIR) || ${DESTDIR} == "/") && \
|
||||
!exists(/libexec/ld-elf.so.1)
|
||||
SUBDIR+= libexec/rtld-elf
|
||||
.if exists(${.CURDIR}/libexec)
|
||||
SUBDIR+= libexec
|
||||
.endif
|
||||
|
||||
.if exists(${.CURDIR}/bin)
|
||||
@@ -74,9 +71,6 @@ SUBDIR+= gnu
|
||||
!defined(NOCRYPT) && !defined(NO_OPENSSL) && !defined(NO_KERBEROS)
|
||||
SUBDIR+= kerberos5
|
||||
.endif
|
||||
.if exists(${.CURDIR}/libexec)
|
||||
SUBDIR+= libexec
|
||||
.endif
|
||||
.if exists(${.CURDIR}/rescue) && !defined(NO_RESCUE)
|
||||
SUBDIR+= rescue
|
||||
.endif
|
||||
@@ -591,7 +585,7 @@ update:
|
||||
@echo "--------------------------------------------------------------"
|
||||
@echo ">>> Updating ${.CURDIR} from cvs repository" ${CVSROOT}
|
||||
@echo "--------------------------------------------------------------"
|
||||
cd ${.CURDIR}; ${CVS} -R -q update -A -P -d
|
||||
cd ${.CURDIR}; ${CVS} -R -q update -rRELENG_5_2 -P -d
|
||||
.endif
|
||||
|
||||
#
|
||||
|
||||
@@ -1,21 +1,11 @@
|
||||
Updating Information for FreeBSD current users
|
||||
Updating Information for FreeBSD 5.2 users
|
||||
|
||||
This file is maintained and copyrighted by M. Warner Losh
|
||||
<[email protected]>. See end of file for further details. For commonly
|
||||
done items, please see the COMMON ITEMS: section later in the file.
|
||||
|
||||
NOTE TO PEOPLE WHO THINK THAT FreeBSD 5.x IS SLOW:
|
||||
FreeBSD 5.x has many debugging features turned on, in
|
||||
both the kernel and userland. These features attempt to detect
|
||||
incorrect use of system primitives, and encourage loud failure
|
||||
through extra sanity checking and fail stop semantics. They
|
||||
also substantially impact system performance. If you want to
|
||||
do performance measurement, benchmarking, and optimization,
|
||||
you'll want to turn them off. This includes various WITNESS-
|
||||
related kernel options, INVARIANTS, malloc debugging flags
|
||||
in userland, and various verbose features in the kernel. Many
|
||||
developers choose to disable these features on build machines
|
||||
to maximize performance.
|
||||
20031206:
|
||||
FreeBSD 5.2 branched
|
||||
|
||||
20031112:
|
||||
The statfs structure has been updated with 64-bit fields to
|
||||
@@ -43,6 +33,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 5.x IS SLOW:
|
||||
new kernel otherwise on a system with new binaries and an old
|
||||
kernel.
|
||||
|
||||
20031203:
|
||||
The ACPI module has been reactivated. It is no longer required
|
||||
to compile ACPI support into kernels statically.
|
||||
|
||||
20031112:
|
||||
Some netgraph string length constants have been changed. This
|
||||
change requires the netgraph kernel modules and all netgraph
|
||||
@@ -50,6 +44,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 5.x IS SLOW:
|
||||
netgraph to boot need to make sure to have world and kernel in
|
||||
sync before rebooting.
|
||||
|
||||
20031111:
|
||||
Hyperthreading logical CPU's are no longer probed by default
|
||||
when using the MP Table. If ACPI is being used, then logical
|
||||
CPUs will be probed if hyperthreading is enabled in the BIOS.
|
||||
If ACPI is not being used and hyperthreading is enabled in the
|
||||
BIOS, logical CPUs can be enabled by building a custom kernel
|
||||
with the option MPTABLE_FORCE_HTT enabled.
|
||||
|
||||
20031103:
|
||||
The i386 APIC_IO kernel option has been replaced by
|
||||
'device apic'. The ACPI module has also been temporarily
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
/* config.h. Generated automatically by configure. */
|
||||
/*
|
||||
* config.h -- configure various defines for tcsh
|
||||
*
|
||||
* All source files should #include this FIRST.
|
||||
*
|
||||
* Edit this to match your system type.
|
||||
*/
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef _h_config
|
||||
#define _h_config
|
||||
/****************** System dependant compilation flags ****************/
|
||||
/*
|
||||
* POSIX This system supports IEEE Std 1003.1-1988 (POSIX).
|
||||
*/
|
||||
#define POSIX
|
||||
|
||||
/*
|
||||
* POSIXJOBS This system supports the optional IEEE Std 1003.1-1988 (POSIX)
|
||||
* job control facilities.
|
||||
*/
|
||||
#define POSIXJOBS
|
||||
|
||||
/*
|
||||
* POSIXSIGS Use the POSIX signal facilities to emulate BSD signals.
|
||||
*/
|
||||
/* #undef POSIXSIGS */
|
||||
|
||||
/*
|
||||
* VFORK This machine has a vfork().
|
||||
* It used to be that for job control to work, this define
|
||||
* was mandatory. This is not the case any more.
|
||||
* If you think you still need it, but you don't have vfork,
|
||||
* define this anyway and then do #define vfork fork.
|
||||
* I do this anyway on a Sun because of yellow pages brain damage,
|
||||
* [should not be needed under 4.1]
|
||||
* and on the iris4d cause SGI's fork is sufficiently "virtual"
|
||||
* that vfork isn't necessary. (Besides, SGI's vfork is weird).
|
||||
* Note that some machines eg. rs6000 have a vfork, but not
|
||||
* with the berkeley semantics, so we cannot use it there either.
|
||||
*/
|
||||
#define VFORK
|
||||
|
||||
/*
|
||||
* BSDJOBS You have BSD-style job control (both process groups and
|
||||
* a tty that deals correctly
|
||||
*/
|
||||
#define BSDJOBS
|
||||
|
||||
/*
|
||||
* BSDSIGS You have 4.2-style signals, rather than USG style.
|
||||
* Note: POSIX systems should not define this unless they
|
||||
* have sigvec() and friends (ie: 4.3BSD-RENO, HP-UX).
|
||||
*/
|
||||
#define BSDSIGS
|
||||
|
||||
/*
|
||||
* BSDTIMES You have BSD-style process time stuff (like rusage)
|
||||
* This may or may not be true. For example, Apple Unix
|
||||
* (OREO) has BSDJOBS and BSDSIGS but not BSDTIMES.
|
||||
*/
|
||||
#define BSDTIMES
|
||||
|
||||
/*
|
||||
* BSDLIMIT You have BSD-style resource limit stuff (getrlimit/setrlimit)
|
||||
*/
|
||||
#define BSDLIMIT
|
||||
|
||||
/*
|
||||
* BSDNICE Your system uses setpriority() instead of nice, to
|
||||
* change a processes scheduling priority
|
||||
*/
|
||||
#define BSDNICE
|
||||
|
||||
/*
|
||||
* TERMIO You have struct termio instead of struct sgttyb.
|
||||
* This is usually the case for SYSV systems, where
|
||||
* BSD uses sgttyb. POSIX systems should define this
|
||||
* anyway, even though they use struct termios.
|
||||
*/
|
||||
#define TERMIO
|
||||
|
||||
/*
|
||||
* SYSVREL Your machine is SYSV based (HPUX, A/UX)
|
||||
* NOTE: don't do this if you are on a Pyramid -- tcsh is
|
||||
* built in a BSD universe.
|
||||
* Set SYSVREL to 1, 2, 3, or 4, depending the version of System V
|
||||
* you are running. Or set it to 0 if you are not SYSV based
|
||||
*/
|
||||
#define SYSVREL 0
|
||||
|
||||
/*
|
||||
* YPBUGS Work around Sun YP bugs that cause expansion of ~username
|
||||
* to send command output to /dev/null
|
||||
*/
|
||||
/* #undef YPBUGS */
|
||||
|
||||
/*
|
||||
* SIGVOID Define this if your signal handlers return void. On older
|
||||
* systems, signal returns int, but on newer ones, it returns void.
|
||||
*/
|
||||
#define SIGVOID
|
||||
|
||||
/*
|
||||
* HAVEDUP2 Define this if your system supports dup2().
|
||||
*/
|
||||
#define HAVEDUP2
|
||||
|
||||
/*
|
||||
* UTHOST Does the utmp file have a host field?
|
||||
*/
|
||||
#define UTHOST
|
||||
|
||||
/*
|
||||
* DIRENT Your system has <dirent.h> instead of <sys/dir.h>
|
||||
*/
|
||||
#define DIRENT
|
||||
/****************** local defines *********************/
|
||||
/****************** configurable hacks ****************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* have been moved to config_f.h */
|
||||
#include "config_f.h"
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#define NLS_BUGS
|
||||
/* we want to use the system malloc when we install as /bin/csh */
|
||||
#define SYSMALLOC
|
||||
#define BSD_STYLE_COLORLS
|
||||
#endif
|
||||
|
||||
#if defined(__bsdi__)
|
||||
/*
|
||||
* _PATH_TCSHELL if you've change the installation location (vix)
|
||||
*/
|
||||
# if _BSDI_VERSION >= 199701
|
||||
# define _PATH_TCSHELL "/bin/tcsh"
|
||||
/* # undef SYSMALLOC */
|
||||
# define SYSMALLOC
|
||||
# else
|
||||
# define _PATH_TCSHELL "/usr/contrib/bin/tcsh"
|
||||
# endif
|
||||
|
||||
# undef NLS
|
||||
# undef NLS_CATALOGS
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
# define SYSMALLOC
|
||||
|
||||
#else
|
||||
# define NLS_CATALOGS
|
||||
#endif
|
||||
|
||||
#define KANJI
|
||||
#define DSPMBYTE
|
||||
|
||||
#endif /* _h_config */
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
@@ -9,6 +9,7 @@ SHSRCS= alias.c arith.y arith_lex.l cd.c echo.c error.c eval.c exec.c expand.c \
|
||||
GENSRCS= builtins.c init.c nodes.c syntax.c
|
||||
GENHDRS= builtins.h nodes.h syntax.h token.h y.tab.h
|
||||
SRCS= ${SHSRCS} ${GENSRCS} ${GENHDRS} y.tab.h
|
||||
NOSHARED?= yes
|
||||
|
||||
# MLINKS for Shell built in commands for which there are no userland
|
||||
# utilities of the same name are handled with the associated manpage,
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= uuidgen
|
||||
WARNS?= 4
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,79 +0,0 @@
|
||||
.\" Copyright (c) 2002 Marcel Moolenaar
|
||||
.\" 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 ``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 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$
|
||||
.\"
|
||||
.Dd May 23, 2002
|
||||
.Dt UUIDGEN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm uuidgen
|
||||
.Nd generate universally unique identifiers
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl 1
|
||||
.Op Fl n Ar count
|
||||
.Op Fl o Ar filename
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility by default generates a single universally unique identifier (UUID),
|
||||
also known as a globally unique identifier (GUID).
|
||||
The UUID is written to stdout by default.
|
||||
The following options can be used to change the behaviour of
|
||||
.Nm :
|
||||
.Bl -tag -width indent
|
||||
.It Fl 1
|
||||
This option only has effect if multiple identifiers are to be generated and
|
||||
instructs
|
||||
.Nm
|
||||
to not generate them in batch, but one at a time.
|
||||
.It Fl n
|
||||
This option controls the number of identifiers generated.
|
||||
By default, multiple
|
||||
identifiers are generated in batch.
|
||||
.It Fl o
|
||||
Redirect output to
|
||||
.Ar filename
|
||||
instead of stdout.
|
||||
.El
|
||||
.Pp
|
||||
Batched generation yields a dense set of identifiers in such a way that there
|
||||
is no identifier that is larger than the smallest identifier in the set and
|
||||
smaller than the largest identifier in the set and that is not already in the
|
||||
set.
|
||||
.Pp
|
||||
When generating the identifiers one at a time, the identifiers will be close
|
||||
to each other, but operating system latency and processing time will be
|
||||
reflected in the distance between two successive identifiers.
|
||||
.Sh DIAGNOSTICS
|
||||
.Ex -std
|
||||
.Sh SEE ALSO
|
||||
.Xr uuidgen 2 ,
|
||||
.Xr uuid 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command first appeared in
|
||||
.Fx 5.0 .
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Marcel Moolenaar
|
||||
* 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 ``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 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/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <uuid.h>
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "usage: uuidgen [-1] [-n count] [-o filename]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
FILE *fp;
|
||||
uuid_t *store, *uuid;
|
||||
char *p;
|
||||
int ch, count, i, iterate;
|
||||
|
||||
count = -1; /* no count yet */
|
||||
fp = stdout; /* default output file */
|
||||
iterate = 0; /* not one at a time */
|
||||
while ((ch = getopt(argc, argv, "1n:o:")) != -1)
|
||||
switch (ch) {
|
||||
case '1':
|
||||
iterate = 1;
|
||||
break;
|
||||
case 'n':
|
||||
if (count > 0)
|
||||
usage();
|
||||
count = strtol(optarg, &p, 10);
|
||||
if (*p != 0 || count < 1)
|
||||
usage();
|
||||
break;
|
||||
case 'o':
|
||||
if (fp != stdout)
|
||||
errx(1, "multiple output files not allowed");
|
||||
fp = fopen(optarg, "w");
|
||||
if (fp == NULL)
|
||||
err(1, "fopen");
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc)
|
||||
usage();
|
||||
|
||||
if (count == -1)
|
||||
count = 1;
|
||||
|
||||
store = (uuid_t*)malloc(sizeof(uuid_t) * count);
|
||||
if (store == NULL)
|
||||
err(1, "malloc()");
|
||||
|
||||
if (!iterate) {
|
||||
/* Get them all in a single batch */
|
||||
if (uuidgen(store, count) != 0)
|
||||
err(1, "uuidgen()");
|
||||
} else {
|
||||
uuid = store;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (uuidgen(uuid++, 1) != 0)
|
||||
err(1, "uuidgen()");
|
||||
}
|
||||
}
|
||||
|
||||
uuid = store;
|
||||
while (count--) {
|
||||
uuid_to_string(uuid++, &p, NULL);
|
||||
fprintf(fp, "%s\n", p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
free(store);
|
||||
if (fp != stdout)
|
||||
fclose(fp);
|
||||
return (0);
|
||||
}
|
||||
@@ -25,6 +25,17 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (FreeBSD/x86-64 ELF)");
|
||||
|
||||
#undef FBSD_TARGET_CPU_CPP_BUILTINS
|
||||
#define FBSD_TARGET_CPU_CPP_BUILTINS() \
|
||||
do \
|
||||
{ \
|
||||
if (TARGET_64BIT) \
|
||||
{ \
|
||||
builtin_define ("__LP64__"); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Provide a LINK_SPEC appropriate for the FreeBSD/x86-64 ELF target.
|
||||
This is a copy of LINK_SPEC from <i386/freebsd.h> tweaked for
|
||||
the x86-64 target. */
|
||||
|
||||
@@ -922,6 +922,7 @@ int blen;
|
||||
}
|
||||
#if (SOLARIS || \
|
||||
(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
|
||||
(defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) || \
|
||||
(defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux)
|
||||
{
|
||||
char ifname[sizeof(ipf->fl_ifname) + 1];
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $P4: //depot/projects/openpam/lib/openpam_ttyconv.c#23 $
|
||||
* $P4: //depot/projects/openpam/lib/openpam_ttyconv.c#24 $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@@ -119,7 +119,7 @@ prompt(const char *msg)
|
||||
}
|
||||
/* trim trailing whitespace */
|
||||
for (len = strlen(buf); len > 0; --len)
|
||||
if (!isspace(buf[len - 1]))
|
||||
if (buf[len - 1] != '\r' && buf[len - 1] != '\n')
|
||||
break;
|
||||
buf[len] = '\0';
|
||||
retval = strdup(buf);
|
||||
@@ -166,26 +166,27 @@ openpam_ttyconv(int n,
|
||||
struct pam_response **resp,
|
||||
void *data)
|
||||
{
|
||||
struct pam_response *aresp;
|
||||
int i;
|
||||
|
||||
ENTER();
|
||||
(void)data;
|
||||
if (n <= 0 || n > PAM_MAX_NUM_MSG)
|
||||
RETURNC(PAM_CONV_ERR);
|
||||
if ((*resp = calloc(n, sizeof **resp)) == NULL)
|
||||
if ((aresp = calloc(n, sizeof *aresp)) == NULL)
|
||||
RETURNC(PAM_BUF_ERR);
|
||||
for (i = 0; i < n; ++i) {
|
||||
resp[i]->resp_retcode = 0;
|
||||
resp[i]->resp = NULL;
|
||||
aresp[i].resp_retcode = 0;
|
||||
aresp[i].resp = NULL;
|
||||
switch (msg[i]->msg_style) {
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
(*resp[i]).resp = prompt_echo_off(msg[i]->msg);
|
||||
if ((*resp[i]).resp == NULL)
|
||||
aresp[i].resp = prompt_echo_off(msg[i]->msg);
|
||||
if (aresp[i].resp == NULL)
|
||||
goto fail;
|
||||
break;
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
(*resp[i]).resp = prompt(msg[i]->msg);
|
||||
if ((*resp[i]).resp == NULL)
|
||||
aresp[i].resp = prompt(msg[i]->msg);
|
||||
if (aresp[i].resp == NULL)
|
||||
goto fail;
|
||||
break;
|
||||
case PAM_ERROR_MSG:
|
||||
@@ -204,16 +205,18 @@ openpam_ttyconv(int n,
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
*resp = aresp;
|
||||
RETURNC(PAM_SUCCESS);
|
||||
fail:
|
||||
for (i = 0; i < n; ++i) {
|
||||
if ((*resp[i]).resp != NULL) {
|
||||
memset((*resp[i]).resp, 0, strlen((*resp[i]).resp));
|
||||
FREE((*resp[i]).resp);
|
||||
if (aresp[i].resp != NULL) {
|
||||
memset(aresp[i].resp, 0, strlen(aresp[i].resp));
|
||||
FREE(aresp[i].resp);
|
||||
}
|
||||
}
|
||||
memset(*resp, 0, n * sizeof **resp);
|
||||
FREE(*resp);
|
||||
memset(aresp, 0, n * sizeof *aresp);
|
||||
FREE(aresp);
|
||||
*resp = NULL;
|
||||
RETURNC(PAM_CONV_ERR);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: nfslocking,v 1.6 2002/03/24 15:52:41 lukem Exp $
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
# PROVIDE: nfslocking
|
||||
# REQUIRE: nfsserver nfsclient nfsd
|
||||
# BEFORE: DAEMON
|
||||
# KEYWORD: FreeBSD NetBSD
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
arg=$1
|
||||
|
||||
case ${OSTYPE} in
|
||||
FreeBSD)
|
||||
RCVAR_SERVER="nfs_server_enable"
|
||||
RCVAR_CLIENT="nfs_client_enable"
|
||||
RCVAR_STATD="rpc_statd_enable"
|
||||
RCVAR_LOCKD="rpc_lockd_enable"
|
||||
;;
|
||||
NetBSD)
|
||||
RCVAR_SERVER="nfs_server"
|
||||
RCVAR_CLIENT="nfs_client"
|
||||
RCVAR_STATD="statd"
|
||||
RCVAR_LOCKD="lockd"
|
||||
;;
|
||||
esac
|
||||
|
||||
start_precmd='checkyesno ${RCVAR_SERVER} || checkyesno ${RCVAR_CLIENT} ||
|
||||
[ -n "$rc_force" ]'
|
||||
stop_precmd=$start_precmd
|
||||
status_precmd=$start_precmd
|
||||
|
||||
name="statd"
|
||||
rcvar=${RCVAR_STATD}
|
||||
command="/usr/sbin/rpc.${name}"
|
||||
load_rc_config $name
|
||||
run_rc_command "$arg"
|
||||
|
||||
name="lockd"
|
||||
rcvar=${RCVAR_LOCKD}
|
||||
command="/usr/sbin/rpc.${name}"
|
||||
load_rc_config $name
|
||||
run_rc_command "$arg"
|
||||
@@ -1,48 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
# PROVIDE: ppp-user
|
||||
# REQUIRE: netif isdnd
|
||||
# KEYWORD: FreeBSD
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
name="ppp"
|
||||
rcvar="ppp_enable"
|
||||
start_cmd="ppp_start"
|
||||
stop_cmd=":"
|
||||
|
||||
ppp_start()
|
||||
{
|
||||
# Establish ppp mode.
|
||||
#
|
||||
if [ "${ppp_mode}" != "ddial" -a "${ppp_mode}" != "direct" \
|
||||
-a "${ppp_mode}" != "dedicated" \
|
||||
-a "${ppp_mode}" != "background" ]; then
|
||||
ppp_mode="auto"
|
||||
fi
|
||||
|
||||
ppp_command="/usr/sbin/ppp -quiet -${ppp_mode}"
|
||||
|
||||
# Switch on NAT mode?
|
||||
#
|
||||
case ${ppp_nat} in
|
||||
[Yy][Ee][Ss])
|
||||
ppp_command="${ppp_command} -nat"
|
||||
;;
|
||||
esac
|
||||
|
||||
ppp_command="${ppp_command} ${ppp_profile}"
|
||||
|
||||
echo "Starting ppp as \"${ppp_user}\""
|
||||
su -m ${ppp_user} -c "exec ${ppp_command}"
|
||||
|
||||
# Re-Sync ipfilter so it picks up any new network interfaces
|
||||
#
|
||||
/etc/rc.d/ipfilter resync
|
||||
}
|
||||
|
||||
load_rc_config $name
|
||||
run_rc_command "$1"
|
||||
-167
@@ -1,167 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 1999 Matt Dillon
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
# PROVIDE: diskless
|
||||
# REQUIRE: initdiskless rcconf mountcritlocal
|
||||
# BEFORE: addswap random
|
||||
# KEYWORD: FreeBSD
|
||||
|
||||
dlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null`
|
||||
[ ${dlv:=0} -eq 0 ] && exit 0
|
||||
|
||||
name="diskless2"
|
||||
|
||||
# Provide a function for normalizing the mounting of memory
|
||||
# filesystems. This should allow the rest of the code here to remain
|
||||
# as close as possible between 5-current and 4-stable.
|
||||
# $1 = size
|
||||
# $2 = mount point
|
||||
# $3 = (optional) bytes-per-inode
|
||||
mount_md() {
|
||||
if [ -n "$3" ]; then
|
||||
bpi="-i $3"
|
||||
fi
|
||||
/sbin/mdmfs $bpi -s $1 -M md $2
|
||||
}
|
||||
|
||||
# If there is a global system configuration file, suck it in.
|
||||
#
|
||||
if [ -r /etc/rc.subr ]; then
|
||||
. /etc/rc.subr
|
||||
load_rc_config $name
|
||||
elif [ -r /etc/defaults/rc.conf ]; then
|
||||
. /etc/defaults/rc.conf
|
||||
source_rc_confs
|
||||
elif [ -r /etc/rc.conf ]; then
|
||||
. /etc/rc.conf
|
||||
fi
|
||||
|
||||
# If we do not have a writable /var, create a memory
|
||||
# filesystem for /var. We don't have /usr yet so
|
||||
# use mkdir instead of touch to test. We want mount
|
||||
# to record its mounts so we have to make sure /var/db
|
||||
# exists before doing the mount -a.
|
||||
#
|
||||
if (/bin/mkdir /var/.diskless 2> /dev/null); then
|
||||
rmdir /var/.diskless
|
||||
else
|
||||
echo "+++ mount_md of /var"
|
||||
mount_md ${varsize:=32m} /var
|
||||
fi
|
||||
|
||||
if [ ! -d /var/db ]; then
|
||||
mkdir /var/db
|
||||
fi
|
||||
|
||||
# Now we need the rest of our mounts, particularly /usr
|
||||
#
|
||||
mount -a # chown and chgrp are in /usr
|
||||
|
||||
# Populate /var
|
||||
#
|
||||
echo "+++ populate /var using /etc/mtree/BSD.var.dist"
|
||||
/usr/sbin/mtree -deU -f /etc/mtree/BSD.var.dist -p /var > /dev/null
|
||||
case ${sendmail_enable} in
|
||||
[Nn][Oo][Nn][Ee])
|
||||
;;
|
||||
*)
|
||||
/usr/sbin/mtree -deU -f /etc/mtree/BSD.sendmail.dist -p / > /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "+++ create log files based on the contents of /etc/newsyslog.conf"
|
||||
LOGFILES=`/usr/bin/awk '$1 != "#" { printf "%s ", $1 } ' /etc/newsyslog.conf`
|
||||
if [ -n "$LOGFILES" ]; then
|
||||
/usr/bin/touch $LOGFILES
|
||||
fi
|
||||
|
||||
echo "+++ create lastlog"
|
||||
/usr/bin/touch /var/log/lastlog
|
||||
|
||||
# Make sure our aliases database is uptodate, the aliases may have
|
||||
# been overriden in /conf.
|
||||
#
|
||||
/usr/bin/newaliases
|
||||
|
||||
# XXX make sure to create one dir for each printer as requested by lpd
|
||||
#
|
||||
# If we do not have a writable /tmp, create a memory
|
||||
# filesystem for /tmp. If /tmp is a symlink (e.g. to /var/tmp,
|
||||
# then it should already be writable).
|
||||
#
|
||||
if (/bin/mkdir /tmp/.diskless 2> /dev/null); then
|
||||
rmdir /tmp/.diskless
|
||||
else
|
||||
if [ -h /tmp ]; then
|
||||
echo "*** /tmp is a symlink to a non-writable area!"
|
||||
echo "dropping into shell, ^D to continue anyway."
|
||||
/bin/sh
|
||||
else
|
||||
mount_md ${tmpsize:=20480} /tmp
|
||||
chmod 01777 /tmp
|
||||
fi
|
||||
fi
|
||||
|
||||
if sysctl vfs.devfs.generation > /dev/null 2>&1 ; then
|
||||
# we have DEVFS, no worries...
|
||||
true
|
||||
elif (/bin/mkdir /dev/.diskless 2> /dev/null); then
|
||||
# if /dev is writable assume it has already been populated
|
||||
# via /etc/rc.d/initdiskless
|
||||
#
|
||||
rmdir /dev/.diskless
|
||||
else
|
||||
(cd /; find -x dev | cpio -o -H newc) > /tmp/dev.tmp
|
||||
mount_md 4096 /dev 512
|
||||
(cd /; cpio -i -H newc -d < /tmp/dev.tmp)
|
||||
rm -f /tmp/dev.tmp
|
||||
fi
|
||||
|
||||
# generate our hostname
|
||||
#
|
||||
if [ -z "`hostname -s`" -a \
|
||||
"x`/bin/kenv dhcp.host-name`" != "x" ]; then
|
||||
hostname=`/bin/kenv dhcp.host-name`
|
||||
hostname $hostname
|
||||
echo "Hostname is $hostname"
|
||||
fi
|
||||
|
||||
# if the info is available via dhcp/kenv
|
||||
# build the resolv.conf
|
||||
#
|
||||
if [ ! -e /etc/resolv.conf -a \
|
||||
"x`/bin/kenv dhcp.domain-name-servers`" != "x" ]; then
|
||||
echo domain `/bin/kenv dhcp.domain-name` > /etc/resolv.conf
|
||||
|
||||
set `/bin/kenv dhcp.domain-name-servers`
|
||||
for ns in `IFS=','; echo $*`; do
|
||||
echo nameserver $ns >> /etc/resolv.conf;
|
||||
done
|
||||
fi
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: nfslocking,v 1.6 2002/03/24 15:52:41 lukem Exp $
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
# PROVIDE: nfslocking
|
||||
# REQUIRE: nfsserver nfsclient nfsd
|
||||
# BEFORE: DAEMON
|
||||
# KEYWORD: FreeBSD NetBSD
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
arg=$1
|
||||
|
||||
case ${OSTYPE} in
|
||||
FreeBSD)
|
||||
RCVAR_SERVER="nfs_server_enable"
|
||||
RCVAR_CLIENT="nfs_client_enable"
|
||||
RCVAR_STATD="rpc_statd_enable"
|
||||
RCVAR_LOCKD="rpc_lockd_enable"
|
||||
;;
|
||||
NetBSD)
|
||||
RCVAR_SERVER="nfs_server"
|
||||
RCVAR_CLIENT="nfs_client"
|
||||
RCVAR_STATD="statd"
|
||||
RCVAR_LOCKD="lockd"
|
||||
;;
|
||||
esac
|
||||
|
||||
start_precmd='checkyesno ${RCVAR_SERVER} || checkyesno ${RCVAR_CLIENT} ||
|
||||
[ -n "$rc_force" ]'
|
||||
stop_precmd=$start_precmd
|
||||
status_precmd=$start_precmd
|
||||
|
||||
name="statd"
|
||||
rcvar=${RCVAR_STATD}
|
||||
command="/usr/sbin/rpc.${name}"
|
||||
load_rc_config $name
|
||||
run_rc_command "$arg"
|
||||
|
||||
name="lockd"
|
||||
rcvar=${RCVAR_LOCKD}
|
||||
command="/usr/sbin/rpc.${name}"
|
||||
load_rc_config $name
|
||||
run_rc_command "$arg"
|
||||
-167
@@ -1,167 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 1999 Matt Dillon
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
# PROVIDE: diskless
|
||||
# REQUIRE: initdiskless rcconf mountcritlocal
|
||||
# BEFORE: addswap random
|
||||
# KEYWORD: FreeBSD
|
||||
|
||||
dlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null`
|
||||
[ ${dlv:=0} -eq 0 ] && exit 0
|
||||
|
||||
name="diskless2"
|
||||
|
||||
# Provide a function for normalizing the mounting of memory
|
||||
# filesystems. This should allow the rest of the code here to remain
|
||||
# as close as possible between 5-current and 4-stable.
|
||||
# $1 = size
|
||||
# $2 = mount point
|
||||
# $3 = (optional) bytes-per-inode
|
||||
mount_md() {
|
||||
if [ -n "$3" ]; then
|
||||
bpi="-i $3"
|
||||
fi
|
||||
/sbin/mdmfs $bpi -s $1 -M md $2
|
||||
}
|
||||
|
||||
# If there is a global system configuration file, suck it in.
|
||||
#
|
||||
if [ -r /etc/rc.subr ]; then
|
||||
. /etc/rc.subr
|
||||
load_rc_config $name
|
||||
elif [ -r /etc/defaults/rc.conf ]; then
|
||||
. /etc/defaults/rc.conf
|
||||
source_rc_confs
|
||||
elif [ -r /etc/rc.conf ]; then
|
||||
. /etc/rc.conf
|
||||
fi
|
||||
|
||||
# If we do not have a writable /var, create a memory
|
||||
# filesystem for /var. We don't have /usr yet so
|
||||
# use mkdir instead of touch to test. We want mount
|
||||
# to record its mounts so we have to make sure /var/db
|
||||
# exists before doing the mount -a.
|
||||
#
|
||||
if (/bin/mkdir /var/.diskless 2> /dev/null); then
|
||||
rmdir /var/.diskless
|
||||
else
|
||||
echo "+++ mount_md of /var"
|
||||
mount_md ${varsize:=32m} /var
|
||||
fi
|
||||
|
||||
if [ ! -d /var/db ]; then
|
||||
mkdir /var/db
|
||||
fi
|
||||
|
||||
# Now we need the rest of our mounts, particularly /usr
|
||||
#
|
||||
mount -a # chown and chgrp are in /usr
|
||||
|
||||
# Populate /var
|
||||
#
|
||||
echo "+++ populate /var using /etc/mtree/BSD.var.dist"
|
||||
/usr/sbin/mtree -deU -f /etc/mtree/BSD.var.dist -p /var > /dev/null
|
||||
case ${sendmail_enable} in
|
||||
[Nn][Oo][Nn][Ee])
|
||||
;;
|
||||
*)
|
||||
/usr/sbin/mtree -deU -f /etc/mtree/BSD.sendmail.dist -p / > /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "+++ create log files based on the contents of /etc/newsyslog.conf"
|
||||
LOGFILES=`/usr/bin/awk '$1 != "#" { printf "%s ", $1 } ' /etc/newsyslog.conf`
|
||||
if [ -n "$LOGFILES" ]; then
|
||||
/usr/bin/touch $LOGFILES
|
||||
fi
|
||||
|
||||
echo "+++ create lastlog"
|
||||
/usr/bin/touch /var/log/lastlog
|
||||
|
||||
# Make sure our aliases database is uptodate, the aliases may have
|
||||
# been overriden in /conf.
|
||||
#
|
||||
/usr/bin/newaliases
|
||||
|
||||
# XXX make sure to create one dir for each printer as requested by lpd
|
||||
#
|
||||
# If we do not have a writable /tmp, create a memory
|
||||
# filesystem for /tmp. If /tmp is a symlink (e.g. to /var/tmp,
|
||||
# then it should already be writable).
|
||||
#
|
||||
if (/bin/mkdir /tmp/.diskless 2> /dev/null); then
|
||||
rmdir /tmp/.diskless
|
||||
else
|
||||
if [ -h /tmp ]; then
|
||||
echo "*** /tmp is a symlink to a non-writable area!"
|
||||
echo "dropping into shell, ^D to continue anyway."
|
||||
/bin/sh
|
||||
else
|
||||
mount_md ${tmpsize:=20480} /tmp
|
||||
chmod 01777 /tmp
|
||||
fi
|
||||
fi
|
||||
|
||||
if sysctl vfs.devfs.generation > /dev/null 2>&1 ; then
|
||||
# we have DEVFS, no worries...
|
||||
true
|
||||
elif (/bin/mkdir /dev/.diskless 2> /dev/null); then
|
||||
# if /dev is writable assume it has already been populated
|
||||
# via /etc/rc.d/initdiskless
|
||||
#
|
||||
rmdir /dev/.diskless
|
||||
else
|
||||
(cd /; find -x dev | cpio -o -H newc) > /tmp/dev.tmp
|
||||
mount_md 4096 /dev 512
|
||||
(cd /; cpio -i -H newc -d < /tmp/dev.tmp)
|
||||
rm -f /tmp/dev.tmp
|
||||
fi
|
||||
|
||||
# generate our hostname
|
||||
#
|
||||
if [ -z "`hostname -s`" -a \
|
||||
"x`/bin/kenv dhcp.host-name`" != "x" ]; then
|
||||
hostname=`/bin/kenv dhcp.host-name`
|
||||
hostname $hostname
|
||||
echo "Hostname is $hostname"
|
||||
fi
|
||||
|
||||
# if the info is available via dhcp/kenv
|
||||
# build the resolv.conf
|
||||
#
|
||||
if [ ! -e /etc/resolv.conf -a \
|
||||
"x`/bin/kenv dhcp.domain-name-servers`" != "x" ]; then
|
||||
echo domain `/bin/kenv dhcp.domain-name` > /etc/resolv.conf
|
||||
|
||||
set `/bin/kenv dhcp.domain-name-servers`
|
||||
for ns in `IFS=','; echo $*`; do
|
||||
echo nameserver $ns >> /etc/resolv.conf;
|
||||
done
|
||||
fi
|
||||
|
||||
-167
@@ -1,167 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 1999 Matt Dillon
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
# PROVIDE: diskless
|
||||
# REQUIRE: initdiskless rcconf mountcritlocal
|
||||
# BEFORE: addswap random
|
||||
# KEYWORD: FreeBSD
|
||||
|
||||
dlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null`
|
||||
[ ${dlv:=0} -eq 0 ] && exit 0
|
||||
|
||||
name="diskless2"
|
||||
|
||||
# Provide a function for normalizing the mounting of memory
|
||||
# filesystems. This should allow the rest of the code here to remain
|
||||
# as close as possible between 5-current and 4-stable.
|
||||
# $1 = size
|
||||
# $2 = mount point
|
||||
# $3 = (optional) bytes-per-inode
|
||||
mount_md() {
|
||||
if [ -n "$3" ]; then
|
||||
bpi="-i $3"
|
||||
fi
|
||||
/sbin/mdmfs $bpi -s $1 -M md $2
|
||||
}
|
||||
|
||||
# If there is a global system configuration file, suck it in.
|
||||
#
|
||||
if [ -r /etc/rc.subr ]; then
|
||||
. /etc/rc.subr
|
||||
load_rc_config $name
|
||||
elif [ -r /etc/defaults/rc.conf ]; then
|
||||
. /etc/defaults/rc.conf
|
||||
source_rc_confs
|
||||
elif [ -r /etc/rc.conf ]; then
|
||||
. /etc/rc.conf
|
||||
fi
|
||||
|
||||
# If we do not have a writable /var, create a memory
|
||||
# filesystem for /var. We don't have /usr yet so
|
||||
# use mkdir instead of touch to test. We want mount
|
||||
# to record its mounts so we have to make sure /var/db
|
||||
# exists before doing the mount -a.
|
||||
#
|
||||
if (/bin/mkdir /var/.diskless 2> /dev/null); then
|
||||
rmdir /var/.diskless
|
||||
else
|
||||
echo "+++ mount_md of /var"
|
||||
mount_md ${varsize:=32m} /var
|
||||
fi
|
||||
|
||||
if [ ! -d /var/db ]; then
|
||||
mkdir /var/db
|
||||
fi
|
||||
|
||||
# Now we need the rest of our mounts, particularly /usr
|
||||
#
|
||||
mount -a # chown and chgrp are in /usr
|
||||
|
||||
# Populate /var
|
||||
#
|
||||
echo "+++ populate /var using /etc/mtree/BSD.var.dist"
|
||||
/usr/sbin/mtree -deU -f /etc/mtree/BSD.var.dist -p /var > /dev/null
|
||||
case ${sendmail_enable} in
|
||||
[Nn][Oo][Nn][Ee])
|
||||
;;
|
||||
*)
|
||||
/usr/sbin/mtree -deU -f /etc/mtree/BSD.sendmail.dist -p / > /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "+++ create log files based on the contents of /etc/newsyslog.conf"
|
||||
LOGFILES=`/usr/bin/awk '$1 != "#" { printf "%s ", $1 } ' /etc/newsyslog.conf`
|
||||
if [ -n "$LOGFILES" ]; then
|
||||
/usr/bin/touch $LOGFILES
|
||||
fi
|
||||
|
||||
echo "+++ create lastlog"
|
||||
/usr/bin/touch /var/log/lastlog
|
||||
|
||||
# Make sure our aliases database is uptodate, the aliases may have
|
||||
# been overriden in /conf.
|
||||
#
|
||||
/usr/bin/newaliases
|
||||
|
||||
# XXX make sure to create one dir for each printer as requested by lpd
|
||||
#
|
||||
# If we do not have a writable /tmp, create a memory
|
||||
# filesystem for /tmp. If /tmp is a symlink (e.g. to /var/tmp,
|
||||
# then it should already be writable).
|
||||
#
|
||||
if (/bin/mkdir /tmp/.diskless 2> /dev/null); then
|
||||
rmdir /tmp/.diskless
|
||||
else
|
||||
if [ -h /tmp ]; then
|
||||
echo "*** /tmp is a symlink to a non-writable area!"
|
||||
echo "dropping into shell, ^D to continue anyway."
|
||||
/bin/sh
|
||||
else
|
||||
mount_md ${tmpsize:=20480} /tmp
|
||||
chmod 01777 /tmp
|
||||
fi
|
||||
fi
|
||||
|
||||
if sysctl vfs.devfs.generation > /dev/null 2>&1 ; then
|
||||
# we have DEVFS, no worries...
|
||||
true
|
||||
elif (/bin/mkdir /dev/.diskless 2> /dev/null); then
|
||||
# if /dev is writable assume it has already been populated
|
||||
# via /etc/rc.d/initdiskless
|
||||
#
|
||||
rmdir /dev/.diskless
|
||||
else
|
||||
(cd /; find -x dev | cpio -o -H newc) > /tmp/dev.tmp
|
||||
mount_md 4096 /dev 512
|
||||
(cd /; cpio -i -H newc -d < /tmp/dev.tmp)
|
||||
rm -f /tmp/dev.tmp
|
||||
fi
|
||||
|
||||
# generate our hostname
|
||||
#
|
||||
if [ -z "`hostname -s`" -a \
|
||||
"x`/bin/kenv dhcp.host-name`" != "x" ]; then
|
||||
hostname=`/bin/kenv dhcp.host-name`
|
||||
hostname $hostname
|
||||
echo "Hostname is $hostname"
|
||||
fi
|
||||
|
||||
# if the info is available via dhcp/kenv
|
||||
# build the resolv.conf
|
||||
#
|
||||
if [ ! -e /etc/resolv.conf -a \
|
||||
"x`/bin/kenv dhcp.domain-name-servers`" != "x" ]; then
|
||||
echo domain `/bin/kenv dhcp.domain-name` > /etc/resolv.conf
|
||||
|
||||
set `/bin/kenv dhcp.domain-name-servers`
|
||||
for ns in `IFS=','; echo $*`; do
|
||||
echo nameserver $ns >> /etc/resolv.conf;
|
||||
done
|
||||
fi
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 1999 Matt Dillon
|
||||
# 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.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
# PROVIDE: initdiskless
|
||||
# KEYWORD: FreeBSD
|
||||
|
||||
|
||||
# On entry to this script the entire system consists of a read-only root
|
||||
# mounted via NFS. We use the contents of /conf to create and populate
|
||||
# memory filesystems. The kernel has run BOOTP and configured an interface
|
||||
# (otherwise it would not have been able to mount the NFS root!)
|
||||
#
|
||||
# The following directories are scanned. Each sucessive directory overrides
|
||||
# (is merged into) the previous one.
|
||||
#
|
||||
# /conf/base universal base
|
||||
# /conf/default modified by a secondary universal base
|
||||
# /conf/${ipba} modified based on the assigned broadcast IP
|
||||
# /conf/${ip} modified based on the machine's assigned IP
|
||||
#
|
||||
# Each of these directories may contain any number of subdirectories which
|
||||
# represent directories in / on the diskless machine. The existance of
|
||||
# these subdirectories causes this script to create a MEMORY FILESYSTEM for
|
||||
# /<sub_directory_name>. For example, if /conf/base/etc exists then a
|
||||
# memory filesystem will be created for /etc.
|
||||
#
|
||||
# If a subdirectory contains the file 'diskless_remount' the contents of
|
||||
# the file is used to remount the subdirectory prior to it being copied to
|
||||
# the memory filesystem. For example, if /conf/base/etc/diskless_remount
|
||||
# contains the string 'my.server.com:/etc' then my.server.com:/etc will be
|
||||
# mounted in place of the subdirectory. This allows you to avoid making
|
||||
# duplicates of system directories in /conf.
|
||||
#
|
||||
# If a subdirectory contains the file 'md_size', the contents of the
|
||||
# file is used to determine the size of the memory filesystem, in 512
|
||||
# byte sectors. The default is 10240 (5MB). You only have to specify an
|
||||
# md_size if the default doesn't work for you (i.e. if it is too big or
|
||||
# too small). For example, /conf/base/etc/md_size might contain '16384'.
|
||||
#
|
||||
# If /conf/<special_dir>/SUBDIR.cpio.gz exists, the file is cpio'd into
|
||||
# the specified /SUBDIR (and a memory filesystem is created for /SUBDIR
|
||||
# if necessary).
|
||||
#
|
||||
# If /conf/<special_dir>/SUBDIR.remove exists, the file contains a list
|
||||
# of paths which are rm -rf'd relative to /SUBDIR.
|
||||
#
|
||||
# You will almost universally want to create a /conf/base/etc containing
|
||||
# a diskless_remount and possibly an md_size file. You will then almost
|
||||
# universally want to override rc.conf, rc.local, and fstab by creating
|
||||
# /conf/default/etc/{rc.conf,rc.local,fstab}. Your fstab should be sure
|
||||
# to mount a /usr... typically an NFS readonly /usr.
|
||||
#
|
||||
# NOTE! /etc/rc.d/diskless will create /var, /tmp, and /dev.
|
||||
# Those filesystems should not be specified in /conf. At least not yet.
|
||||
|
||||
dlv=`/sbin/sysctl -n vfs.nfs.diskless_valid 2> /dev/null`
|
||||
[ ${dlv:=0} -eq 0 ] && exit 0
|
||||
|
||||
# chkerr:
|
||||
#
|
||||
# Routine to check for error
|
||||
#
|
||||
# checks error code and drops into shell on failure.
|
||||
# if shell exits, terminates script as well as /etc/rc.
|
||||
#
|
||||
chkerr() {
|
||||
case $1 in
|
||||
0)
|
||||
;;
|
||||
*)
|
||||
echo "$2 failed: dropping into /bin/sh"
|
||||
/bin/sh
|
||||
# RESUME
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Create a generic memory disk
|
||||
#
|
||||
mount_md() {
|
||||
/sbin/mdmfs -i 4096 -s $1 -M md $2
|
||||
}
|
||||
|
||||
# Create the memory filesystem if it has not already been created
|
||||
#
|
||||
create_md() {
|
||||
if [ "x`eval echo \\$md_created_$1`" = "x" ]; then
|
||||
if [ "x`eval echo \\$md_size_$1`" = "x" ]; then
|
||||
md_size=10240
|
||||
else
|
||||
md_size=`eval echo \\$md_size_$1`
|
||||
fi
|
||||
mount_md $md_size /$1
|
||||
/bin/chmod 755 /$1
|
||||
eval md_created_$1=created
|
||||
fi
|
||||
}
|
||||
|
||||
# DEBUGGING
|
||||
#
|
||||
# set -v
|
||||
|
||||
# Figure out our interface and IP.
|
||||
#
|
||||
bootp_ifc=""
|
||||
bootp_ipa=""
|
||||
bootp_ipbca=""
|
||||
iflist=`ifconfig -l`
|
||||
for i in ${iflist} ; do
|
||||
set `ifconfig ${i}`
|
||||
while [ $# -ge 1 ] ; do
|
||||
if [ "${bootp_ifc}" = "" -a "$1" = "inet" ] ; then
|
||||
bootp_ifc=${i} ; bootp_ipa=${2} ; shift
|
||||
fi
|
||||
if [ "${bootp_ipbca}" = "" -a "$1" = "broadcast" ] ; then
|
||||
bootp_ipbca=$2; shift
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if [ "${bootp_ifc}" != "" ] ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo "Interface ${bootp_ifc} IP-Address ${bootp_ipa} Broadcast ${bootp_ipbca}"
|
||||
|
||||
# Figure out our NFS root path
|
||||
#
|
||||
set `mount -t nfs`
|
||||
while [ $# -ge 1 ] ; do
|
||||
if [ "$2" = "on" -a "$3" = "/" ]; then
|
||||
nfsroot="$1"
|
||||
break
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
# Resolve templates in /conf/base, /conf/default, /conf/${bootp_ipbca},
|
||||
# and /conf/${bootp_ipa}. For each subdirectory found within these
|
||||
# directories:
|
||||
#
|
||||
# - calculate memory filesystem sizes. If the subdirectory (prior to
|
||||
# NFS remounting) contains the file 'md_size', the contents specified
|
||||
# in 512 byte sectors will be used to size the memory filesystem. Otherwise
|
||||
# 8192 sectors (4MB) is used.
|
||||
#
|
||||
# - handle NFS remounts. If the subdirectory contains the file
|
||||
# diskless_remount, the contents of the file is NFS mounted over
|
||||
# the directory. For example /conf/base/etc/diskless_remount
|
||||
# might contain 'myserver:/etc'. NFS remounts allow you to avoid
|
||||
# having to dup your system directories in /conf. Your server must
|
||||
# be sure to export those filesystems -alldirs, however.
|
||||
# If the diskless_remount file contains a string beginning with a
|
||||
# '/' it is assumed that the local nfsroot should be prepended to
|
||||
# it before attemping to the remount. This allows the root to be
|
||||
# relocated without needing to change the remount files.
|
||||
#
|
||||
for i in base default ${bootp_ipbca} ${bootp_ipa} ; do
|
||||
for j in /conf/$i/* ; do
|
||||
# memory filesystem size specification
|
||||
#
|
||||
subdir=${j##*/}
|
||||
if [ -d $j -a -f $j/md_size ]; then
|
||||
eval md_size_$subdir=`cat $j/md_size`
|
||||
fi
|
||||
|
||||
# NFS remount
|
||||
#
|
||||
if [ -d $j -a -f $j/diskless_remount ]; then
|
||||
nfspt=`/bin/cat $j/diskless_remount`
|
||||
if [ `expr "$nfspt" : '\(.\)'` = "/" ]; then
|
||||
nfspt="${nfsroot}${nfspt}"
|
||||
fi
|
||||
mount_nfs $nfspt $j
|
||||
chkerr $? "mount_nfs $nfspt $j"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# - Create all required MFS filesystems and populate them from
|
||||
# our templates. Support both a direct template and a dir.cpio.gz
|
||||
# archive. Support dir.remove files containing a list of relative
|
||||
# paths to remove.
|
||||
#
|
||||
# TODO:
|
||||
# + find a way to assign a 'group' identifier to a machine
|
||||
# so we can use group-specific configurations;
|
||||
|
||||
for i in base default ${bootp_ipbca} ${bootp_ipa} ; do
|
||||
for j in /conf/$i/* ; do
|
||||
subdir=${j##*/}
|
||||
if [ -d $j ]; then
|
||||
create_md $subdir
|
||||
cp -Rp $j/* /$subdir
|
||||
fi
|
||||
done
|
||||
for j in /conf/$i/*.cpio.gz ; do
|
||||
subdir=${j%*.cpio.gz}
|
||||
subdir=${subdir##*/}
|
||||
if [ -f $j ]; then
|
||||
create_md $subdir
|
||||
echo "Loading /$subdir from cpio archive $j"
|
||||
(cd / ; /stand/gzip -d < $j | /stand/cpio --extract -d )
|
||||
fi
|
||||
done
|
||||
for j in /conf/$i/*.remove ; do
|
||||
subdir=${j%*.remove}
|
||||
subdir=${subdir##*/}
|
||||
if [ -f $j ]; then
|
||||
# doubly sure it is a memory disk before rm -rf'ing
|
||||
create_md $subdir
|
||||
(cd /$subdir; rm -rf `/bin/cat $j`)
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
@@ -132,8 +132,8 @@ GDB_VERSION= "5.2.1 (FreeBSD)"
|
||||
gdbversion.c:
|
||||
@echo '#include "version.h"' > ${.TARGET}
|
||||
@echo 'const char version[] = ${GDB_VERSION};' >>${.TARGET}
|
||||
@echo 'const char host_name[] = "${MACHINE_ARCH}-undermydesk-freebsd";' >>${.TARGET}
|
||||
@echo 'const char target_name[] = "${TARGET_ARCH}-undermydesk-freebsd";' >>${.TARGET}
|
||||
@echo 'const char host_name[] = "${MACHINE_ARCH}-unknown-freebsd";' >>${.TARGET}
|
||||
@echo 'const char target_name[] = "${TARGET_ARCH}-unknown-freebsd";' >>${.TARGET}
|
||||
|
||||
xregex.h:
|
||||
@echo '#include <gnuregex.h>' >${.TARGET}
|
||||
|
||||
@@ -12,7 +12,7 @@ GCCDIR= ${.CURDIR}/../../../../contrib/gcc
|
||||
|
||||
# Machine description.
|
||||
MD_FILE= ${GCCDIR}/config/${GCC_CPU}/${GCC_CPU}.md
|
||||
target= ${TARGET_ARCH}-undermydesk-freebsd
|
||||
target= ${TARGET_ARCH}-unknown-freebsd
|
||||
|
||||
CFLAGS+= -DIN_GCC -DHAVE_CONFIG_H
|
||||
CFLAGS+= -DPREFIX=\"${TOOLS_PREFIX}/usr\"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
.PATH: ${GCCDIR}/config/${GCC_CPU}
|
||||
|
||||
.if ${TARGET_ARCH} == "i386" || ${TARGET_ARCH} == "amd64"
|
||||
INCS= mmintrin.h xmmintrin.h
|
||||
INCS= emmintrin.h mmintrin.h pmmintrin.h xmmintrin.h
|
||||
.elif ${TARGET_ARCH} == "ia64"
|
||||
INCS= ia64intrin.h
|
||||
.endif
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
$FreeBSD$
|
||||
|
||||
--- inc-hist.texinfo.orig Wed Apr 11 08:20:01 2001
|
||||
+++ inc-hist.texinfo Wed Apr 11 08:21:57 2001
|
||||
@@ -26,9 +26,9 @@
|
||||
@node Using History Interactively
|
||||
@chapter Using History Interactively
|
||||
|
||||
-@ifclear BashFeatures
|
||||
-@defcodeindex bt
|
||||
-@end ifclear
|
||||
+@c @ifclear BashFeatures
|
||||
+@c @defcodeindex bt
|
||||
+@c @end ifclear
|
||||
|
||||
@ifset BashFeatures
|
||||
This chapter describes how to use the @sc{gnu} History Library
|
||||
@@ -39,9 +39,10 @@
|
||||
@end ifset
|
||||
@ifclear BashFeatures
|
||||
This chapter describes how to use the @sc{gnu} History Library interactively,
|
||||
-from a user's standpoint. It should be considered a user's guide. For
|
||||
-information on using the @sc{gnu} History Library in your own programs,
|
||||
-@pxref{Programming with GNU History}.
|
||||
+from a user's standpoint.
|
||||
+@c It should be considered a user's guide. For
|
||||
+@c information on using the @sc{gnu} History Library in your own programs,
|
||||
+@c @pxref{Programming with GNU History}.
|
||||
@end ifclear
|
||||
|
||||
@ifset BashFeatures
|
||||
@@ -55,7 +55,7 @@
|
||||
.ds doc-str-Lb-libvgl Video Graphics Library (libvgl, \-lvgl)
|
||||
.
|
||||
.\" Default .Os value
|
||||
.ds doc-default-operating-system FreeBSD\~5.1
|
||||
.ds doc-default-operating-system FreeBSD\~5.2
|
||||
.
|
||||
.\" FreeBSD releases not found in doc-common
|
||||
.ds doc-operating-system-FreeBSD-4.9 4.9
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Paul Borman at Krystal Technologies.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @(#)ctype.h 8.4 (Berkeley) 1/21/94
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _CTYPE_H_
|
||||
#define _CTYPE_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_types.h>
|
||||
|
||||
#define _CTYPE_A 0x00000100L /* Alpha */
|
||||
#define _CTYPE_C 0x00000200L /* Control */
|
||||
#define _CTYPE_D 0x00000400L /* Digit */
|
||||
#define _CTYPE_G 0x00000800L /* Graph */
|
||||
#define _CTYPE_L 0x00001000L /* Lower */
|
||||
#define _CTYPE_P 0x00002000L /* Punct */
|
||||
#define _CTYPE_S 0x00004000L /* Space */
|
||||
#define _CTYPE_U 0x00008000L /* Upper */
|
||||
#define _CTYPE_X 0x00010000L /* X digit */
|
||||
#define _CTYPE_B 0x00020000L /* Blank */
|
||||
#define _CTYPE_R 0x00040000L /* Print */
|
||||
#define _CTYPE_I 0x00080000L /* Ideogram */
|
||||
#define _CTYPE_T 0x00100000L /* Special */
|
||||
#define _CTYPE_Q 0x00200000L /* Phonogram */
|
||||
#define _CTYPE_SW0 0x20000000L /* 0 width character */
|
||||
#define _CTYPE_SW1 0x40000000L /* 1 width character */
|
||||
#define _CTYPE_SW2 0x80000000L /* 2 width character */
|
||||
#define _CTYPE_SW3 0xc0000000L /* 3 width character */
|
||||
|
||||
__BEGIN_DECLS
|
||||
int isalnum(int);
|
||||
int isalpha(int);
|
||||
int iscntrl(int);
|
||||
int isdigit(int);
|
||||
int isgraph(int);
|
||||
int islower(int);
|
||||
int isprint(int);
|
||||
int ispunct(int);
|
||||
int isspace(int);
|
||||
int isupper(int);
|
||||
int isxdigit(int);
|
||||
int tolower(int);
|
||||
int toupper(int);
|
||||
|
||||
#if __XSI_VISIBLE
|
||||
int _tolower(int);
|
||||
int _toupper(int);
|
||||
int isascii(int);
|
||||
int toascii(int);
|
||||
#endif
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
int digittoint(int);
|
||||
int isblank(int);
|
||||
int ishexnumber(int);
|
||||
int isideogram(int);
|
||||
int isnumber(int);
|
||||
int isphonogram(int);
|
||||
int isrune(int);
|
||||
int isspecial(int);
|
||||
#endif
|
||||
__END_DECLS
|
||||
|
||||
#define isalnum(c) __istype((c), _CTYPE_A|_CTYPE_D)
|
||||
#define isalpha(c) __istype((c), _CTYPE_A)
|
||||
#define iscntrl(c) __istype((c), _CTYPE_C)
|
||||
#define isdigit(c) __isctype((c), _CTYPE_D) /* ANSI -- locale independent */
|
||||
#define isgraph(c) __istype((c), _CTYPE_G)
|
||||
#define islower(c) __istype((c), _CTYPE_L)
|
||||
#define isprint(c) __istype((c), _CTYPE_R)
|
||||
#define ispunct(c) __istype((c), _CTYPE_P)
|
||||
#define isspace(c) __istype((c), _CTYPE_S)
|
||||
#define isupper(c) __istype((c), _CTYPE_U)
|
||||
#define isxdigit(c) __isctype((c), _CTYPE_X) /* ANSI -- locale independent */
|
||||
#define tolower(c) __tolower(c)
|
||||
#define toupper(c) __toupper(c)
|
||||
|
||||
#if __XSI_VISIBLE
|
||||
/*
|
||||
* POSIX.1-2001 specifies _tolower() and _toupper() to be macros equivalent to
|
||||
* tolower() and toupper() respectively, minus extra checking to ensure that
|
||||
* the argument is a lower or uppercase letter respectively. We've chosen to
|
||||
* implement these macros with the same error checking as tolower() and
|
||||
* toupper() since this doesn't violate the specification itself, only its
|
||||
* intent. We purposely leave _tolower() and _toupper() undocumented to
|
||||
* discourage their use.
|
||||
*
|
||||
* XXX isascii() and toascii() should similarly be undocumented.
|
||||
*/
|
||||
#define _tolower(c) __tolower(c)
|
||||
#define _toupper(c) __toupper(c)
|
||||
#define isascii(c) (((c) & ~0x7F) == 0)
|
||||
#define toascii(c) ((c) & 0x7F)
|
||||
#endif
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
#define digittoint(c) __maskrune((c), 0xFF)
|
||||
#define isblank(c) __istype((c), _CTYPE_B)
|
||||
#define ishexnumber(c) __istype((c), _CTYPE_X)
|
||||
#define isideogram(c) __istype((c), _CTYPE_I)
|
||||
#define isnumber(c) __istype((c), _CTYPE_D)
|
||||
#define isphonogram(c) __istype((c), _CTYPE_Q)
|
||||
#define isrune(c) __istype((c), 0xFFFFFF00L)
|
||||
#define isspecial(c) __istype((c), _CTYPE_T)
|
||||
#endif
|
||||
|
||||
/* See comments in <sys/_types.h> about __ct_rune_t. */
|
||||
__BEGIN_DECLS
|
||||
unsigned long ___runetype(__ct_rune_t);
|
||||
__ct_rune_t ___tolower(__ct_rune_t);
|
||||
__ct_rune_t ___toupper(__ct_rune_t);
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us
|
||||
* to generate code for extern versions of all our inline functions.
|
||||
*/
|
||||
#ifdef _EXTERNALIZE_CTYPE_INLINES_
|
||||
#define _USE_CTYPE_INLINE_
|
||||
#define static
|
||||
#define __inline
|
||||
#endif
|
||||
|
||||
/*
|
||||
* <runetype.h> brings namespace pollution (struct member names). This prevents
|
||||
* us from using the inline optimizations in the more strict __POSIX_VISIBLE and
|
||||
* __XSI_VISIBLE namespaces. To fix this properly would require that we rename
|
||||
* member names of long-standing structs, or something equally evil.
|
||||
*/
|
||||
#if !__BSD_VISIBLE && !defined(_USE_CTYPE_INLINE_) && \
|
||||
!defined(_DONT_USE_CTYPE_INLINE_)
|
||||
#define _DONT_USE_CTYPE_INLINE_
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use inline functions if we are allowed to and the compiler supports them.
|
||||
*/
|
||||
#if !defined(_DONT_USE_CTYPE_INLINE_) && \
|
||||
(defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus))
|
||||
|
||||
#include <runetype.h>
|
||||
|
||||
static __inline int
|
||||
__maskrune(__ct_rune_t _c, unsigned long _f)
|
||||
{
|
||||
return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype(_c) :
|
||||
_CurrentRuneLocale->runetype[_c]) & _f;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
__istype(__ct_rune_t _c, unsigned long _f)
|
||||
{
|
||||
return (!!__maskrune(_c, _f));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
__isctype(__ct_rune_t _c, unsigned long _f)
|
||||
{
|
||||
return (_c < 0 || _c >= _CACHED_RUNES) ? 0 :
|
||||
!!(_DefaultRuneLocale.runetype[_c] & _f);
|
||||
}
|
||||
|
||||
static __inline __ct_rune_t
|
||||
__toupper(__ct_rune_t _c)
|
||||
{
|
||||
return (_c < 0 || _c >= _CACHED_RUNES) ? ___toupper(_c) :
|
||||
_CurrentRuneLocale->mapupper[_c];
|
||||
}
|
||||
|
||||
static __inline __ct_rune_t
|
||||
__tolower(__ct_rune_t _c)
|
||||
{
|
||||
return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_c) :
|
||||
_CurrentRuneLocale->maplower[_c];
|
||||
}
|
||||
|
||||
#else /* not using inlines */
|
||||
|
||||
__BEGIN_DECLS
|
||||
int __maskrune(__ct_rune_t, unsigned long);
|
||||
int __istype(__ct_rune_t, unsigned long);
|
||||
int __isctype(__ct_rune_t, unsigned long);
|
||||
__ct_rune_t __toupper(__ct_rune_t);
|
||||
__ct_rune_t __tolower(__ct_rune_t);
|
||||
__END_DECLS
|
||||
#endif /* using inlines */
|
||||
|
||||
#endif /* !_CTYPE_H_ */
|
||||
+2
-4
@@ -54,6 +54,8 @@
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
|
||||
#include <sys/_null.h>
|
||||
|
||||
/* definitions for library routines operating on directories. */
|
||||
#define DIRBLKSIZ 1024
|
||||
|
||||
@@ -81,10 +83,6 @@ typedef struct _dirdesc {
|
||||
#define DTF_REWIND 0x0004 /* rewind after reading union stack */
|
||||
#define __DTF_READALL 0x0008 /* everything has been read */
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#else /* !__BSD_VISIBLE */
|
||||
|
||||
typedef void * DIR;
|
||||
|
||||
+2
-4
@@ -37,6 +37,8 @@
|
||||
#ifndef _LOCALE_H_
|
||||
#define _LOCALE_H_
|
||||
|
||||
#include <sys/_null.h>
|
||||
|
||||
struct lconv {
|
||||
char *decimal_point;
|
||||
char *thousands_sep;
|
||||
@@ -64,10 +66,6 @@ struct lconv {
|
||||
char int_n_sign_posn;
|
||||
};
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define LC_ALL 0
|
||||
#define LC_COLLATE 1
|
||||
#define LC_CTYPE 2
|
||||
|
||||
+1
-3
@@ -40,6 +40,7 @@
|
||||
#define _RPC_TYPES_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/_null.h>
|
||||
|
||||
typedef int32_t bool_t;
|
||||
typedef int32_t enum_t;
|
||||
@@ -59,9 +60,6 @@ typedef int32_t rpc_inline_t;
|
||||
#ifndef TRUE
|
||||
# define TRUE (1)
|
||||
#endif
|
||||
#ifndef NULL
|
||||
# define NULL 0
|
||||
#endif
|
||||
|
||||
#define mem_alloc(bsize) calloc(1, bsize)
|
||||
#define mem_free(ptr, bsize) free(ptr)
|
||||
|
||||
+1
-4
@@ -39,6 +39,7 @@
|
||||
#define _STDDEF_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_null.h>
|
||||
#include <sys/_types.h>
|
||||
|
||||
typedef __ptrdiff_t ptrdiff_t;
|
||||
@@ -62,10 +63,6 @@ typedef __wchar_t wchar_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define offsetof(type, member) __offsetof(type, member)
|
||||
|
||||
#endif /* _STDDEF_H_ */
|
||||
+1
-4
@@ -41,6 +41,7 @@
|
||||
#define _STDIO_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_null.h>
|
||||
#include <sys/_types.h>
|
||||
|
||||
typedef __off_t fpos_t;
|
||||
@@ -57,10 +58,6 @@ typedef __va_list va_list;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define _FSTDIO /* Define for new stdio with functions. */
|
||||
|
||||
/*
|
||||
|
||||
+1
-4
@@ -38,6 +38,7 @@
|
||||
#define _STDLIB_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_null.h>
|
||||
#include <sys/_types.h>
|
||||
|
||||
#if __BSD_VISIBLE
|
||||
@@ -69,10 +70,6 @@ typedef struct {
|
||||
long rem;
|
||||
} ldiv_t;
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define EXIT_FAILURE 1
|
||||
#define EXIT_SUCCESS 0
|
||||
|
||||
|
||||
+1
-4
@@ -38,6 +38,7 @@
|
||||
#define _STRING_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_null.h>
|
||||
#include <sys/_types.h>
|
||||
|
||||
/*
|
||||
@@ -53,10 +54,6 @@ typedef __size_t size_t;
|
||||
#define _SIZE_T_DECLARED
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
|
||||
void *memccpy(void * __restrict, const void * __restrict, int, size_t);
|
||||
|
||||
+1
-4
@@ -46,6 +46,7 @@
|
||||
#define _TIME_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_null.h>
|
||||
#include <sys/_types.h>
|
||||
|
||||
#if __POSIX_VISIBLE > 0 && __POSIX_VISIBLE < 200112 || __BSD_VISIBLE
|
||||
@@ -59,10 +60,6 @@
|
||||
/* Frequency of the clock ticks reported by clock(). */
|
||||
#define CLOCKS_PER_SEC 128
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef _CLOCK_T_DECLARED
|
||||
typedef __clock_t clock_t;
|
||||
#define _CLOCK_T_DECLARED
|
||||
|
||||
+1
-4
@@ -40,6 +40,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h> /* XXX adds too much pollution. */
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/_null.h>
|
||||
#include <sys/_types.h>
|
||||
|
||||
#ifndef _GID_T_DECLARED
|
||||
@@ -81,10 +82,6 @@ typedef __useconds_t useconds_t;
|
||||
#define STDOUT_FILENO 1 /* standard output file descriptor */
|
||||
#define STDERR_FILENO 2 /* standard error file descriptor */
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0 /* null pointer constant */
|
||||
#endif
|
||||
|
||||
#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200112
|
||||
#define F_ULOCK 0 /* unlock locked section */
|
||||
#define F_LOCK 1 /* lock a section for exclusive use */
|
||||
|
||||
+1
-4
@@ -68,13 +68,10 @@
|
||||
#define _WCHAR_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_null.h>
|
||||
#include <sys/_types.h>
|
||||
#include <machine/_limits.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef _MBSTATE_T_DECLARED
|
||||
typedef __mbstate_t mbstate_t;
|
||||
#define _MBSTATE_T_DECLARED
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 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.
|
||||
*
|
||||
* @(#)fts.h 8.3 (Berkeley) 8/14/94
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _FTS_H_
|
||||
#define _FTS_H_
|
||||
|
||||
typedef struct {
|
||||
struct _ftsent *fts_cur; /* current node */
|
||||
struct _ftsent *fts_child; /* linked list of children */
|
||||
struct _ftsent **fts_array; /* sort array */
|
||||
dev_t fts_dev; /* starting device # */
|
||||
char *fts_path; /* path for this descent */
|
||||
int fts_rfd; /* fd for root */
|
||||
int fts_pathlen; /* sizeof(path) */
|
||||
int fts_nitems; /* elements in the sort array */
|
||||
int (*fts_compar) /* compare function */
|
||||
(const struct _ftsent * const *, const struct _ftsent * const *);
|
||||
|
||||
#define FTS_COMFOLLOW 0x001 /* follow command line symlinks */
|
||||
#define FTS_LOGICAL 0x002 /* logical walk */
|
||||
#define FTS_NOCHDIR 0x004 /* don't change directories */
|
||||
#define FTS_NOSTAT 0x008 /* don't get stat info */
|
||||
#define FTS_PHYSICAL 0x010 /* physical walk */
|
||||
#define FTS_SEEDOT 0x020 /* return dot and dot-dot */
|
||||
#define FTS_XDEV 0x040 /* don't cross devices */
|
||||
#define FTS_WHITEOUT 0x080 /* return whiteout information */
|
||||
#define FTS_OPTIONMASK 0x0ff /* valid user option mask */
|
||||
|
||||
#define FTS_NAMEONLY 0x100 /* (private) child names only */
|
||||
#define FTS_STOP 0x200 /* (private) unrecoverable error */
|
||||
int fts_options; /* fts_open options, global flags */
|
||||
void *fts_clientptr; /* thunk for sort function */
|
||||
} FTS;
|
||||
|
||||
typedef struct _ftsent {
|
||||
struct _ftsent *fts_cycle; /* cycle node */
|
||||
struct _ftsent *fts_parent; /* parent directory */
|
||||
struct _ftsent *fts_link; /* next file in directory */
|
||||
long fts_number; /* local numeric value */
|
||||
void *fts_pointer; /* local address value */
|
||||
char *fts_accpath; /* access path */
|
||||
char *fts_path; /* root path */
|
||||
int fts_errno; /* errno for this node */
|
||||
int fts_symfd; /* fd for symlink */
|
||||
u_short fts_pathlen; /* strlen(fts_path) */
|
||||
u_short fts_namelen; /* strlen(fts_name) */
|
||||
|
||||
ino_t fts_ino; /* inode */
|
||||
dev_t fts_dev; /* device */
|
||||
nlink_t fts_nlink; /* link count */
|
||||
|
||||
#define FTS_ROOTPARENTLEVEL -1
|
||||
#define FTS_ROOTLEVEL 0
|
||||
short fts_level; /* depth (-1 to N) */
|
||||
|
||||
#define FTS_D 1 /* preorder directory */
|
||||
#define FTS_DC 2 /* directory that causes cycles */
|
||||
#define FTS_DEFAULT 3 /* none of the above */
|
||||
#define FTS_DNR 4 /* unreadable directory */
|
||||
#define FTS_DOT 5 /* dot or dot-dot */
|
||||
#define FTS_DP 6 /* postorder directory */
|
||||
#define FTS_ERR 7 /* error; errno is set */
|
||||
#define FTS_F 8 /* regular file */
|
||||
#define FTS_INIT 9 /* initialized only */
|
||||
#define FTS_NS 10 /* stat(2) failed */
|
||||
#define FTS_NSOK 11 /* no stat(2) requested */
|
||||
#define FTS_SL 12 /* symbolic link */
|
||||
#define FTS_SLNONE 13 /* symbolic link without target */
|
||||
#define FTS_W 14 /* whiteout object */
|
||||
u_short fts_info; /* user flags for FTSENT structure */
|
||||
|
||||
#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */
|
||||
#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */
|
||||
#define FTS_ISW 0x04 /* this is a whiteout object */
|
||||
u_short fts_flags; /* private flags for FTSENT structure */
|
||||
|
||||
#define FTS_AGAIN 1 /* read node again */
|
||||
#define FTS_FOLLOW 2 /* follow symbolic link */
|
||||
#define FTS_NOINSTR 3 /* no instructions */
|
||||
#define FTS_SKIP 4 /* discard node */
|
||||
u_short fts_instr; /* fts_set() instructions */
|
||||
|
||||
struct stat *fts_statp; /* stat(2) information */
|
||||
char *fts_name; /* file name */
|
||||
FTS *fts_fts; /* back pointer to main FTS */
|
||||
} FTSENT;
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
FTSENT *fts_children(FTS *, int);
|
||||
int fts_close(FTS *);
|
||||
void *fts_get_clientptr(FTS *);
|
||||
#define fts_get_clientptr(fts) ((fts)->fts_clientptr)
|
||||
FTS *fts_get_stream(FTSENT *);
|
||||
#define fts_get_stream(ftsent) ((ftsent)->fts_fts)
|
||||
FTS *fts_open(char * const *, int,
|
||||
int (*)(const FTSENT * const *, const FTSENT * const *));
|
||||
FTSENT *fts_read(FTS *);
|
||||
int fts_set(FTS *, FTSENT *, int);
|
||||
void fts_set_clientptr(FTS *, void *);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_FTS_H_ */
|
||||
@@ -1,357 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2000 Jason Evans <[email protected]>.
|
||||
* 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(s), this list of conditions and the following disclaimer as
|
||||
* the first lines of this file unmodified other than the possible
|
||||
* addition of one or more copyright notices.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdarg.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/queue.h>
|
||||
#include <_semaphore.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#define _SEM_CHECK_VALIDITY(sem) \
|
||||
if ((*(sem))->magic != SEM_MAGIC) { \
|
||||
errno = EINVAL; \
|
||||
retval = -1; \
|
||||
goto RETURN; \
|
||||
}
|
||||
|
||||
static sem_t sem_alloc(unsigned int value, semid_t semid, int system_sem);
|
||||
static void sem_free(sem_t sem);
|
||||
|
||||
static LIST_HEAD(, sem) named_sems = LIST_HEAD_INITIALIZER(&named_sems);
|
||||
static pthread_mutex_t named_sems_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static void
|
||||
sem_free(sem_t sem)
|
||||
{
|
||||
|
||||
_pthread_mutex_destroy(&sem->lock);
|
||||
_pthread_cond_destroy(&sem->gtzero);
|
||||
sem->magic = 0;
|
||||
free(sem);
|
||||
}
|
||||
|
||||
static sem_t
|
||||
sem_alloc(unsigned int value, semid_t semid, int system_sem)
|
||||
{
|
||||
sem_t sem;
|
||||
|
||||
if (value > SEM_VALUE_MAX) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
sem = (sem_t)malloc(sizeof(struct sem));
|
||||
if (sem == NULL) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the semaphore.
|
||||
*/
|
||||
if (_pthread_mutex_init(&sem->lock, NULL) != 0) {
|
||||
free(sem);
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (_pthread_cond_init(&sem->gtzero, NULL) != 0) {
|
||||
_pthread_mutex_destroy(&sem->lock);
|
||||
free(sem);
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
sem->count = (u_int32_t)value;
|
||||
sem->nwaiters = 0;
|
||||
sem->magic = SEM_MAGIC;
|
||||
sem->semid = semid;
|
||||
sem->syssem = system_sem;
|
||||
return (sem);
|
||||
}
|
||||
|
||||
int
|
||||
sem_init(sem_t *sem, int pshared, unsigned int value)
|
||||
{
|
||||
int retval, got_system_sem;
|
||||
semid_t semid;
|
||||
|
||||
got_system_sem = 0;
|
||||
semid = SEM_USER;
|
||||
/*
|
||||
* Range check the arguments.
|
||||
*/
|
||||
if (pshared != 0) {
|
||||
retval = ksem_init(&semid, value);
|
||||
if (retval == -1)
|
||||
goto RETURN;
|
||||
got_system_sem = 1;
|
||||
}
|
||||
|
||||
(*sem) = sem_alloc(value, semid, got_system_sem);
|
||||
if ((*sem) == NULL)
|
||||
retval = -1;
|
||||
else
|
||||
retval = 0;
|
||||
RETURN:
|
||||
if (retval != 0 && got_system_sem)
|
||||
ksem_destroy(semid);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
sem_destroy(sem_t *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
_SEM_CHECK_VALIDITY(sem);
|
||||
|
||||
_pthread_mutex_lock(&(*sem)->lock);
|
||||
/*
|
||||
* If this is a system semaphore let the kernel track it otherwise
|
||||
* make sure there are no waiters.
|
||||
*/
|
||||
if ((*sem)->syssem != 0) {
|
||||
retval = ksem_destroy((*sem)->semid);
|
||||
if (retval == -1) {
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
goto RETURN;
|
||||
}
|
||||
} else if ((*sem)->nwaiters > 0) {
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
errno = EBUSY;
|
||||
retval = -1;
|
||||
goto RETURN;
|
||||
}
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
|
||||
sem_free(*sem);
|
||||
|
||||
retval = 0;
|
||||
RETURN:
|
||||
return retval;
|
||||
}
|
||||
|
||||
sem_t *
|
||||
sem_open(const char *name, int oflag, ...)
|
||||
{
|
||||
sem_t *sem;
|
||||
sem_t s;
|
||||
semid_t semid;
|
||||
mode_t mode;
|
||||
unsigned int value;
|
||||
|
||||
mode = 0;
|
||||
value = 0;
|
||||
|
||||
if ((oflag & O_CREAT) != 0) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, oflag);
|
||||
mode = va_arg(ap, int);
|
||||
value = va_arg(ap, unsigned int);
|
||||
va_end(ap);
|
||||
}
|
||||
/*
|
||||
* we can be lazy and let the kernel handle the "oflag",
|
||||
* we'll just merge duplicate IDs into our list.
|
||||
*/
|
||||
if (ksem_open(&semid, name, oflag, mode, value) == -1)
|
||||
return (SEM_FAILED);
|
||||
/*
|
||||
* search for a duplicate ID, we must return the same sem_t *
|
||||
* if we locate one.
|
||||
*/
|
||||
_pthread_mutex_lock(&named_sems_mtx);
|
||||
LIST_FOREACH(s, &named_sems, entry) {
|
||||
if (s->semid == semid) {
|
||||
_pthread_mutex_unlock(&named_sems_mtx);
|
||||
return (s->backpointer);
|
||||
}
|
||||
}
|
||||
sem = (sem_t *)malloc(sizeof(*sem));
|
||||
if (sem == NULL)
|
||||
goto err;
|
||||
*sem = sem_alloc(value, semid, 1);
|
||||
if ((*sem) == NULL)
|
||||
goto err;
|
||||
LIST_INSERT_HEAD(&named_sems, *sem, entry);
|
||||
(*sem)->backpointer = sem;
|
||||
_pthread_mutex_unlock(&named_sems_mtx);
|
||||
return (sem);
|
||||
err:
|
||||
_pthread_mutex_unlock(&named_sems_mtx);
|
||||
ksem_close(semid);
|
||||
if (sem != NULL) {
|
||||
if (*sem != NULL)
|
||||
sem_free(*sem);
|
||||
else
|
||||
errno = ENOSPC;
|
||||
free(sem);
|
||||
} else {
|
||||
errno = ENOSPC;
|
||||
}
|
||||
return (SEM_FAILED);
|
||||
}
|
||||
|
||||
int
|
||||
sem_close(sem_t *sem)
|
||||
{
|
||||
|
||||
if ((*sem)->syssem == 0) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
_pthread_mutex_lock(&named_sems_mtx);
|
||||
if (ksem_close((*sem)->semid) == -1) {
|
||||
_pthread_mutex_unlock(&named_sems_mtx);
|
||||
return (-1);
|
||||
}
|
||||
LIST_REMOVE((*sem), entry);
|
||||
_pthread_mutex_unlock(&named_sems_mtx);
|
||||
sem_free(*sem);
|
||||
free(sem);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
sem_unlink(const char *name)
|
||||
{
|
||||
|
||||
return (ksem_unlink(name));
|
||||
}
|
||||
|
||||
int
|
||||
sem_wait(sem_t *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
_SEM_CHECK_VALIDITY(sem);
|
||||
|
||||
if ((*sem)->syssem != 0) {
|
||||
retval = ksem_wait((*sem)->semid);
|
||||
goto RETURN;
|
||||
}
|
||||
|
||||
_pthread_mutex_lock(&(*sem)->lock);
|
||||
|
||||
while ((*sem)->count == 0) {
|
||||
(*sem)->nwaiters++;
|
||||
_pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
|
||||
(*sem)->nwaiters--;
|
||||
}
|
||||
(*sem)->count--;
|
||||
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
|
||||
retval = 0;
|
||||
RETURN:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
sem_trywait(sem_t *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
_SEM_CHECK_VALIDITY(sem);
|
||||
|
||||
if ((*sem)->syssem != 0) {
|
||||
retval = ksem_trywait((*sem)->semid);
|
||||
goto RETURN;
|
||||
}
|
||||
|
||||
_pthread_mutex_lock(&(*sem)->lock);
|
||||
|
||||
if ((*sem)->count > 0) {
|
||||
(*sem)->count--;
|
||||
retval = 0;
|
||||
} else {
|
||||
errno = EAGAIN;
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
|
||||
RETURN:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
sem_post(sem_t *sem)
|
||||
{
|
||||
int retval;
|
||||
|
||||
_SEM_CHECK_VALIDITY(sem);
|
||||
|
||||
if ((*sem)->syssem != 0) {
|
||||
retval = ksem_post((*sem)->semid);
|
||||
goto RETURN;
|
||||
}
|
||||
|
||||
_pthread_mutex_lock(&(*sem)->lock);
|
||||
|
||||
(*sem)->count++;
|
||||
if ((*sem)->nwaiters > 0)
|
||||
_pthread_cond_signal(&(*sem)->gtzero);
|
||||
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
|
||||
retval = 0;
|
||||
RETURN:
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
sem_getvalue(sem_t * __restrict sem, int * __restrict sval)
|
||||
{
|
||||
int retval;
|
||||
|
||||
_SEM_CHECK_VALIDITY(sem);
|
||||
|
||||
if ((*sem)->syssem != 0) {
|
||||
retval = ksem_getvalue((*sem)->semid, sval);
|
||||
goto RETURN;
|
||||
}
|
||||
|
||||
_pthread_mutex_lock(&(*sem)->lock);
|
||||
*sval = (int)(*sem)->count;
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
|
||||
retval = 0;
|
||||
RETURN:
|
||||
return retval;
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
.\" Copyright (C) 2000 Jason Evans <[email protected]>.
|
||||
.\" 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(s), this list of conditions and the following disclaimer as
|
||||
.\" the first lines of this file unmodified other than the possible
|
||||
.\" addition of one or more copyright notices.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
.Dd February 15, 2000
|
||||
.Dt SEM_DESTROY 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sem_destroy
|
||||
.Nd destroy an unnamed semaphore
|
||||
.Sh LIBRARY
|
||||
.Lb libc_r
|
||||
.Sh SYNOPSIS
|
||||
.In semaphore.h
|
||||
.Ft int
|
||||
.Fn sem_destroy "sem_t *sem"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn sem_destroy
|
||||
function destroys the unnamed semaphore pointed to by
|
||||
.Fa sem .
|
||||
After a successful call to
|
||||
.Fn sem_destroy ,
|
||||
.Fa sem
|
||||
is unusable until re-initialized by another call to
|
||||
.Fn sem_init .
|
||||
.Sh RETURN VALUES
|
||||
.Rv -std sem_destroy
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn sem_destroy
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
.Fa sem
|
||||
points to an invalid semaphore.
|
||||
.It Bq Er EBUSY
|
||||
There are currently threads blocked on the semaphore that
|
||||
.Fa sem
|
||||
points to.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sem_init 3 ,
|
||||
.Xr sem 4
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn sem_destroy
|
||||
function conforms to
|
||||
.St -p1003.1-96 .
|
||||
.Pp
|
||||
POSIX does not define the behavior of
|
||||
.Fn sem_destroy
|
||||
if called while there are threads blocked on
|
||||
.Fa sem ,
|
||||
but this implementation is guaranteed to return -1 and set
|
||||
.Va errno
|
||||
to
|
||||
.Er EBUSY
|
||||
if there are threads blocked on
|
||||
.Fa sem .
|
||||
@@ -1,76 +0,0 @@
|
||||
.\" Copyright (C) 2000 Jason Evans <[email protected]>.
|
||||
.\" 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(s), this list of conditions and the following disclaimer as
|
||||
.\" the first lines of this file unmodified other than the possible
|
||||
.\" addition of one or more copyright notices.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
.Dd February 15, 2000
|
||||
.Dt SEM_GETVALUE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sem_getvalue
|
||||
.Nd get the value of a semaphore
|
||||
.Sh LIBRARY
|
||||
.Lb libc_r
|
||||
.Sh SYNOPSIS
|
||||
.In semaphore.h
|
||||
.Ft int
|
||||
.Fn sem_getvalue "sem_t * restrict sem" "int * restrict sval"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn sem_getvalue
|
||||
function sets the variable pointed to by
|
||||
.Fa sval
|
||||
to the current value of the semaphore pointed to by
|
||||
.Fa sem ,
|
||||
as of the time that the call to
|
||||
.Fn sem_getvalue
|
||||
is actually run.
|
||||
.Sh RETURN VALUES
|
||||
.Rv -std sem_getvalue
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn sem_getvalue
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
.Fa sem
|
||||
points to an invalid semaphore.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sem_post 3 ,
|
||||
.Xr sem_trywait 3 ,
|
||||
.Xr sem_wait 3 ,
|
||||
.Xr sem 4
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn sem_getvalue
|
||||
function conforms to
|
||||
.St -p1003.1-96 .
|
||||
.Pp
|
||||
The value of the semaphore is never negative, even if there are threads blocked
|
||||
on the semaphore. POSIX is somewhat ambiguous in its wording with regard to
|
||||
what the value of the semaphore should be if there are blocked waiting threads,
|
||||
but this behavior is conformant, given the wording of the specification.
|
||||
@@ -1,102 +0,0 @@
|
||||
.\" Copyright (C) 2000 Jason Evans <[email protected]>.
|
||||
.\" 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(s), this list of conditions and the following disclaimer as
|
||||
.\" the first lines of this file unmodified other than the possible
|
||||
.\" addition of one or more copyright notices.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
.Dd February 15, 2000
|
||||
.Dt SEM_INIT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sem_init
|
||||
.Nd initialize an unnamed semaphore
|
||||
.Sh LIBRARY
|
||||
.Lb libc_r
|
||||
.Sh SYNOPSIS
|
||||
.In semaphore.h
|
||||
.Ft int
|
||||
.Fn sem_init "sem_t *sem" "int pshared" "unsigned int value"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn sem_init
|
||||
function initializes the unnamed semaphore pointed to by
|
||||
.Fa sem
|
||||
to have the value
|
||||
.Fa value .
|
||||
A non-zero value for
|
||||
.Fa pshared
|
||||
specifies a shared semaphore that can be used by multiple processes, which this
|
||||
implementation is not capable of.
|
||||
.Pp
|
||||
Following a successful call to
|
||||
.Fn sem_init ,
|
||||
.Fa sem
|
||||
can be used as an argument in subsequent calls to
|
||||
.Xr sem_wait 3 ,
|
||||
.Xr sem_trywait 3 ,
|
||||
.Xr sem_post 3 ,
|
||||
and
|
||||
.Xr sem_destroy 3 .
|
||||
The
|
||||
.Fa sem
|
||||
argument is no longer valid after a successful call to
|
||||
.Xr sem_destroy 3 .
|
||||
.Sh RETURN VALUES
|
||||
.Rv -std sem_init
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn sem_init
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
.Fa value
|
||||
exceeds SEM_VALUE_MAX.
|
||||
.It Bq Er ENOSPC
|
||||
Memory allocation error.
|
||||
.It Bq Er EPERM
|
||||
Unable to initialize a shared semaphore.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sem_destroy 3 ,
|
||||
.Xr sem_post 3 ,
|
||||
.Xr sem_trywait 3 ,
|
||||
.Xr sem_wait 3 ,
|
||||
.Xr sem 4
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn sem_init
|
||||
function conforms to
|
||||
.St -p1003.1-96 .
|
||||
.Pp
|
||||
This implementation does not support shared semaphores, and reports this fact
|
||||
by setting
|
||||
.Va errno
|
||||
to
|
||||
.Er EPERM .
|
||||
This is perhaps a stretch of the intention of POSIX, but is
|
||||
compliant, with the caveat that
|
||||
.Fn sem_init
|
||||
always reports a permissions error when an attempt to create a shared semaphore
|
||||
is made.
|
||||
@@ -1,227 +0,0 @@
|
||||
.\" Copyright (C) 2000 Jason Evans <[email protected]>.
|
||||
.\" 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(s), this list of conditions and the following disclaimer as
|
||||
.\" the first lines of this file unmodified other than the possible
|
||||
.\" addition of one or more copyright notices.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
.Dd January 15, 2003
|
||||
.Dt SEM_OPEN 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sem_open ,
|
||||
.Nm sem_close ,
|
||||
.Nm sem_unlink
|
||||
.Nd named semaphore operations
|
||||
.Sh LIBRARY
|
||||
.Lb libc_r
|
||||
.Sh SYNOPSIS
|
||||
.In semaphore.h
|
||||
.Ft sem_t *
|
||||
.Fn sem_open "const char *name" "int oflag" "..."
|
||||
.Ft int
|
||||
.Fn sem_close "sem_t *sem"
|
||||
.Ft int
|
||||
.Fn sem_unlink "const char *name"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn sem_open
|
||||
function creates or opens the named semaphore specified by
|
||||
.Fa name .
|
||||
The returned semaphore may be used in subsequent calls to
|
||||
.Fn sem_getvalue ,
|
||||
.Fn sem_wait ,
|
||||
.Fn sem_trywait ,
|
||||
.Fn sem_post
|
||||
and
|
||||
.Fn sem_close .
|
||||
.Pp
|
||||
The following bits may be set in the
|
||||
.Fa oflag
|
||||
argument:
|
||||
.Bl -tag -width ".Dv O_CREAT"
|
||||
.It Dv O_CREAT
|
||||
Create the semaphore if it does not already exist.
|
||||
.Pp
|
||||
The third argument to the call to
|
||||
.Fn sem_open
|
||||
must be of type
|
||||
.Vt mode_t
|
||||
and specifies the mode for the semaphore.
|
||||
Only the
|
||||
.Dv S_IWUSR ,
|
||||
.Dv S_IWGRP ,
|
||||
and
|
||||
.Dv S_IWOTH
|
||||
bits are examined;
|
||||
it is not possible to grant only
|
||||
.Dq read
|
||||
permission on a semaphore.
|
||||
The mode is modified according to the process's file creation
|
||||
mask; see
|
||||
.Xr umask 2 .
|
||||
.Pp
|
||||
The fourth argument must be an
|
||||
.Vt "unsigned int"
|
||||
and specifies the initial value for the semaphore,
|
||||
and must be no greater than
|
||||
.Dv SEM_VALUE_MAX .
|
||||
.It Dv O_EXCL
|
||||
Create the semaphore if it does not exist.
|
||||
If the semaphore already exists,
|
||||
.Fn sem_open
|
||||
will fail.
|
||||
This flag is ignored unless
|
||||
.Dv O_CREAT
|
||||
is also specified.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn sem_close
|
||||
function closes a named semaphore that was opened by a call to
|
||||
.Fn sem_open .
|
||||
.Pp
|
||||
The
|
||||
.Fn sem_unlink
|
||||
function removes the semaphore named
|
||||
.Fa name .
|
||||
Resources allocated to the semaphore are only deallocated when all
|
||||
processes that have the semaphore open close it.
|
||||
.Sh RETURN VALUES
|
||||
If successful,
|
||||
the
|
||||
.Fn sem_open
|
||||
function returns the address of the opened semaphore.
|
||||
If the same
|
||||
.Fa name
|
||||
argument is given to multiple calls to
|
||||
.Fn sem_open
|
||||
by the same process without an intervening call to
|
||||
.Fn sem_close ,
|
||||
the same address is returned each time.
|
||||
If the semaphore cannot be opened,
|
||||
.Fn sem_open
|
||||
returns
|
||||
.Dv SEM_FAILED
|
||||
and the global variable
|
||||
.Va errno
|
||||
is set to indicate the error.
|
||||
.Pp
|
||||
.Rv -std sem_close sem_unlink
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn sem_open
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EACCES
|
||||
The semaphore exists and the permissions specified by
|
||||
.Fa oflag
|
||||
at the time it was created deny access to the this process.
|
||||
.It Bq Er EACCES
|
||||
The semaphore does not exist, but permission to create it is denied.
|
||||
.It Bq Er EEXIST
|
||||
.Dv O_CREAT
|
||||
and
|
||||
.Dv O_EXCL
|
||||
are set but the semaphore already exists.
|
||||
.It Bq Er EINTR
|
||||
The call was interrupted by a signal.
|
||||
.It Bq Er EINVAL
|
||||
The
|
||||
.Fn sem_open
|
||||
operation is not supported for the given
|
||||
.Fa name .
|
||||
.It Bq Er EINVAL
|
||||
The
|
||||
.Fa value
|
||||
argument is greater than
|
||||
.Dv SEM_VALUE_MAX .
|
||||
.\"FreeBSD never returns EMFILE
|
||||
.\".It Bq Er EMFILE
|
||||
.\"Too many semaphores are in use by this process.
|
||||
.It Bq Er ENAMETOOLONG
|
||||
The
|
||||
.Fa name
|
||||
argument is too long.
|
||||
.It Bq Er ENFILE
|
||||
The system limit on semaphores has been reached.
|
||||
.It Bq Er ENOENT
|
||||
.Dv O_CREAT
|
||||
is set but the named semaphore does not exist.
|
||||
.It Bq Er ENOSPC
|
||||
There is not enough space to create the semaphore.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn sem_close
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
The
|
||||
.Fa sem
|
||||
argument is not a valid semaphore.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn sem_unlink
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EACCES
|
||||
Permission is denied to unlink the semaphore.
|
||||
.It Bq Er ENAMETOOLONG
|
||||
The specified
|
||||
.Fa name
|
||||
is too long.
|
||||
.It Bq Er ENOENT
|
||||
The named semaphore does not exist.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr close 2 ,
|
||||
.Xr open 2 ,
|
||||
.Xr umask 2 ,
|
||||
.Xr unlink 2 ,
|
||||
.Xr sem_getvalue 3 ,
|
||||
.Xr sem_post 3 ,
|
||||
.Xr sem_trywait 3 ,
|
||||
.Xr sem_wait 3 ,
|
||||
.Xr sem 4
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn sem_open ,
|
||||
.Fn sem_close ,
|
||||
and
|
||||
.Fn sem_unlink
|
||||
functions conform to
|
||||
.St -p1003.1-96 .
|
||||
.Sh HISTORY
|
||||
Support for named semaphores first appeared in
|
||||
.Fx 5.0 .
|
||||
.Sh BUGS
|
||||
This implementation places strict requirements on the value of
|
||||
.Fa name :
|
||||
it must begin with a slash
|
||||
.Pq Ql / ,
|
||||
contain no other slash characters,
|
||||
and be less than 14 characters in length
|
||||
not including the terminating null character.
|
||||
@@ -1,74 +0,0 @@
|
||||
.\" Copyright (C) 2000 Jason Evans <[email protected]>.
|
||||
.\" 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(s), this list of conditions and the following disclaimer as
|
||||
.\" the first lines of this file unmodified other than the possible
|
||||
.\" addition of one or more copyright notices.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
.Dd February 15, 2000
|
||||
.Dt SEM_POST 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sem_post
|
||||
.Nd increment (unlock) a semaphore
|
||||
.Sh LIBRARY
|
||||
.Lb libc_r
|
||||
.Sh SYNOPSIS
|
||||
.In semaphore.h
|
||||
.Ft int
|
||||
.Fn sem_post "sem_t *sem"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn sem_post
|
||||
function increments (unlocks) the semaphore pointed to by
|
||||
.Fa sem .
|
||||
If there are threads blocked on the semaphore when
|
||||
.Fn sem_post
|
||||
is called, then the highest priority thread that has been blocked the longest on
|
||||
the semaphore will be allowed to return from
|
||||
.Fn sem_wait .
|
||||
.Pp
|
||||
The
|
||||
.Fn sem_post
|
||||
function is signal-reentrant and may be called within signal handlers.
|
||||
.Sh RETURN VALUES
|
||||
.Rv -std sem_post
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn sem_post
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
.Fa sem
|
||||
points to an invalid semaphore.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sem_trywait 3 ,
|
||||
.Xr sem_wait 3 ,
|
||||
.Xr sem 4
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn sem_post
|
||||
function conforms to
|
||||
.St -p1003.1-96 .
|
||||
@@ -1,89 +0,0 @@
|
||||
.\" Copyright (C) 2000 Jason Evans <[email protected]>.
|
||||
.\" 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(s), this list of conditions and the following disclaimer as
|
||||
.\" the first lines of this file unmodified other than the possible
|
||||
.\" addition of one or more copyright notices.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
.Dd February 15, 2000
|
||||
.Dt SEM_WAIT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sem_wait ,
|
||||
.Nm sem_trywait
|
||||
.Nd decrement (lock) a semaphore
|
||||
.Sh LIBRARY
|
||||
.Lb libc_r
|
||||
.Sh SYNOPSIS
|
||||
.In semaphore.h
|
||||
.Ft int
|
||||
.Fn sem_wait "sem_t *sem"
|
||||
.Ft int
|
||||
.Fn sem_trywait "sem_t *sem"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn sem_wait
|
||||
function decrements (locks) the semaphore pointed to by
|
||||
.Fa sem ,
|
||||
but blocks if the value of
|
||||
.Fa sem
|
||||
is zero, until the value is non-zero and the value can be decremented.
|
||||
.Pp
|
||||
The
|
||||
.Fn sem_trywait
|
||||
function decrements (locks) the semaphore pointed to by
|
||||
.Fa sem
|
||||
only if the value is non-zero. Otherwise, the semaphore is not decremented and
|
||||
an error is returned.
|
||||
.Sh RETURN VALUES
|
||||
.Rv -std
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn sem_wait
|
||||
and
|
||||
.Fn sem_trywait
|
||||
functions will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
.Fa sem
|
||||
points to an invalid semaphore.
|
||||
.El
|
||||
.Pp
|
||||
Additionally,
|
||||
.Fn sem_trywait
|
||||
will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EAGAIN
|
||||
The semaphore value was zero, and thus could not be decremented.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sem_post 3 ,
|
||||
.Xr sem 4
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn sem_wait
|
||||
and
|
||||
.Fn sem_trywait
|
||||
functions conform to
|
||||
.St -p1003.1-96 .
|
||||
@@ -71,6 +71,10 @@ extern size_t __emulated_wcrtomb(char * __restrict, wchar_t,
|
||||
mbstate_t * __restrict ps);
|
||||
extern rune_t __emulated_sgetrune(const char *, size_t, const char **);
|
||||
extern int __emulated_sputrune(rune_t, char *, size_t, char **);
|
||||
extern size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict,
|
||||
size_t, mbstate_t * __restrict);
|
||||
extern size_t _none_wcrtomb(char * __restrict, wchar_t,
|
||||
mbstate_t * __restrict);
|
||||
|
||||
static int __setrunelocale(const char *);
|
||||
|
||||
@@ -104,6 +108,10 @@ __setrunelocale(const char *encoding)
|
||||
static char ctype_encoding[ENCODING_LEN + 1];
|
||||
static _RuneLocale *CachedRuneLocale;
|
||||
static int Cached__mb_cur_max;
|
||||
static size_t (*Cached__mbrtowc)(wchar_t * __restrict,
|
||||
const char * __restrict, size_t, mbstate_t * __restrict);
|
||||
static size_t (*Cached__wcrtomb)(char * __restrict, wchar_t,
|
||||
mbstate_t * __restrict);
|
||||
|
||||
/*
|
||||
* The "C" and "POSIX" locale are always here.
|
||||
@@ -111,6 +119,8 @@ __setrunelocale(const char *encoding)
|
||||
if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) {
|
||||
_CurrentRuneLocale = &_DefaultRuneLocale;
|
||||
__mb_cur_max = 1;
|
||||
__mbrtowc = _none_mbrtowc;
|
||||
__wcrtomb = _none_wcrtomb;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -121,6 +131,8 @@ __setrunelocale(const char *encoding)
|
||||
strcmp(encoding, ctype_encoding) == 0) {
|
||||
_CurrentRuneLocale = CachedRuneLocale;
|
||||
__mb_cur_max = Cached__mb_cur_max;
|
||||
__mbrtowc = Cached__mbrtowc;
|
||||
__wcrtomb = Cached__wcrtomb;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -177,6 +189,8 @@ __setrunelocale(const char *encoding)
|
||||
}
|
||||
CachedRuneLocale = _CurrentRuneLocale;
|
||||
Cached__mb_cur_max = __mb_cur_max;
|
||||
Cached__mbrtowc = __mbrtowc;
|
||||
Cached__wcrtomb = __wcrtomb;
|
||||
(void)strcpy(ctype_encoding, encoding);
|
||||
} else
|
||||
free(rl);
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
.\" Copyright (c) 2002 Networks Associates Technology, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This software was developed for the FreeBSD Project by Chris
|
||||
.\" Costello at Safeport Network Services and NAI Labs, the Security
|
||||
.\" Research Division of Network Associates, Inc. under DARPA/SPAWAR
|
||||
.\" contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
|
||||
.\" research program.
|
||||
.\"
|
||||
.\" 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 AUTHORS 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 AUTHORS 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$
|
||||
.\"
|
||||
.Dd January 9, 2002
|
||||
.Dt MAC_IS_PRESENT_NP 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mac_is_present_np
|
||||
.Nd report whether the running system has MAC support
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.In sys/mac.h
|
||||
.Ft int
|
||||
.Fn mac_is_present "const char *policyname"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn mac_is_present_np
|
||||
function determines whether the currently-running kernel supports MAC for
|
||||
a given policy or not.
|
||||
If
|
||||
.Fa policyname
|
||||
is
|
||||
.No non- Ns Dv NULL ,
|
||||
the presence of the named policy
|
||||
(e.g.\&
|
||||
.Dq Li biba ,
|
||||
.Dq Li mls ,
|
||||
.Dq Li te )
|
||||
is checked, otherwise the presence of any MAC policies at all is checked.
|
||||
.Sh RETURN VALUES
|
||||
If the system supports the given MAC policy, the value 1 is returned.
|
||||
If the specified MAC policy is not supported, the value 0 is returned.
|
||||
If an error occurs, the value \-1 is returned.
|
||||
.Sh ERRORS
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
The value of
|
||||
.Fa policyname
|
||||
is not valid.
|
||||
.It Bq Er ENOMEM
|
||||
Insufficient memory was available to allocate internal storage.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mac 3 ,
|
||||
.Xr mac_free 3 ,
|
||||
.Xr mac_get 3 ,
|
||||
.Xr mac_prepare 3 ,
|
||||
.Xr mac_set 3 ,
|
||||
.Xr mac_text 3 ,
|
||||
.Xr mac 4 ,
|
||||
.Xr mac 9
|
||||
.Sh HISTORY
|
||||
Support for Mandatory Access Control was introduced in
|
||||
.Fx 5.0
|
||||
as part of the
|
||||
.Tn TrustedBSD
|
||||
Project.
|
||||
@@ -223,7 +223,7 @@ static unsigned malloc_ninfo;
|
||||
static struct pgfree free_list;
|
||||
|
||||
/* Abort(), user doesn't handle problems. */
|
||||
static int malloc_abort = 1;
|
||||
static int malloc_abort;
|
||||
|
||||
/* Are we trying to die ? */
|
||||
static int suicide;
|
||||
@@ -246,7 +246,7 @@ static int malloc_sysv;
|
||||
static int malloc_zero;
|
||||
|
||||
/* junk fill ? */
|
||||
static int malloc_junk = 1;
|
||||
static int malloc_junk;
|
||||
|
||||
#ifdef HAS_UTRACE
|
||||
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
.\"
|
||||
.\" Copyright 2000 Massachusetts Institute of Technology
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software and
|
||||
.\" its documentation for any purpose and without fee is hereby
|
||||
.\" granted, provided that both the above copyright notice and this
|
||||
.\" permission notice appear in all copies, that both the above
|
||||
.\" copyright notice and this permission notice appear in all
|
||||
.\" supporting documentation, and that the name of M.I.T. not be used
|
||||
.\" in advertising or publicity pertaining to distribution of the
|
||||
.\" software without specific, written prior permission. M.I.T. makes
|
||||
.\" no representations about the suitability of this software for any
|
||||
.\" purpose. It is provided "as is" without express or implied
|
||||
.\" warranty.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
|
||||
.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
|
||||
.\" SHALL M.I.T. 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$
|
||||
.\"
|
||||
.Dd March 24, 2000
|
||||
.Dt SHM_OPEN 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm shm_open
|
||||
.Nd open or create a shared memory object
|
||||
.Nm shm_unlink
|
||||
.Nd remove a shared memory object
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
.In sys/mman.h
|
||||
.Ft int
|
||||
.Fn shm_open "const char *path" "int flags" "mode_t mode"
|
||||
.Ft int
|
||||
.Fn shm_unlink "const char *path"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn shm_open
|
||||
function opens (or optionally creates) a
|
||||
.Tn POSIX
|
||||
shared memory object named
|
||||
.Fa path .
|
||||
The
|
||||
.Fn shm_unlink
|
||||
function removes a shared memory object named
|
||||
.Fa path .
|
||||
.Pp
|
||||
In the
|
||||
.Fx
|
||||
implementation,
|
||||
.Tn POSIX
|
||||
shared memory objects are implemented as ordinary files.
|
||||
The
|
||||
.Fn shm_open
|
||||
and
|
||||
.Fn shm_unlink
|
||||
act as wrappers around the
|
||||
.Xr open 2
|
||||
and
|
||||
.Xr unlink 2
|
||||
routines, and
|
||||
.Fa path ,
|
||||
.Fa flags ,
|
||||
and
|
||||
.Fa mode
|
||||
arguments are as specified for those functions.
|
||||
The
|
||||
.Fa flags
|
||||
argument is checked to ensure that the access mode specified is not
|
||||
.Dv O_WRONLY
|
||||
(which is not defined for shared memory objects).
|
||||
.Pp
|
||||
In addition, the
|
||||
.Fx
|
||||
implementation causes
|
||||
.Fn mmap
|
||||
of a descriptor returned by
|
||||
.Fn shm_open
|
||||
to behave as if the
|
||||
.Dv MAP_NOSYNC
|
||||
flag had been specified to
|
||||
.Xr mmap 2 .
|
||||
(It does so by setting a special file flag using
|
||||
.Xr fcntl 2 . )
|
||||
.Pp
|
||||
The
|
||||
.Fn shm_unlink
|
||||
function makes no effort to ensure that
|
||||
.Fa path
|
||||
refers to a shared memory object.
|
||||
.Sh COMPATIBILITY
|
||||
The
|
||||
.Fa path
|
||||
argument does not necessarily represent a pathname (although it does in this
|
||||
and most other implementations).
|
||||
Two processes opening the same
|
||||
.Fa path
|
||||
are guaranteed to access the same shared memory object if and only if
|
||||
.Fa path
|
||||
begins with a slash
|
||||
.Pq Ql \&/
|
||||
character.
|
||||
.Pp
|
||||
Only the
|
||||
.Dv O_RDONLY ,
|
||||
.Dv O_RDWR ,
|
||||
.Dv O_CREAT ,
|
||||
.Dv O_EXCL ,
|
||||
and
|
||||
.Dv O_TRUNC
|
||||
flags may be used in portable programs.
|
||||
.Pp
|
||||
The result of using
|
||||
.Xr open 2 ,
|
||||
.Xr read 2 ,
|
||||
or
|
||||
.Xr write 2
|
||||
on a shared memory object, or on the descriptor returned by
|
||||
.Fn shm_open ,
|
||||
is undefined.
|
||||
It is also undefined whether the shared memory object itself, or its
|
||||
contents, persist across reboots.
|
||||
.Sh RETURN VALUES
|
||||
If successful,
|
||||
.Fn shm_open
|
||||
returns a non-negative integer;
|
||||
.Fn shm_unlink
|
||||
returns zero.
|
||||
Both functions return -1 on failure, and set
|
||||
.Va errno
|
||||
to indicate the error.
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn shm_open
|
||||
and
|
||||
.Fn shm_unlink
|
||||
functions can fail with any error defined for
|
||||
.Fn open
|
||||
and
|
||||
.Fn unlink ,
|
||||
respectively. In addition, the following errors are defined for
|
||||
.Fn shm_open :
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
The object named by
|
||||
.Fa path
|
||||
is not a shared memory object
|
||||
(i.e., it is not a regular file).
|
||||
.It Bq Er EINVAL
|
||||
The
|
||||
.Fa flags
|
||||
argument to
|
||||
.Fn shm_open
|
||||
specifies an access mode of
|
||||
.Dv O_WRONLY .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mmap 2 ,
|
||||
.Xr munmap 2 ,
|
||||
.Xr open 2 ,
|
||||
.Xr unlink 2
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn shm_open
|
||||
and
|
||||
.Fn shm_unlink
|
||||
functions are believed to conform to
|
||||
.St -p1003.1b-93 .
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn shm_open
|
||||
and
|
||||
.Fn shm_unlink
|
||||
functions first appeared in
|
||||
.Fx 4.3 .
|
||||
.Sh AUTHORS
|
||||
.An Garrett A. Wollman Aq [email protected]
|
||||
(C library support and this manual page)
|
||||
.Pp
|
||||
.An Matthew Dillon Aq [email protected]
|
||||
.Pq Dv MAP_NOSYNC
|
||||
@@ -1,86 +0,0 @@
|
||||
.\" Copyright (C) 2000 Jason Evans <[email protected]>.
|
||||
.\" 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(s), this list of conditions and the following disclaimer as
|
||||
.\" the first lines of this file unmodified other than the possible
|
||||
.\" addition of one or more copyright notices.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
.Dd April 27, 2000
|
||||
.Dt SIGWAIT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sigwait
|
||||
.Nd select a set of signals
|
||||
.Sh LIBRARY
|
||||
.Lb libc_r
|
||||
.Sh SYNOPSIS
|
||||
.In signal.h
|
||||
.Ft int
|
||||
.Fn sigwait "const sigset_t * restrict set" "int * restrict sig"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn sigwait
|
||||
function selects a set of signals, specified by
|
||||
.Fa set .
|
||||
If none of the selected signals are pending,
|
||||
.Fn sigwait
|
||||
waits until one or more of the selected signals has been generated.
|
||||
Then
|
||||
.Fn sigwait
|
||||
atomically clears one of the selected signals from the set of pending signals
|
||||
for the process and sets the location pointed to by
|
||||
.Fa sig
|
||||
to the signal number that was cleared.
|
||||
.Pp
|
||||
The signals specified by
|
||||
.Fa set
|
||||
should be blocked at the time of the call to
|
||||
.Fn sigwait .
|
||||
.Sh RETURN VALUES
|
||||
If successful,
|
||||
.Fn sigwait
|
||||
returns 0 and sets the location pointed to by
|
||||
.Fa sig
|
||||
to the cleared signal number.
|
||||
Otherwise, an error number is returned.
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn sigwait
|
||||
function will fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
.Fa set
|
||||
specifies one or more invalid signal numbers.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sigaction 2 ,
|
||||
.Xr sigpending 2 ,
|
||||
.Xr sigsuspend 2 ,
|
||||
.Xr pause 3 ,
|
||||
.Xr pthread_sigmask 3
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Fn sigwait
|
||||
function conforms to
|
||||
.St -p1003.1-96
|
||||
@@ -10,6 +10,7 @@ SHLIB_MAJOR= 1
|
||||
MAN= kiconv.3
|
||||
|
||||
MLINKS+= kiconv.3 kiconv_add_xlat16_cspair.3 \
|
||||
kiconv.3 kiconv_add_xlat16_cspairs.3 \
|
||||
kiconv.3 kiconv_add_xlat16_table.3
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../sys
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm kiconv_add_xlat16_cspair ,
|
||||
.Nm kiconv_add_xlat16_cspairs ,
|
||||
.Nm kiconv_add_xlat16_table
|
||||
.Nd Kernel side iconv library
|
||||
.Sh LIBRARY
|
||||
@@ -43,6 +44,11 @@
|
||||
.Fa "int flag"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo kiconv_add_xlat16_cspairs
|
||||
.Fa "const char *foreigncode"
|
||||
.Fa "const char *localcode"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo kiconv_add_xlat16_table
|
||||
.Fa "const char *tocode"
|
||||
.Fa "const char *fromcode"
|
||||
@@ -92,6 +98,17 @@ or toupper
|
||||
.Pp
|
||||
A tolower/toupper conversion is limited to single-byte characters.
|
||||
.Pp
|
||||
.Fn kiconv_add_xlat16_cspairs
|
||||
defines two conversion tables which are from
|
||||
.Ar localcode
|
||||
to
|
||||
.Ar foreigncode
|
||||
and from
|
||||
.Ar foreigncode
|
||||
to
|
||||
.Ar localcode .
|
||||
This conversion tables also contain both of tolower and toupper tables.
|
||||
.Pp
|
||||
.Fn kiconv_add_xlat16_table
|
||||
defines a conversion table directly pointed by
|
||||
.Ar data
|
||||
|
||||
@@ -113,6 +113,23 @@ kiconv_add_xlat16_cspair(const char *tocode, const char *fromcode, int flag)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
kiconv_add_xlat16_cspairs(const char *foreigncode, const char *localcode)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = kiconv_add_xlat16_cspair(foreigncode, localcode,
|
||||
KICONV_FROM_LOWER | KICONV_FROM_UPPER);
|
||||
if (error)
|
||||
return (error);
|
||||
error = kiconv_add_xlat16_cspair(localcode, foreigncode,
|
||||
KICONV_LOWER | KICONV_UPPER);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct xlat16_table
|
||||
kiconv_xlat16_open(const char *tocode, const char *fromcode, int lcase)
|
||||
{
|
||||
@@ -371,4 +388,11 @@ kiconv_add_xlat16_cspair(const char *tocode, const char *fromcode, int flag)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
kiconv_add_xlat16_cspairs(const char *tocode, const char *fromcode)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* PIC */
|
||||
@@ -1,53 +0,0 @@
|
||||
# $FreeBSD$
|
||||
#
|
||||
# All library objects contain FreeBSD revision strings by default; they may be
|
||||
# excluded as a space-saving measure. To produce a library that does
|
||||
# not contain these strings, add -DSTRIP_FBSDID (see <sys/cdefs.h>) to CFLAGS
|
||||
# below. Note, there are no IDs for syscall stubs whose sources are generated.
|
||||
# To included legacy CSRG sccsid strings, add -DLIBC_SCCS and -DSYSLIBC_SCCS
|
||||
# (for system call stubs) to CFLAGS below. -DSYSLIBC_SCCS affects just the
|
||||
# system call stubs.
|
||||
LIB=kse
|
||||
SHLIB_MAJOR= 1
|
||||
CFLAGS+=-DPTHREAD_KERNEL
|
||||
CFLAGS+=-I${.CURDIR}/../libc/include -I${.CURDIR}/thread \
|
||||
-I${.CURDIR}/../../include
|
||||
CFLAGS+=-I${.CURDIR}/arch/${MACHINE_ARCH}/include
|
||||
CFLAGS+=-I${.CURDIR}/sys
|
||||
CFLAGS+=-I${.CURDIR}/../../libexec/rtld-elf
|
||||
CFLAGS+=-fno-builtin
|
||||
|
||||
# Uncomment this if you want libpthread to contain debug information for
|
||||
# thread locking.
|
||||
CFLAGS+=-D_LOCK_DEBUG
|
||||
#CFLAGS+= -g
|
||||
|
||||
# Uncomment this if you want to build a 1:1 threading mode library
|
||||
# however it is no longer strictly conformed to POSIX
|
||||
# CFLAGS+=-DSYSTEM_SCOPE_ONLY
|
||||
|
||||
LDFLAGS= -Wl,--version-script=${.CURDIR}/pthread.map
|
||||
|
||||
# enable extra internal consistancy checks
|
||||
CFLAGS+=-D_PTHREADS_INVARIANTS -Wall
|
||||
|
||||
PRECIOUSLIB= yes
|
||||
|
||||
.include "${.CURDIR}/arch/${MACHINE_ARCH}/Makefile.inc"
|
||||
.include "${.CURDIR}/support/Makefile.inc"
|
||||
.include "${.CURDIR}/sys/Makefile.inc"
|
||||
.include "${.CURDIR}/thread/Makefile.inc"
|
||||
|
||||
.if !defined(NOLIBC_R)
|
||||
.if ${MACHINE_ARCH} == "ia64"
|
||||
SYMLINKS+=lib${LIB}.a ${LIBDIR}/libc_r.a
|
||||
.if !defined(NOPIC)
|
||||
SYMLINKS+=lib${LIB}.so ${SHLIBDIR}/libc_r.so
|
||||
.endif
|
||||
.if !defined(NOPROFILE)
|
||||
SYMLINKS+=lib${LIB}_p.a ${LIBDIR}/libc_r_p.a
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
@@ -1,5 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
|
||||
|
||||
SRCS+= context.S enter_uts.S pthread_md.c
|
||||
@@ -1,210 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>.
|
||||
* 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. Neither the name of the author 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 DANIEL EISCHEN 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* The following notes ("cheat sheet") was provided by Peter Wemm.
|
||||
*
|
||||
* scratch:
|
||||
* rax (1st return)
|
||||
* rcx (4th arg)
|
||||
* rdx (3rd arg, 2nd return)
|
||||
* rsi (2nd arg)
|
||||
* rdi (1st arg)
|
||||
* r8 (5th arg)
|
||||
* r9 (6th arg)
|
||||
* r10 (temp, static chain?)
|
||||
* r11 (temp)
|
||||
*
|
||||
* preserved:
|
||||
* rbx (base pointer)
|
||||
* rsp (stack)
|
||||
* rbp (frame)
|
||||
* r12-r15 (general)
|
||||
*
|
||||
* calls:
|
||||
* rdi 1
|
||||
* rsi 2
|
||||
* rdx 3
|
||||
* rcx 4
|
||||
* r8 5
|
||||
* r9 6
|
||||
*
|
||||
* return:
|
||||
* rax 1
|
||||
* rdx 2
|
||||
*
|
||||
* This means:
|
||||
* arg1 goes in %rdi, arg2 in %rsi, etc. return value is %rax (and
|
||||
* secondary return, eg: pipe(2), in %rdx) %rcx,%rsi,%rdi etc are
|
||||
* trashed by making a call to something. %rbx,%rbp,%r12-15 are the
|
||||
* only registers preserved across a call. Note that unlike i386,
|
||||
* %rsi and %rdi are scratch rather than preserved. FPU is
|
||||
* different, args are in SSE registers rather than the x87 stack.
|
||||
*
|
||||
* Aside from the register calling conventions, amd64 can be treated
|
||||
* very much like i386. Things like setjmp/longjmp etc were literal
|
||||
* translations from i386 but with the register names updated, etc.
|
||||
* The main gotcha is that FPU save/restore is in SSE format, which
|
||||
* means a sparse 512 byte FPU context.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Where do we define these?
|
||||
*/
|
||||
#define MC_SIZE 800 /* sizeof mcontext_t */
|
||||
#define MC_LEN_OFFSET (25*8) /* offset to mc_len from mcontext */
|
||||
#define MC_FPFMT_OFFSET (26*8) /* offset to mc_fpformat from mcontext */
|
||||
#define MC_FPFMT_NODEV 0x10000
|
||||
#define MC_OWNEDFP_OFFSET (27*8) /* offset to mc_ownedfp from mcontext */
|
||||
#define MC_OWNEDFP_NONE 0x20000
|
||||
#define MC_OWNEDFP_FPU 0x20001
|
||||
#define MC_OWNEDFP_PCB 0x20002
|
||||
#define MC_FPREGS_OFFSET (28*8) /* offset to FP registers */
|
||||
#define MC_FP_CW_OFFSET (28*8) /* offset to FP control word */
|
||||
|
||||
#define MC_RDI (1 * 8)
|
||||
#define MC_RSI (2 * 8)
|
||||
#define MC_RDX (3 * 8)
|
||||
#define MC_RCX (4 * 8)
|
||||
#define MC_R8 (5 * 8)
|
||||
#define MC_R9 (6 * 8)
|
||||
#define MC_RAX (7 * 8)
|
||||
#define MC_RBX (8 * 8)
|
||||
#define MC_RBP (9 * 8)
|
||||
#define MC_R10 (10 * 8)
|
||||
#define MC_R11 (11 * 8)
|
||||
#define MC_R12 (12 * 8)
|
||||
#define MC_R13 (13 * 8)
|
||||
#define MC_R14 (14 * 8)
|
||||
#define MC_R15 (15 * 8)
|
||||
#define MC_FLAGS (18 * 8)
|
||||
#define MC_RIP (20 * 8)
|
||||
#define MC_RFLAGS (22 * 8)
|
||||
#define MC_RSP (23 * 8)
|
||||
|
||||
/*
|
||||
* _amd64_ctx_save(mcontext_t *mcp)
|
||||
*
|
||||
* No values are saved to mc_trapno, mc_addr, mc_err, mc_cs, or mc_ss.
|
||||
* For the FPU state, only the floating point control word is stored.
|
||||
*/
|
||||
ENTRY(_amd64_save_context)
|
||||
cmpq $0, %rdi /* check for null pointer */
|
||||
jne 1f
|
||||
movq $-1, %rax
|
||||
jmp 2f
|
||||
1: movq %rdi, MC_RDI(%rdi)
|
||||
movq %rsi, MC_RSI(%rdi)
|
||||
movq %rdx, MC_RDX(%rdi)
|
||||
movq %rcx, MC_RCX(%rdi)
|
||||
movq %r8, MC_R8(%rdi)
|
||||
movq %r9, MC_R9(%rdi)
|
||||
movq $1, MC_RAX(%rdi) /* return 1 when restored */
|
||||
movq %rbx, MC_RBX(%rdi)
|
||||
movq %rbp, MC_RBP(%rdi)
|
||||
movq %r10, MC_R10(%rdi)
|
||||
movq %r11, MC_R11(%rdi)
|
||||
movq %r12, MC_R12(%rdi)
|
||||
movq %r13, MC_R13(%rdi)
|
||||
movq %r14, MC_R14(%rdi)
|
||||
movq %r15, MC_R15(%rdi)
|
||||
movq (%rsp), %rax /* get return address */
|
||||
movq %rax, MC_RIP(%rdi) /* save return address (%rip) */
|
||||
pushfq /* get flags */
|
||||
popq %rax
|
||||
movq %rax, MC_RFLAGS(%rdi) /* save flags */
|
||||
movq %rsp, %rax /* setcontext pushes the return */
|
||||
addq $8, %rax /* address onto the stack; */
|
||||
movq %rax, MC_RSP(%rdi) /* account for this -- ???. */
|
||||
fnstcw MC_FP_CW_OFFSET(%rdi) /* save FPU control word */
|
||||
movq $MC_OWNEDFP_NONE, MC_OWNEDFP_OFFSET(%rdi) /* no FP */
|
||||
/*movq $MC_FPFMT_NODEV, MC_FPFMT_OFFSET(%rdi)*/ /* unused for amd64 */
|
||||
movq $MC_SIZE, MC_LEN_OFFSET(%rdi)
|
||||
xorq %rax, %rax /* return 0 */
|
||||
2: ret
|
||||
|
||||
/*
|
||||
* _amd64_ctx_restore(mcontext_t *mcp, intptr_t val, intptr_t *loc);
|
||||
*/
|
||||
ENTRY(_amd64_restore_context)
|
||||
cmpq $0, %rdi /* check for null pointer */
|
||||
jne 1f
|
||||
movq $-1, %rax
|
||||
jmp 7f
|
||||
1: cmpq $MC_SIZE, MC_LEN_OFFSET(%rdi) /* is context valid? */
|
||||
je 2f
|
||||
movq $-1, %rax /* bzzzt, invalid context */
|
||||
jmp 7f
|
||||
2: movq MC_RCX(%rdi), %rcx
|
||||
movq MC_R8(%rdi), %r8
|
||||
movq MC_R9(%rdi), %r9
|
||||
movq MC_RBX(%rdi), %rbx
|
||||
movq MC_RBP(%rdi), %rbp
|
||||
movq MC_R10(%rdi), %r10
|
||||
movq MC_R11(%rdi), %r11
|
||||
movq MC_R12(%rdi), %r12
|
||||
movq MC_R13(%rdi), %r13
|
||||
movq MC_R14(%rdi), %r14
|
||||
movq MC_R15(%rdi), %r15
|
||||
/*
|
||||
* if (mc_fpowned == MC_OWNEDFP_FPU || mc_fpowned == MC_OWNEDFP_PCB)
|
||||
* restore XMM/SSE FP register format
|
||||
*/
|
||||
cmpq $MC_OWNEDFP_NONE, MC_OWNEDFP_OFFSET(%rdi)
|
||||
je 4f
|
||||
cmpq $MC_OWNEDFP_PCB, MC_OWNEDFP_OFFSET(%rdi)
|
||||
je 3f
|
||||
cmpq $MC_OWNEDFP_FPU, MC_OWNEDFP_OFFSET(%rdi)
|
||||
jne 4f
|
||||
3: fxrstor MC_FPREGS_OFFSET(%rdi) /* restore XMM FP regs */
|
||||
jmp 5f
|
||||
4: fninit
|
||||
fldcw MC_FP_CW_OFFSET(%rdi)
|
||||
5: movq MC_RSP(%rdi), %rsp /* switch to context stack */
|
||||
movq MC_RIP(%rdi), %rax /* return address on stack */
|
||||
pushq %rax
|
||||
movq MC_RDI(%rdi), %rax /* rdi on stack */
|
||||
pushq %rax
|
||||
movq MC_RDX(%rdi), %rax /* rdx on stack */
|
||||
pushq %rax
|
||||
movq MC_RSI(%rdi), %rax /* rsi on stack */
|
||||
pushq %rax
|
||||
movq MC_RFLAGS(%rdi), %rax /* flags on stack*/
|
||||
pushq %rax
|
||||
movq MC_RAX(%rdi), %rax /* restore rax */
|
||||
/* At this point we're done with the context. */
|
||||
cmpq $0, %rdx /* set *loc to val */
|
||||
je 6f
|
||||
movq %rsi, (%rdx)
|
||||
6: popfq /* restore flags */
|
||||
popq %rsi /* restore rsi, rdx, and rdi */
|
||||
popq %rdx
|
||||
popq %rdi
|
||||
7: ret
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>.
|
||||
* 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. Neither the name of the author 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 DANIEL EISCHEN 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
/*
|
||||
* _amd64_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
* size_t stacksz);
|
||||
*/
|
||||
ENTRY(_amd64_enter_uts)
|
||||
addq %rcx, %rdx /* get stack base */
|
||||
andq $~0xf, %rdx /* align to 16 bytes */
|
||||
subq $8, %rdx /* simulate "call" alignment */
|
||||
movq %rdx, %rsp /* switch to UTS stack */
|
||||
movq %rdx, %rbp /* set frame */
|
||||
jmpq *%rsi
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <[email protected]>
|
||||
* 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. Neither the name of the author 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 AUTHOR ``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 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$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include "pthread_md.h"
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
if ((tcb = malloc(sizeof(struct tcb))) != NULL) {
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_thread = thread;
|
||||
/* Allocate TDV */
|
||||
}
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
/* Free TDV */
|
||||
free(tcb);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
if ((kcb = malloc(sizeof(struct kcb))) != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_kse = kse;
|
||||
kcb->kcb_self = kcb;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Daniel Eischen <[email protected]>
|
||||
* 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. Neither the name of the author 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 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap64(intptr_t *dst, intptr_t val, intptr_t *res);
|
||||
*/
|
||||
static inline void
|
||||
atomic_swap64(intptr_t *dst, intptr_t val, intptr_t *res)
|
||||
{
|
||||
__asm __volatile(
|
||||
"xchgq %2, %1; movq %2, %0"
|
||||
: "=m" (*res) : "m" (*dst), "r" (val) : "memory");
|
||||
}
|
||||
|
||||
static inline void
|
||||
atomic_swap_int(int *dst, int val, int *res)
|
||||
{
|
||||
__asm __volatile(
|
||||
"xchgl %2, %1; movl %2, %0"
|
||||
: "=m" (*res) : "m" (*dst), "r" (val) : "memory");
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(d, v, r) \
|
||||
atomic_swap64((intptr_t *)(d), (intptr_t)(v), (intptr_t *)(r))
|
||||
|
||||
#endif
|
||||
@@ -1,251 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 David Xu <[email protected]>
|
||||
* Copyright (c) 2001 Daniel Eischen <[email protected]>
|
||||
* 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. Neither the name of the author 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 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/kse.h>
|
||||
#include <machine/sysarch.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
|
||||
#define THR_GETCONTEXT(ucp) \
|
||||
(void)_amd64_save_context(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) \
|
||||
(void)_amd64_restore_context(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_KSE
|
||||
#undef PER_THREAD
|
||||
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tdv;
|
||||
|
||||
/*
|
||||
* %fs points to a struct kcb.
|
||||
*/
|
||||
struct kcb {
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kcb *kcb_self; /* self reference */
|
||||
struct kse *kcb_kse;
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct tdv *tcb_tdv;
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_spare[2]; /* align tcb_tmbx to 16 bytes */
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
};
|
||||
|
||||
/*
|
||||
* Evaluates to the byte offset of the per-kse variable name.
|
||||
*/
|
||||
#define __kcb_offset(name) __offsetof(struct kcb, name)
|
||||
|
||||
/*
|
||||
* Evaluates to the type of the per-kse variable name.
|
||||
*/
|
||||
#define __kcb_type(name) __typeof(((struct kcb *)0)->name)
|
||||
|
||||
/*
|
||||
* Evaluates to the value of the per-kse variable name.
|
||||
*/
|
||||
#define KCB_GET64(name) ({ \
|
||||
__kcb_type(name) __result; \
|
||||
\
|
||||
u_long __i; \
|
||||
__asm __volatile("movq %%fs:%1, %0" \
|
||||
: "=r" (__i) \
|
||||
: "m" (*(u_long *)(__kcb_offset(name)))); \
|
||||
__result = *(__kcb_type(name) *)&__i; \
|
||||
\
|
||||
__result; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Sets the value of the per-kse variable name to value val.
|
||||
*/
|
||||
#define KCB_SET64(name, val) ({ \
|
||||
__kcb_type(name) __val = (val); \
|
||||
\
|
||||
u_long __i; \
|
||||
__i = *(u_long *)&__val; \
|
||||
__asm __volatile("movq %1,%%fs:%0" \
|
||||
: "=m" (*(u_long *)(__kcb_offset(name))) \
|
||||
: "r" (__i)); \
|
||||
})
|
||||
|
||||
static __inline u_long
|
||||
__kcb_readandclear64(volatile u_long *addr)
|
||||
{
|
||||
u_long result;
|
||||
|
||||
__asm __volatile (
|
||||
" xorq %0, %0;"
|
||||
" xchgq %%fs:%1, %0;"
|
||||
"# __kcb_readandclear64"
|
||||
: "=&r" (result)
|
||||
: "m" (*addr));
|
||||
return (result);
|
||||
}
|
||||
|
||||
#define KCB_READANDCLEAR64(name) ({ \
|
||||
__kcb_type(name) __result; \
|
||||
\
|
||||
__result = (__kcb_type(name)) \
|
||||
__kcb_readandclear64((u_long *)__kcb_offset(name)); \
|
||||
__result; \
|
||||
})
|
||||
|
||||
|
||||
#define _kcb_curkcb() KCB_GET64(kcb_self)
|
||||
#define _kcb_curtcb() KCB_GET64(kcb_curtcb)
|
||||
#define _kcb_curkse() ((struct kse *)KCB_GET64(kcb_kmbx.km_udata))
|
||||
#define _kcb_get_tmbx() KCB_GET64(kcb_kmbx.km_curthread)
|
||||
#define _kcb_set_tmbx(value) KCB_SET64(kcb_kmbx.km_curthread, (void *)value)
|
||||
#define _kcb_readandclear_tmbx() KCB_READANDCLEAR64(kcb_kmbx.km_curthread)
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
void _tcb_dtor(struct tcb *tcb);
|
||||
struct kcb *_kcb_ctor(struct kse *);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
amd64_set_fsbase(kcb);
|
||||
}
|
||||
|
||||
/* Get the current kcb. */
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_kcb_curkcb());
|
||||
}
|
||||
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
|
||||
crit = _kcb_readandclear_tmbx();
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
_kcb_set_tmbx(crit);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
return (_kcb_get_tmbx() == NULL);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
kcb->kcb_curtcb = tcb;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_kcb_curtcb());
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
tcb = _kcb_curtcb();
|
||||
if (tcb != NULL)
|
||||
return (tcb->tcb_thread);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return ((struct kse *)_kcb_curkse());
|
||||
}
|
||||
|
||||
void _amd64_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
size_t stacksz);
|
||||
int _amd64_restore_context(mcontext_t *mc, intptr_t val, intptr_t *loc);
|
||||
int _amd64_save_context(mcontext_t *mc);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _amd64_save_context(&tcb->tcb_tmbx.tm_context.uc_mcontext);
|
||||
if (ret == 0) {
|
||||
_amd64_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
else if (ret < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
if ((kcb == NULL) || (tcb == NULL))
|
||||
return (-1);
|
||||
kcb->kcb_curtcb = tcb;
|
||||
if (setmbox != 0)
|
||||
_amd64_restore_context(&tcb->tcb_tmbx.tm_context.uc_mcontext,
|
||||
(intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_amd64_restore_context(&tcb->tcb_tmbx.tm_context.uc_mcontext,
|
||||
0, NULL);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
|
||||
|
||||
SRCS+= thr_enter_uts.S thr_getcontext.S pthread_md.c
|
||||
@@ -1,114 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 David Xu <[email protected]>
|
||||
* Copyright (c) 2001,2003 Daniel Eischen <[email protected]>
|
||||
* 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. Neither the name of the author 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 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/segments.h>
|
||||
#include <machine/sysarch.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *addr;
|
||||
|
||||
addr = malloc(sizeof(struct tcb) + 15);
|
||||
if (addr == NULL)
|
||||
tcb = NULL;
|
||||
else {
|
||||
tcb = (struct tcb *)(((uintptr_t)(addr) + 15) & ~15);
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_addr = addr;
|
||||
tcb->tcb_thread = thread;
|
||||
/* XXX - Allocate tdv/tls */
|
||||
}
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
addr = tcb->tcb_addr;
|
||||
tcb->tcb_addr = NULL;
|
||||
free(addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize KSD. This also includes setting up the LDT.
|
||||
*/
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
union descriptor ldt;
|
||||
struct kcb *kcb;
|
||||
|
||||
kcb = malloc(sizeof(struct kcb));
|
||||
if (kcb != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_self = kcb;
|
||||
kcb->kcb_kse = kse;
|
||||
ldt.sd.sd_hibase = (unsigned int)kcb >> 24;
|
||||
ldt.sd.sd_lobase = (unsigned int)kcb & 0xFFFFFF;
|
||||
ldt.sd.sd_hilimit = (sizeof(struct kcb) >> 16) & 0xF;
|
||||
ldt.sd.sd_lolimit = sizeof(struct kcb) & 0xFFFF;
|
||||
ldt.sd.sd_type = SDT_MEMRWA;
|
||||
ldt.sd.sd_dpl = SEL_UPL;
|
||||
ldt.sd.sd_p = 1;
|
||||
ldt.sd.sd_xx = 0;
|
||||
ldt.sd.sd_def32 = 1;
|
||||
ldt.sd.sd_gran = 0; /* no more than 1M */
|
||||
kcb->kcb_ldt = i386_set_ldt(LDT_AUTO_ALLOC, &ldt, 1);
|
||||
if (kcb->kcb_ldt < 0) {
|
||||
free(kcb);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
if (kcb->kcb_ldt >= 0) {
|
||||
i386_set_ldt(kcb->kcb_ldt, NULL, 1);
|
||||
kcb->kcb_ldt = -1; /* just in case */
|
||||
}
|
||||
free(kcb);
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Jonathan Mini <mini@freebsd.org>.
|
||||
* Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>.
|
||||
* 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. Neither the name of the author 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 DANIEL EISCHEN 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
|
||||
/*
|
||||
* _i386_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
* long stacksz);
|
||||
* +4 = km, +8 = uts, +12 = stack, +16 = size
|
||||
*/
|
||||
ENTRY(_i386_enter_uts)
|
||||
movl %esp, %edx /* save stack */
|
||||
movl 12(%edx), %eax /* get bottom of stack */
|
||||
addl 16(%edx), %eax /* add length */
|
||||
movl %eax, %esp /* switch to uts stack */
|
||||
pushl 4(%edx) /* push the address of the mailbox */
|
||||
call *8(%edx)
|
||||
ret
|
||||
@@ -1,156 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>.
|
||||
* 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. Neither the name of the author 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 DANIEL EISCHEN 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Where do we define these?
|
||||
*/
|
||||
#define MC_LEN_OFFSET 80 /* offset to mc_len from mcontext */
|
||||
#define MC_LEN 640 /* mc_len <machine/ucontext.h> */
|
||||
#define MC_FPFMT_OFFSET 84
|
||||
#define MC_FPFMT_NODEV 0x10000
|
||||
#define MC_FPFMT_387 0x10001
|
||||
#define MC_FPFMT_XMM 0x10002
|
||||
#define MC_OWNEDFP_OFFSET 88
|
||||
#define MC_OWNEDFP_NONE 0x20000
|
||||
#define MC_OWNEDFP_FPU 0x20001
|
||||
#define MC_OWNEDFP_PCB 0x20002
|
||||
#define MC_FPREGS_OFFSET 96 /* offset to FP regs from mcontext */
|
||||
#define MC_FP_CW_OFFSET 96 /* offset to FP control word */
|
||||
|
||||
/*
|
||||
* int thr_setcontext(mcontext_t *mcp, intptr_t val, intptr_t *loc)
|
||||
*
|
||||
* Restores the context in mcp.
|
||||
*
|
||||
* Returns 0 if there are no errors; -1 otherwise
|
||||
*/
|
||||
.weak CNAME(_thr_setcontext)
|
||||
.set CNAME(_thr_setcontext),CNAME(__thr_setcontext)
|
||||
ENTRY(__thr_setcontext)
|
||||
movl 4(%esp), %edx /* get address of mcontext */
|
||||
cmpl $0, %edx /* check for null pointer */
|
||||
jne 1f
|
||||
movl $-1, %eax
|
||||
jmp 8f
|
||||
1: cmpl $MC_LEN, MC_LEN_OFFSET(%edx) /* is context valid? */
|
||||
je 2f
|
||||
movl $-1, %eax /* bzzzt, invalid context */
|
||||
jmp 8f
|
||||
2: /*movl 4(%edx), %gs*/ /* we don't touch %gs */
|
||||
movl 8(%edx), %fs
|
||||
movl 12(%edx), %es
|
||||
movl 16(%edx), %ds
|
||||
movl 76(%edx), %ss
|
||||
movl 20(%edx), %edi
|
||||
movl 24(%edx), %esi
|
||||
movl 28(%edx), %ebp
|
||||
movl %esp, %ecx /* save current stack in ecx */
|
||||
movl 72(%edx), %esp /* switch to context defined stack */
|
||||
pushl 60(%edx) /* push return address on stack */
|
||||
pushl 44(%edx) /* push ecx on stack */
|
||||
pushl 48(%edx) /* push eax on stack */
|
||||
/*
|
||||
* if (mc_fpowned == MC_OWNEDFP_FPU || mc_fpowned == MC_OWNEDFP_PCB) {
|
||||
* if (mc_fpformat == MC_FPFMT_387)
|
||||
* restore 387 FP register format
|
||||
* else if (mc_fpformat == MC_FPFMT_XMM)
|
||||
* restore XMM/SSE FP register format
|
||||
* }
|
||||
*/
|
||||
cmpl $MC_OWNEDFP_FPU, MC_OWNEDFP_OFFSET(%edx)
|
||||
je 3f
|
||||
cmpl $MC_OWNEDFP_PCB, MC_OWNEDFP_OFFSET(%edx)
|
||||
jne 5f
|
||||
3: cmpl $MC_FPFMT_387, MC_FPFMT_OFFSET(%edx)
|
||||
jne 4f
|
||||
frstor MC_FPREGS_OFFSET(%edx) /* restore 387 FP regs */
|
||||
jmp 6f
|
||||
4: cmpl $MC_FPFMT_XMM, MC_FPFMT_OFFSET(%edx)
|
||||
jne 5f
|
||||
fxrstor MC_FPREGS_OFFSET(%edx) /* restore XMM FP regs */
|
||||
jmp 6f
|
||||
5: fninit
|
||||
fldcw MC_FP_CW_OFFSET(%edx)
|
||||
6: pushl 68(%edx) /* push flags register on stack*/
|
||||
movl 36(%edx), %ebx /* restore ebx and edx */
|
||||
movl 40(%edx), %edx
|
||||
movl 12(%ecx), %eax /* get 3rd arg (loc) */
|
||||
cmpl $0, %eax /* do nothing if loc == null */
|
||||
je 7f
|
||||
movl 8(%ecx), %ecx /* get 2nd arg (val) */
|
||||
movl %ecx, (%eax) /* set loc = val */
|
||||
7: popfl /* restore flags after test */
|
||||
popl %eax /* restore eax and ecx last */
|
||||
popl %ecx
|
||||
8: ret
|
||||
|
||||
/*
|
||||
* int thr_getcontext(mcontext_t *mcp);
|
||||
*
|
||||
* Returns -1 if there is an error, 0 no errors; 1 upon return
|
||||
* from a setcontext().
|
||||
*/
|
||||
.weak CNAME(_thr_getcontext)
|
||||
.set CNAME(_thr_getcontext),CNAME(__thr_getcontext)
|
||||
ENTRY(__thr_getcontext)
|
||||
pushl %edx /* save edx */
|
||||
movl 8(%esp), %edx /* get address of mcontext */
|
||||
cmpl $0, %edx /* check for null pointer */
|
||||
jne 1f
|
||||
popl %edx /* restore edx and stack */
|
||||
movl $-1, %eax
|
||||
jmp 2f
|
||||
1: /*movl %gs, 4(%edx)*/ /* we don't touch %gs */
|
||||
movl %fs, 8(%edx)
|
||||
movl %es, 12(%edx)
|
||||
movl %ds, 16(%edx)
|
||||
movl %ss, 76(%edx)
|
||||
movl %edi, 20(%edx)
|
||||
movl %esi, 24(%edx)
|
||||
movl %ebp, 28(%edx)
|
||||
movl %ebx, 36(%edx)
|
||||
movl $1, 48(%edx) /* store successful return in eax */
|
||||
popl %eax /* get saved value of edx */
|
||||
movl %eax, 40(%edx) /* save edx */
|
||||
movl %ecx, 44(%edx)
|
||||
movl (%esp), %eax /* get return address */
|
||||
movl %eax, 60(%edx) /* save return address */
|
||||
fnstcw MC_FP_CW_OFFSET(%edx)
|
||||
movl $MC_LEN, MC_LEN_OFFSET(%edx)
|
||||
movl $MC_FPFMT_NODEV, MC_FPFMT_OFFSET(%edx) /* no FP */
|
||||
movl $MC_OWNEDFP_NONE, MC_OWNEDFP_OFFSET(%edx) /* no FP */
|
||||
pushfl
|
||||
popl %eax /* get eflags */
|
||||
movl %eax, 68(%edx) /* store eflags */
|
||||
movl %esp, %eax /* setcontext pushes the return */
|
||||
addl $4, %eax /* address onto the top of the */
|
||||
movl %eax, 72(%edx) /* stack; account for this */
|
||||
movl 40(%edx), %edx /* restore edx -- is this needed? */
|
||||
xorl %eax, %eax /* return 0 */
|
||||
2: ret
|
||||
@@ -1,51 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Daniel Eischen <[email protected]>
|
||||
* 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. Neither the name of the author 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 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res);
|
||||
*/
|
||||
static inline void
|
||||
atomic_swap32(intptr_t *dst, intptr_t val, intptr_t *res)
|
||||
{
|
||||
__asm __volatile(
|
||||
"xchgl %2, %1; movl %2, %0"
|
||||
: "=m" (*res) : "m" (*dst), "r" (val) : "memory");
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(d, v, r) \
|
||||
atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
|
||||
#define atomic_swap_int(d, v, r) \
|
||||
atomic_swap32((intptr_t *)d, (intptr_t)v, (intptr_t *)r)
|
||||
#endif
|
||||
@@ -1,253 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2002 Daniel Eischen <[email protected]>.
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
extern int _thr_setcontext(mcontext_t *, intptr_t, intptr_t *);
|
||||
extern int _thr_getcontext(mcontext_t *);
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _thr_getcontext(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) _thr_setcontext(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_KSE
|
||||
#undef PER_THREAD
|
||||
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tdv;
|
||||
|
||||
/*
|
||||
* %gs points to a struct kcb.
|
||||
*/
|
||||
struct kcb {
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kcb *kcb_self; /* self reference */
|
||||
int kcb_ldt;
|
||||
struct kse *kcb_kse;
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct tdv *tcb_tdv;
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_addr; /* allocated tcb address */
|
||||
void *tcb_spare; /* align tcb_tmbx to 16 bytes */
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
};
|
||||
|
||||
/*
|
||||
* Evaluates to the byte offset of the per-kse variable name.
|
||||
*/
|
||||
#define __kcb_offset(name) __offsetof(struct kcb, name)
|
||||
|
||||
/*
|
||||
* Evaluates to the type of the per-kse variable name.
|
||||
*/
|
||||
#define __kcb_type(name) __typeof(((struct kcb *)0)->name)
|
||||
|
||||
/*
|
||||
* Evaluates to the value of the per-kse variable name.
|
||||
*/
|
||||
#define KCB_GET32(name) ({ \
|
||||
__kcb_type(name) __result; \
|
||||
\
|
||||
u_int __i; \
|
||||
__asm __volatile("movl %%gs:%1, %0" \
|
||||
: "=r" (__i) \
|
||||
: "m" (*(u_int *)(__kcb_offset(name)))); \
|
||||
__result = *(__kcb_type(name) *)&__i; \
|
||||
\
|
||||
__result; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Sets the value of the per-kse variable name to value val.
|
||||
*/
|
||||
#define KCB_SET32(name, val) ({ \
|
||||
__kcb_type(name) __val = (val); \
|
||||
\
|
||||
u_int __i; \
|
||||
__i = *(u_int *)&__val; \
|
||||
__asm __volatile("movl %1,%%gs:%0" \
|
||||
: "=m" (*(u_int *)(__kcb_offset(name))) \
|
||||
: "r" (__i)); \
|
||||
})
|
||||
|
||||
static __inline u_long
|
||||
__kcb_readandclear32(volatile u_long *addr)
|
||||
{
|
||||
u_long result;
|
||||
|
||||
__asm __volatile (
|
||||
" xorl %0, %0;"
|
||||
" xchgl %%gs:%1, %0;"
|
||||
"# __kcb_readandclear32"
|
||||
: "=&r" (result)
|
||||
: "m" (*addr));
|
||||
return (result);
|
||||
}
|
||||
|
||||
#define KCB_READANDCLEAR32(name) ({ \
|
||||
__kcb_type(name) __result; \
|
||||
\
|
||||
__result = (__kcb_type(name)) \
|
||||
__kcb_readandclear32((u_long *)__kcb_offset(name)); \
|
||||
__result; \
|
||||
})
|
||||
|
||||
|
||||
#define _kcb_curkcb() KCB_GET32(kcb_self)
|
||||
#define _kcb_curtcb() KCB_GET32(kcb_curtcb)
|
||||
#define _kcb_curkse() ((struct kse *)KCB_GET32(kcb_kmbx.km_udata))
|
||||
#define _kcb_get_tmbx() KCB_GET32(kcb_kmbx.km_curthread)
|
||||
#define _kcb_set_tmbx(value) KCB_SET32(kcb_kmbx.km_curthread, (void *)value)
|
||||
#define _kcb_readandclear_tmbx() KCB_READANDCLEAR32(kcb_kmbx.km_curthread)
|
||||
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
void _tcb_dtor(struct tcb *tcb);
|
||||
struct kcb *_kcb_ctor(struct kse *);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
int val;
|
||||
|
||||
val = (kcb->kcb_ldt << 3) | 7;
|
||||
__asm __volatile("movl %0, %%gs" : : "r" (val));
|
||||
}
|
||||
|
||||
/* Get the current kcb. */
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_kcb_curkcb());
|
||||
}
|
||||
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
|
||||
crit = _kcb_readandclear_tmbx();
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
_kcb_set_tmbx(crit);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
return (_kcb_get_tmbx() == NULL);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
kcb->kcb_curtcb = tcb;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_kcb_curtcb());
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
tcb = _kcb_curtcb();
|
||||
if (tcb != NULL)
|
||||
return (tcb->tcb_thread);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return ((struct kse *)_kcb_curkse());
|
||||
}
|
||||
|
||||
void _i386_enter_uts(struct kse_mailbox *km, kse_func_t uts, void *stack,
|
||||
size_t stacksz);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _thr_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext);
|
||||
if (ret == 0) {
|
||||
_i386_enter_uts(&kcb->kcb_kmbx, kcb->kcb_kmbx.km_func,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
else if (ret < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
if ((kcb == NULL) || (tcb == NULL))
|
||||
return (-1);
|
||||
kcb->kcb_curtcb = tcb;
|
||||
if (setmbox != 0)
|
||||
_thr_setcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext,
|
||||
(intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_thr_setcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext, 0, NULL);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,5 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
|
||||
|
||||
SRCS+= context.S enter_uts.S pthread_md.c
|
||||
@@ -1,351 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* 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 ``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 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 <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#define SIZEOF_SPECIAL (18*8)
|
||||
|
||||
/*
|
||||
* int _ia64_restore_context(mcontext_t *mc, intptr_t val, intptr_t *loc);
|
||||
*/
|
||||
ENTRY(_ia64_restore_context, 3)
|
||||
{ .mmi
|
||||
invala
|
||||
mov ar.rsc=0xc
|
||||
add r32=16,r32
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
loadrs
|
||||
ld8 r12=[r32] // sp
|
||||
add r31=8,r32
|
||||
;;
|
||||
}
|
||||
{ .mii
|
||||
ld8 r16=[r31],16 // unat (before)
|
||||
add r30=16,r32
|
||||
add r14=SIZEOF_SPECIAL,r32
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r17=[r30],16 // rp
|
||||
ld8 r18=[r31],16 // pr
|
||||
mov r2=r33
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r19=[r30],16 // pfs
|
||||
ld8 r20=[r31],32 // bspstore
|
||||
mov rp=r17
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r21=[r30],32 // rnat
|
||||
ld8 r22=[r31],16 // rsc
|
||||
mov pr=r18,0x1fffe
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r23=[r30] // fpsr
|
||||
ld8 r24=[r31] // psr -- not used
|
||||
mov r3=r34
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r17=[r14],8 // unat (after)
|
||||
mov ar.bspstore=r20
|
||||
cmp.ne p15,p0=r0,r3
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
mov ar.rnat=r21
|
||||
mov ar.unat=r17
|
||||
add r15=8,r14
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8.fill r4=[r14],16 // r4
|
||||
ld8.fill r5=[r15],16 // r5
|
||||
mov ar.pfs=r19
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8.fill r6=[r14],16 // r6
|
||||
ld8.fill r7=[r15],16 // r7
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
mov ar.unat=r16
|
||||
mov ar.rsc=r22
|
||||
nop 0
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r17=[r14],16 // b1
|
||||
ld8 r18=[r15],16 // b2
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r19=[r14],16 // b3
|
||||
ld8 r20=[r15],16 // b4
|
||||
mov b1=r17
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ld8 r16=[r14],24 // b5
|
||||
ld8 r17=[r15],32 // lc
|
||||
mov b2=r18
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ldf.fill f2=[r14],32
|
||||
ldf.fill f3=[r15],32
|
||||
mov b3=r19
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ldf.fill f4=[r14],32
|
||||
ldf.fill f5=[r15],32
|
||||
mov b4=r20
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ldf.fill f16=[r14],32
|
||||
ldf.fill f17=[r15],32
|
||||
mov b5=r16
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
ldf.fill f18=[r14],32
|
||||
ldf.fill f19=[r15],32
|
||||
mov ar.lc=r17
|
||||
;;
|
||||
}
|
||||
ldf.fill f20=[r14],32
|
||||
ldf.fill f21=[r15],32
|
||||
;;
|
||||
ldf.fill f22=[r14],32
|
||||
ldf.fill f23=[r15],32
|
||||
;;
|
||||
ldf.fill f24=[r14],32
|
||||
ldf.fill f25=[r15],32
|
||||
;;
|
||||
ldf.fill f26=[r14],32
|
||||
ldf.fill f27=[r15],32
|
||||
;;
|
||||
ldf.fill f28=[r14],32
|
||||
ldf.fill f29=[r15],32
|
||||
;;
|
||||
ldf.fill f30=[r14],32+24
|
||||
ldf.fill f31=[r15],24+24
|
||||
;;
|
||||
ld8 r8=[r14],16
|
||||
ld8 r9=[r15],16
|
||||
;;
|
||||
ld8 r10=[r14]
|
||||
ld8 r11=[r15]
|
||||
;;
|
||||
{ .mmb
|
||||
(p15) st8 [r3]=r2
|
||||
mov ar.fpsr=r23
|
||||
br.ret.sptk rp
|
||||
;;
|
||||
}
|
||||
END(_ia64_restore_context)
|
||||
|
||||
/*
|
||||
* int _ia64_save_context(mcontext_t *mc);
|
||||
*/
|
||||
ENTRY(_ia64_save_context, 1)
|
||||
{ .mmi
|
||||
mov r14=ar.rsc
|
||||
mov r15=ar.fpsr
|
||||
add r31=8,r32
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r32]=r0,16
|
||||
st8 [r31]=r0,16
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
mov ar.rsc=0xc
|
||||
mov r16=ar.unat
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
flushrs
|
||||
st8 [r32]=sp,16 // sp
|
||||
mov r17=rp
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r31]=r16,16 // unat (before)
|
||||
st8 [r32]=r17,16 // rp
|
||||
mov r16=pr
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r31]=r16,16 // pr
|
||||
mov r17=ar.bsp
|
||||
mov r16=ar.pfs
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r32]=r16,16 // pfs
|
||||
st8 [r31]=r17,16 // bspstore
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
mov r16=ar.rnat
|
||||
mov ar.rsc=r14
|
||||
add r30=SIZEOF_SPECIAL-(6*8),r32
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r32]=r16,16 // rnat
|
||||
st8 [r31]=r0,16 // __spare
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r32]=r13,16 // tp -- not used
|
||||
st8 [r31]=r14,16 // rsc
|
||||
mov r16=b1
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r32]=r15,10*8 // fpr
|
||||
st8 [r31]=r0,8*8 // psr
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
/* callee_saved */
|
||||
{ .mmi
|
||||
.mem.offset 8,0
|
||||
st8.spill [r31]=r4,16 // r4
|
||||
.mem.offset 16,0
|
||||
st8.spill [r32]=r5,16 // r5
|
||||
mov r17=b2
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
.mem.offset 24,0
|
||||
st8.spill [r31]=r6,16 // r6
|
||||
.mem.offset 32,0
|
||||
st8.spill [r32]=r7,16 // r7
|
||||
mov r18=b3
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r31]=r16,16 // b1
|
||||
mov r16=ar.unat
|
||||
mov r19=b4
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r30]=r16 // unat (after)
|
||||
st8 [r32]=r17,16 // b2
|
||||
mov r16=b5
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
st8 [r31]=r18,16 // b3
|
||||
st8 [r32]=r19,16 // b4
|
||||
mov r17=ar.lc
|
||||
;;
|
||||
}
|
||||
st8 [r31]=r16,16 // b5
|
||||
st8 [r32]=r17,16 // lc
|
||||
;;
|
||||
st8 [r31]=r0,24 // __spare
|
||||
stf.spill [r32]=f2,32
|
||||
;;
|
||||
stf.spill [r31]=f3,32
|
||||
stf.spill [r32]=f4,32
|
||||
;;
|
||||
stf.spill [r31]=f5,32
|
||||
stf.spill [r32]=f16,32
|
||||
;;
|
||||
stf.spill [r31]=f17,32
|
||||
stf.spill [r32]=f18,32
|
||||
;;
|
||||
stf.spill [r31]=f19,32
|
||||
stf.spill [r32]=f20,32
|
||||
;;
|
||||
stf.spill [r31]=f21,32
|
||||
stf.spill [r32]=f22,32
|
||||
;;
|
||||
stf.spill [r31]=f23,32
|
||||
stf.spill [r32]=f24,32
|
||||
;;
|
||||
stf.spill [r31]=f25,32
|
||||
stf.spill [r32]=f26,32
|
||||
;;
|
||||
stf.spill [r31]=f27,32
|
||||
stf.spill [r32]=f28,32
|
||||
;;
|
||||
{ .mmi
|
||||
stf.spill [r31]=f29,32
|
||||
stf.spill [r32]=f30,32+24
|
||||
add r14=1,r0
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
stf.spill [r31]=f31,24+24
|
||||
st8 [r32]=r14,16 // r8
|
||||
add r8=0,r0
|
||||
;;
|
||||
}
|
||||
st8 [r31]=r0,16 // r9
|
||||
st8 [r32]=r0 // r10
|
||||
;;
|
||||
{ .mmb
|
||||
st8 [r31]=r0 // r11
|
||||
mf
|
||||
br.ret.sptk rp
|
||||
;;
|
||||
}
|
||||
END(_ia64_save_context)
|
||||
|
||||
/*
|
||||
* void _ia64_break_setcontext(mcontext_t *mc);
|
||||
*/
|
||||
ENTRY(_ia64_break_setcontext, 1)
|
||||
{ .mmi
|
||||
mov r8=r32
|
||||
break 0x180000
|
||||
nop 0
|
||||
;;
|
||||
}
|
||||
END(_ia64_break_setcontext)
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* 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 ``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 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 <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* void _ia64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack,
|
||||
* size_t stacksz);
|
||||
*/
|
||||
ENTRY(_ia64_enter_uts, 4)
|
||||
{ .mmi
|
||||
ld8 r14=[in0],8
|
||||
mov ar.rsc=0xc
|
||||
add r15=in2,in3
|
||||
;;
|
||||
}
|
||||
{ .mmi
|
||||
flushrs
|
||||
ld8 r1=[in0]
|
||||
mov b7=r14
|
||||
;;
|
||||
}
|
||||
{ .mii
|
||||
mov ar.bspstore=in2
|
||||
add sp=-16,r15
|
||||
mov rp=r14
|
||||
;;
|
||||
}
|
||||
{ .mib
|
||||
mov ar.rsc=0xf
|
||||
mov in0=in1
|
||||
br.cond.sptk b7
|
||||
;;
|
||||
}
|
||||
1: br.cond.sptk 1b
|
||||
END(_ia64_enter_uts)
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Daniel Eischen <[email protected]>
|
||||
* 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. Neither the name of the author 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 AUTHOR ``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 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$
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include "pthread_md.h"
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
if ((tcb = malloc(sizeof(struct tcb))) != NULL) {
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_thread = thread;
|
||||
/* Allocate TDV */
|
||||
}
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
/* Free TDV */
|
||||
free(tcb);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
if ((kcb = malloc(sizeof(struct kcb))) != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_faketcb.tcb_isfake = 1;
|
||||
kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_kse = kse;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
||||
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* 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 ``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 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$
|
||||
*/
|
||||
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _ia64_save_context(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) PANIC("THR_SETCONTEXT() now in use!\n")
|
||||
|
||||
#define PER_THREAD
|
||||
|
||||
struct kcb;
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tcb;
|
||||
struct tdv; /* We don't know what this is yet? */
|
||||
|
||||
/*
|
||||
* tp points to one of these. We define the static TLS as an array
|
||||
* of long double to enforce 16-byte alignment of the TLS memory,
|
||||
* struct ia64_tp, struct tcb and also struct kcb. Both static and
|
||||
* dynamic allocation of any of these structures will result in a
|
||||
* valid, well-aligned thread pointer.
|
||||
*/
|
||||
struct ia64_tp {
|
||||
struct tdv *tp_tdv; /* dynamic TLS */
|
||||
uint64_t _reserved_;
|
||||
long double tp_tls[0]; /* static TLS */
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
struct pthread *tcb_thread;
|
||||
struct kcb *tcb_curkcb;
|
||||
long tcb_isfake;
|
||||
struct ia64_tp tcb_tp;
|
||||
};
|
||||
|
||||
struct kcb {
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
struct tcb kcb_faketcb;
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kse *kcb_kse;
|
||||
};
|
||||
|
||||
register struct ia64_tp *_tp __asm("%r13");
|
||||
|
||||
#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp)))
|
||||
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
/* There is no thread yet; use the fake tcb. */
|
||||
_tp = &kcb->kcb_faketcb.tcb_tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kcb.
|
||||
*
|
||||
* This can only be called while in a critical region; don't
|
||||
* worry about having the kcb changed out from under us.
|
||||
*/
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical region.
|
||||
*
|
||||
* Read and clear km_curthread in the kse mailbox.
|
||||
*/
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
uint32_t flags;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We already are in a critical region since
|
||||
* there is no current thread.
|
||||
*/
|
||||
crit = NULL;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
crit = _tcb->tcb_curkcb->kcb_kmbx.km_curthread;
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL;
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
/* No need to do anything if this is a fake tcb. */
|
||||
if (_tcb->tcb_isfake == 0)
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We are in a critical region since there is no
|
||||
* current thread.
|
||||
*/
|
||||
ret = 1;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
if (tcb == NULL)
|
||||
tcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_curtcb = tcb;
|
||||
tcb->tcb_curkcb = kcb;
|
||||
_tp = &tcb->tcb_tp;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_tcb);
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
return (_tcb->tcb_thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kse.
|
||||
*
|
||||
* Like _kcb_get(), this can only be called while in a critical region.
|
||||
*/
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb->kcb_kse);
|
||||
}
|
||||
|
||||
void _ia64_break_setcontext(mcontext_t *mc);
|
||||
void _ia64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack,
|
||||
size_t stacksz);
|
||||
int _ia64_restore_context(mcontext_t *mc, intptr_t val, intptr_t *loc);
|
||||
int _ia64_save_context(mcontext_t *mc);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
if (_ia64_save_context(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
|
||||
/* Make the fake tcb the current thread. */
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
_tp = &kcb->kcb_faketcb.tcb_tp;
|
||||
_ia64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
mcontext_t *mc;
|
||||
|
||||
_tcb_set(kcb, tcb);
|
||||
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
|
||||
if (mc->mc_flags & _MC_FLAGS_ASYNC_CONTEXT) {
|
||||
if (setmbox) {
|
||||
mc->mc_flags |= _MC_FLAGS_KSE_SET_MBOX;
|
||||
mc->mc_special.ifa =
|
||||
(intptr_t)&kcb->kcb_kmbx.km_curthread;
|
||||
mc->mc_special.isr = (intptr_t)&tcb->tcb_tmbx;
|
||||
}
|
||||
_ia64_break_setcontext(mc);
|
||||
} else {
|
||||
if (setmbox)
|
||||
_ia64_restore_context(mc, (intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_ia64_restore_context(mc, 0, NULL);
|
||||
}
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* _PTHREAD_MD_H_ */
|
||||
@@ -1,5 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}
|
||||
|
||||
SRCS+= pthread_md.c thr_getcontext.S
|
||||
@@ -1,75 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Jake Burkholder <[email protected]>
|
||||
* 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. Neither the name of the author 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 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ATOMIC_OPS_H_
|
||||
#define _ATOMIC_OPS_H_
|
||||
|
||||
#include <machine/atomic.h>
|
||||
|
||||
/*
|
||||
* Atomic swap:
|
||||
* Atomic (tmp = *dst, *dst = val), then *res = tmp
|
||||
*
|
||||
* void atomic_swap_long(long *dst, long val, long *res);
|
||||
*/
|
||||
static __inline void
|
||||
atomic_swap_long(long *dst, long val, long *res)
|
||||
{
|
||||
long tmp;
|
||||
long r;
|
||||
|
||||
tmp = *dst;
|
||||
for (;;) {
|
||||
r = atomic_cas_64(dst, tmp, val);
|
||||
if (r == tmp)
|
||||
break;
|
||||
tmp = r;
|
||||
}
|
||||
*res = tmp;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
atomic_swap_int(int *dst, int val, int *res)
|
||||
{
|
||||
int tmp;
|
||||
int r;
|
||||
|
||||
tmp = *dst;
|
||||
for (;;) {
|
||||
r = atomic_cas_32(dst, tmp, val);
|
||||
if (r == tmp)
|
||||
break;
|
||||
tmp = r;
|
||||
}
|
||||
*res = tmp;
|
||||
}
|
||||
|
||||
#define atomic_swap_ptr(dst, val, res) \
|
||||
atomic_swap_long((long *)dst, (long)val, (long *)res)
|
||||
|
||||
#endif
|
||||
@@ -1,243 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Jake Burkholder <[email protected]>.
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* 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 ``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 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Machine-dependent thread prototypes/definitions for the thread kernel.
|
||||
*/
|
||||
#ifndef _PTHREAD_MD_H_
|
||||
#define _PTHREAD_MD_H_
|
||||
|
||||
#include <sys/kse.h>
|
||||
#include <stddef.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#define KSE_STACKSIZE 16384
|
||||
|
||||
int _thr_setcontext(mcontext_t *, intptr_t, intptr_t *);
|
||||
int _thr_getcontext(mcontext_t *);
|
||||
|
||||
#define THR_GETCONTEXT(ucp) _thr_getcontext(&(ucp)->uc_mcontext)
|
||||
#define THR_SETCONTEXT(ucp) _thr_setcontext(&(ucp)->uc_mcontext, 0, NULL)
|
||||
|
||||
#define PER_THREAD
|
||||
|
||||
struct kcb;
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tcb;
|
||||
struct tdv; /* We don't know what this is yet? */
|
||||
|
||||
|
||||
/*
|
||||
* %g6 points to one of these. We define the static TLS as an array
|
||||
* of long double to enforce 16-byte alignment of the TLS memory.
|
||||
*
|
||||
* XXX - Both static and dynamic allocation of any of these structures
|
||||
* will result in a valid, well-aligned thread pointer???
|
||||
*/
|
||||
struct sparc64_tp {
|
||||
struct tdv *tp_tdv; /* dynamic TLS */
|
||||
uint64_t _reserved_;
|
||||
long double tp_tls[0]; /* static TLS */
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_addr; /* allocated tcb address */
|
||||
struct kcb *tcb_curkcb;
|
||||
uint64_t tcb_isfake;
|
||||
uint64_t tcb_spare[4];
|
||||
struct kse_thr_mailbox tcb_tmbx; /* needs 64-byte alignment */
|
||||
struct sparc64_tp tcb_tp;
|
||||
} __aligned(64);
|
||||
|
||||
struct kcb {
|
||||
struct kse_mailbox kcb_kmbx;
|
||||
struct tcb kcb_faketcb;
|
||||
struct tcb *kcb_curtcb;
|
||||
struct kse *kcb_kse;
|
||||
};
|
||||
|
||||
register struct sparc64_tp *_tp __asm("%g6");
|
||||
|
||||
#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp)))
|
||||
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
||||
/* Called from the KSE to set its private data. */
|
||||
static __inline void
|
||||
_kcb_set(struct kcb *kcb)
|
||||
{
|
||||
/* There is no thread yet; use the fake tcb. */
|
||||
_tp = &kcb->kcb_faketcb.tcb_tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kcb.
|
||||
*
|
||||
* This can only be called while in a critical region; don't
|
||||
* worry about having the kcb changed out from under us.
|
||||
*/
|
||||
static __inline struct kcb *
|
||||
_kcb_get(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter a critical region.
|
||||
*
|
||||
* Read and clear km_curthread in the kse mailbox.
|
||||
*/
|
||||
static __inline struct kse_thr_mailbox *
|
||||
_kcb_critical_enter(void)
|
||||
{
|
||||
struct kse_thr_mailbox *crit;
|
||||
uint32_t flags;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We already are in a critical region since
|
||||
* there is no current thread.
|
||||
*/
|
||||
crit = NULL;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
crit = _tcb->tcb_curkcb->kcb_kmbx.km_curthread;
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL;
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (crit);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_kcb_critical_leave(struct kse_thr_mailbox *crit)
|
||||
{
|
||||
/* No need to do anything if this is a fake tcb. */
|
||||
if (_tcb->tcb_isfake == 0)
|
||||
_tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_kcb_in_critical(void)
|
||||
{
|
||||
uint32_t flags;
|
||||
int ret;
|
||||
|
||||
if (_tcb->tcb_isfake != 0) {
|
||||
/*
|
||||
* We are in a critical region since there is no
|
||||
* current thread.
|
||||
*/
|
||||
ret = 1;
|
||||
} else {
|
||||
flags = _tcb->tcb_tmbx.tm_flags;
|
||||
_tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL;
|
||||
ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL);
|
||||
_tcb->tcb_tmbx.tm_flags = flags;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
_tcb_set(struct kcb *kcb, struct tcb *tcb)
|
||||
{
|
||||
if (tcb == NULL)
|
||||
tcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_curtcb = tcb;
|
||||
tcb->tcb_curkcb = kcb;
|
||||
_tp = &tcb->tcb_tp;
|
||||
}
|
||||
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
return (_tcb);
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
_get_curthread(void)
|
||||
{
|
||||
return (_tcb->tcb_thread);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current kse.
|
||||
*
|
||||
* Like _kcb_get(), this can only be called while in a critical region.
|
||||
*/
|
||||
static __inline struct kse *
|
||||
_get_curkse(void)
|
||||
{
|
||||
return (_tcb->tcb_curkcb->kcb_kse);
|
||||
}
|
||||
|
||||
void _sparc64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack,
|
||||
size_t stacksz);
|
||||
|
||||
static __inline int
|
||||
_thread_enter_uts(struct tcb *tcb, struct kcb *kcb)
|
||||
{
|
||||
if (_thr_getcontext(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) {
|
||||
/* Make the fake tcb the current thread. */
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
_tp = &kcb->kcb_faketcb.tcb_tp;
|
||||
_sparc64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx,
|
||||
kcb->kcb_kmbx.km_stack.ss_sp,
|
||||
kcb->kcb_kmbx.km_stack.ss_size);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox)
|
||||
{
|
||||
mcontext_t *mc;
|
||||
|
||||
_tcb_set(kcb, tcb);
|
||||
mc = &tcb->tcb_tmbx.tm_context.uc_mcontext;
|
||||
if (setmbox)
|
||||
_thr_setcontext(mc, (intptr_t)&tcb->tcb_tmbx,
|
||||
(intptr_t *)&kcb->kcb_kmbx.km_curthread);
|
||||
else
|
||||
_thr_setcontext(mc, 0, NULL);
|
||||
/* We should not reach here. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* _PTHREAD_MD_H_ */
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Offsets into structures used from asm. Must be kept in sync with
|
||||
* appropriate headers.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define UC_MCONTEXT 0x40
|
||||
|
||||
#define MC_FLAGS 0x0
|
||||
#define MC_VALID_FLAGS 0x1
|
||||
#define MC_GLOBAL 0x0
|
||||
#define MC_OUT 0x40
|
||||
#define MC_TPC 0xc8
|
||||
#define MC_TNPC 0xc0
|
||||
@@ -1,91 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 Jake Burkholder <[email protected]>
|
||||
* Copyright (C) 2003 David Xu <[email protected]>
|
||||
* Copyright (c) 2001,2003 Daniel Eischen <[email protected]>
|
||||
* 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. Neither the name of the author 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 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *addr;
|
||||
|
||||
addr = malloc(sizeof(struct tcb) + 63);
|
||||
if (addr == NULL)
|
||||
tcb = NULL;
|
||||
else {
|
||||
tcb = (struct tcb *)(((uintptr_t)(addr) + 63) & ~63);
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_addr = addr;
|
||||
tcb->tcb_thread = thread;
|
||||
/* XXX - Allocate tdv/tls */
|
||||
}
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
addr = tcb->tcb_addr;
|
||||
tcb->tcb_addr = NULL;
|
||||
free(addr);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
_kcb_ctor(struct kse *kse)
|
||||
{
|
||||
struct kcb *kcb;
|
||||
|
||||
kcb = malloc(sizeof(struct kcb));
|
||||
if (kcb != NULL) {
|
||||
bzero(kcb, sizeof(struct kcb));
|
||||
kcb->kcb_faketcb.tcb_isfake = 1;
|
||||
kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL;
|
||||
kcb->kcb_curtcb = &kcb->kcb_faketcb;
|
||||
kcb->kcb_kse = kse;
|
||||
}
|
||||
return (kcb);
|
||||
}
|
||||
|
||||
void
|
||||
_kcb_dtor(struct kcb *kcb)
|
||||
{
|
||||
free(kcb);
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*-
|
||||
* Copyright (C) 2003 Jake Burkholder <jake@freebsd.org>
|
||||
* 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. Neither the name of the author 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 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.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
.weak CNAME(_thr_getcontext)
|
||||
.set CNAME(_thr_getcontext),CNAME(__thr_getcontext)
|
||||
ENTRY(__thr_getcontext)
|
||||
add %o7, 8, %o1
|
||||
add %o1, 4, %o2
|
||||
stx %sp, [%o0 + MC_OUT + (6 * 8)]
|
||||
stx %o1, [%o0 + MC_TPC]
|
||||
stx %o2, [%o0 + MC_TNPC]
|
||||
mov MC_VALID_FLAGS, %l0 /* Validate the context. */
|
||||
stx %l0, [%o0 + MC_FLAGS]
|
||||
mov 1, %l0
|
||||
stx %l0, [%o0 + MC_OUT + (0 * 8)] /* return 1 when resumed */
|
||||
retl
|
||||
mov 0, %o0 /* return 0 */
|
||||
END(__thr_getcontext)
|
||||
|
||||
.weak CNAME(_thr_setcontext)
|
||||
.set CNAME(_thr_setcontext),CNAME(__thr_setcontext)
|
||||
ENTRY(__thr_setcontext)
|
||||
save %sp, -CCFSZ, %sp
|
||||
flushw
|
||||
mov %i0, %l0
|
||||
mov %i1, %l1
|
||||
mov %i2, %l2
|
||||
ldx [%l0 + MC_GLOBAL + (1 * 8)], %g1
|
||||
ldx [%l0 + MC_GLOBAL + (2 * 8)], %g2
|
||||
ldx [%l0 + MC_GLOBAL + (3 * 8)], %g3
|
||||
ldx [%l0 + MC_GLOBAL + (4 * 8)], %g4
|
||||
ldx [%l0 + MC_GLOBAL + (5 * 8)], %g5
|
||||
ldx [%l0 + MC_GLOBAL + (6 * 8)], %g6
|
||||
ldx [%l0 + MC_GLOBAL + (7 * 8)], %g7
|
||||
ldx [%l0 + MC_OUT + (0 * 8)], %i0
|
||||
ldx [%l0 + MC_OUT + (1 * 8)], %i1
|
||||
ldx [%l0 + MC_OUT + (2 * 8)], %i2
|
||||
ldx [%l0 + MC_OUT + (3 * 8)], %i3
|
||||
ldx [%l0 + MC_OUT + (4 * 8)], %i4
|
||||
ldx [%l0 + MC_OUT + (5 * 8)], %i5
|
||||
ldx [%l0 + MC_OUT + (6 * 8)], %i6
|
||||
ldx [%l0 + MC_OUT + (7 * 8)], %i7
|
||||
ldx [%l0 + MC_TPC], %l4
|
||||
ldx [%l0 + MC_TNPC], %l3
|
||||
brz %l2, 1f
|
||||
nop
|
||||
stx %l1, [%l2]
|
||||
1: jmpl %l3, %g0
|
||||
return %l4
|
||||
END(__thr_setcontext)
|
||||
|
||||
ENTRY(_sparc64_enter_uts)
|
||||
save %sp, -CCFSZ, %sp
|
||||
flushw
|
||||
add %i2, %i3, %i2
|
||||
sub %i2, SPOFF + CCFSZ, %sp
|
||||
jmpl %i0, %g0
|
||||
mov %i1, %o0
|
||||
END(_sparc64_enter_uts)
|
||||
@@ -1,39 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/support ${.CURDIR}/../libc/gen ${.CURDIR}/../libc/string
|
||||
.PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/sys
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../libc/${MACHINE_ARCH}
|
||||
|
||||
SYSCALLS= clock_gettime \
|
||||
kse_create \
|
||||
kse_exit \
|
||||
kse_release \
|
||||
kse_thr_interrupt \
|
||||
kse_wakeup \
|
||||
sigaction \
|
||||
sigprocmask \
|
||||
sigtimedwait \
|
||||
write
|
||||
|
||||
SYSCALL_SRC= ${SYSCALLS:S/$/.S/}
|
||||
SYSCALL_OBJ= ${SYSCALLS:S/$/.So/}
|
||||
|
||||
${SYSCALL_SRC}:
|
||||
printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' > ${.TARGET}
|
||||
|
||||
LIBC_OBJS= sigsetops.So \
|
||||
bcopy.So \
|
||||
bzero.So \
|
||||
cerror.So \
|
||||
memcpy.So \
|
||||
memset.So \
|
||||
strcpy.So \
|
||||
strlen.So
|
||||
|
||||
SOBJS+= thr_libc.So
|
||||
CLEANFILES+= ${SYSCALL_SRC} ${SYSCALL_OBJ} ${LIBC_OBJS}
|
||||
|
||||
thr_libc.So: ${SYSCALL_OBJ} ${LIBC_OBJS}
|
||||
${CC} -fPIC -nostdlib -o ${.TARGET} -r ${.ALLSRC}
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2003 Alexander Kabaev.
|
||||
* 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 ``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 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$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kse.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "thr_private.h"
|
||||
|
||||
__strong_reference(clock_gettime, _thr_clock_gettime);
|
||||
__strong_reference(kse_exit, _thr_kse_exit);
|
||||
__strong_reference(kse_wakeup, _thr_kse_wakeup);
|
||||
__strong_reference(kse_create, _thr_kse_create);
|
||||
__strong_reference(kse_thr_interrupt, _thr_kse_thr_interrupt);
|
||||
__strong_reference(kse_release, _thr_kse_release);
|
||||
|
||||
__strong_reference(sigaction, _thr_sigaction);
|
||||
__strong_reference(sigprocmask, _thr_sigprocmask);
|
||||
__strong_reference(sigemptyset, _thr_sigemptyset);
|
||||
__strong_reference(sigaddset, _thr_sigaddset);
|
||||
__strong_reference(sigfillset, _thr_sigfillset);
|
||||
__strong_reference(sigismember, _thr_sigismember);
|
||||
__strong_reference(sigdelset, _thr_sigdelset);
|
||||
|
||||
__strong_reference(memset, _thr_memset);
|
||||
__strong_reference(memcpy, _thr_memcpy);
|
||||
__strong_reference(strcpy, _thr_strcpy);
|
||||
__strong_reference(strlen, _thr_strlen);
|
||||
__strong_reference(bzero, _thr_bzero);
|
||||
__strong_reference(bcopy, _thr_bcopy);
|
||||
|
||||
__strong_reference(__sys_write, _thr__sys_write);
|
||||
__strong_reference(__sys_sigtimedwait, _thr__sys_sigtimedwait);
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/sys
|
||||
|
||||
SRCS+= lock.c thr_error.c
|
||||
@@ -1,344 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2001, 2003 Daniel Eischen <[email protected]>.
|
||||
* 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 AUTHORS 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <machine/atomic.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "atomic_ops.h"
|
||||
#include "lock.h"
|
||||
|
||||
#ifdef _LOCK_DEBUG
|
||||
#define LCK_ASSERT(e) assert(e)
|
||||
#else
|
||||
#define LCK_ASSERT(e)
|
||||
#endif
|
||||
|
||||
#define MAX_SPINS 500
|
||||
|
||||
void
|
||||
_lock_destroy(struct lock *lck)
|
||||
{
|
||||
if ((lck != NULL) && (lck->l_head != NULL)) {
|
||||
free(lck->l_head);
|
||||
lck->l_head = NULL;
|
||||
lck->l_tail = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_lock_init(struct lock *lck, enum lock_type ltype,
|
||||
lock_handler_t *waitfunc, lock_handler_t *wakeupfunc)
|
||||
{
|
||||
if (lck == NULL)
|
||||
return (-1);
|
||||
else if ((lck->l_head = malloc(sizeof(struct lockreq))) == NULL)
|
||||
return (-1);
|
||||
else {
|
||||
lck->l_type = ltype;
|
||||
lck->l_wait = waitfunc;
|
||||
lck->l_wakeup = wakeupfunc;
|
||||
lck->l_head->lr_locked = 0;
|
||||
lck->l_head->lr_watcher = NULL;
|
||||
lck->l_head->lr_owner = NULL;
|
||||
lck->l_head->lr_active = 1;
|
||||
lck->l_tail = lck->l_head;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_lock_reinit(struct lock *lck, enum lock_type ltype,
|
||||
lock_handler_t *waitfunc, lock_handler_t *wakeupfunc)
|
||||
{
|
||||
if (lck == NULL)
|
||||
return (-1);
|
||||
else if (lck->l_head == NULL)
|
||||
return (_lock_init(lck, ltype, waitfunc, wakeupfunc));
|
||||
else {
|
||||
lck->l_head->lr_locked = 0;
|
||||
lck->l_head->lr_watcher = NULL;
|
||||
lck->l_head->lr_owner = NULL;
|
||||
lck->l_head->lr_active = 1;
|
||||
lck->l_tail = lck->l_head;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_lockuser_init(struct lockuser *lu, void *priv)
|
||||
{
|
||||
if (lu == NULL)
|
||||
return (-1);
|
||||
else if ((lu->lu_myreq == NULL) &&
|
||||
((lu->lu_myreq = malloc(sizeof(struct lockreq))) == NULL))
|
||||
return (-1);
|
||||
else {
|
||||
lu->lu_myreq->lr_locked = 1;
|
||||
lu->lu_myreq->lr_watcher = NULL;
|
||||
lu->lu_myreq->lr_owner = lu;
|
||||
lu->lu_myreq->lr_active = 0;
|
||||
lu->lu_watchreq = NULL;
|
||||
lu->lu_priority = 0;
|
||||
lu->lu_private = priv;
|
||||
lu->lu_private2 = NULL;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_lockuser_reinit(struct lockuser *lu, void *priv)
|
||||
{
|
||||
if (lu == NULL)
|
||||
return (-1);
|
||||
/*
|
||||
* All lockusers keep their watch request and drop their
|
||||
* own (lu_myreq) request. Their own request is either
|
||||
* some other lockuser's watch request or is the head of
|
||||
* the lock.
|
||||
*/
|
||||
lu->lu_myreq = lu->lu_watchreq;
|
||||
if (lu->lu_myreq == NULL)
|
||||
return (_lockuser_init(lu, priv));
|
||||
else {
|
||||
lu->lu_myreq->lr_locked = 1;
|
||||
lu->lu_myreq->lr_watcher = NULL;
|
||||
lu->lu_myreq->lr_owner = lu;
|
||||
lu->lu_myreq->lr_active = 0;
|
||||
lu->lu_watchreq = NULL;
|
||||
lu->lu_priority = 0;
|
||||
lu->lu_private = priv;
|
||||
lu->lu_private2 = NULL;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
_lockuser_destroy(struct lockuser *lu)
|
||||
{
|
||||
if ((lu != NULL) && (lu->lu_myreq != NULL))
|
||||
free(lu->lu_myreq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Acquire a lock waiting (spin or sleep) for it to become available.
|
||||
*/
|
||||
void
|
||||
_lock_acquire(struct lock *lck, struct lockuser *lu, int prio)
|
||||
{
|
||||
int i;
|
||||
int lval;
|
||||
|
||||
/**
|
||||
* XXX - We probably want to remove these checks to optimize
|
||||
* performance. It is also a bug if any one of the
|
||||
* checks fail, so it's probably better to just let it
|
||||
* SEGV and fix it.
|
||||
*/
|
||||
#if 0
|
||||
if (lck == NULL || lu == NULL || lck->l_head == NULL)
|
||||
return;
|
||||
#endif
|
||||
if ((lck->l_type & LCK_PRIORITY) != 0) {
|
||||
LCK_ASSERT(lu->lu_myreq->lr_locked == 1);
|
||||
LCK_ASSERT(lu->lu_myreq->lr_watcher == NULL);
|
||||
LCK_ASSERT(lu->lu_myreq->lr_owner == lu);
|
||||
LCK_ASSERT(lu->lu_watchreq == NULL);
|
||||
|
||||
lu->lu_priority = prio;
|
||||
}
|
||||
/*
|
||||
* Atomically swap the head of the lock request with
|
||||
* this request.
|
||||
*/
|
||||
atomic_swap_ptr(&lck->l_head, lu->lu_myreq, &lu->lu_watchreq);
|
||||
|
||||
if (lu->lu_watchreq->lr_locked != 0) {
|
||||
atomic_store_rel_ptr(&lu->lu_watchreq->lr_watcher, lu);
|
||||
if ((lck->l_wait == NULL) ||
|
||||
((lck->l_type & LCK_ADAPTIVE) == 0)) {
|
||||
while (lu->lu_watchreq->lr_locked == 0)
|
||||
; /* spin, then yield? */
|
||||
} else {
|
||||
/*
|
||||
* Spin for a bit before invoking the wait function.
|
||||
*
|
||||
* We should be a little smarter here. If we're
|
||||
* running on a single processor, then the lock
|
||||
* owner got preempted and spinning will accomplish
|
||||
* nothing but waste time. If we're running on
|
||||
* multiple processors, the owner could be running
|
||||
* on another CPU and we might acquire the lock if
|
||||
* we spin for a bit.
|
||||
*
|
||||
* The other thing to keep in mind is that threads
|
||||
* acquiring these locks are considered to be in
|
||||
* critical regions; they will not be preempted by
|
||||
* the _UTS_ until they release the lock. It is
|
||||
* therefore safe to assume that if a lock can't
|
||||
* be acquired, it is currently held by a thread
|
||||
* running in another KSE.
|
||||
*/
|
||||
for (i = 0; i < MAX_SPINS; i++) {
|
||||
if (lu->lu_watchreq->lr_locked == 0)
|
||||
return;
|
||||
if (lu->lu_watchreq->lr_active == 0)
|
||||
break;
|
||||
}
|
||||
atomic_swap_int((int *)&lu->lu_watchreq->lr_locked,
|
||||
2, &lval);
|
||||
if (lval == 0)
|
||||
lu->lu_watchreq->lr_locked = 0;
|
||||
else
|
||||
lck->l_wait(lck, lu);
|
||||
|
||||
}
|
||||
}
|
||||
lu->lu_myreq->lr_active = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release a lock.
|
||||
*/
|
||||
void
|
||||
_lock_release(struct lock *lck, struct lockuser *lu)
|
||||
{
|
||||
struct lockuser *lu_tmp, *lu_h;
|
||||
struct lockreq *myreq;
|
||||
int prio_h;
|
||||
int lval;
|
||||
|
||||
/**
|
||||
* XXX - We probably want to remove these checks to optimize
|
||||
* performance. It is also a bug if any one of the
|
||||
* checks fail, so it's probably better to just let it
|
||||
* SEGV and fix it.
|
||||
*/
|
||||
#if 0
|
||||
if ((lck == NULL) || (lu == NULL))
|
||||
return;
|
||||
#endif
|
||||
if ((lck->l_type & LCK_PRIORITY) != 0) {
|
||||
prio_h = 0;
|
||||
lu_h = NULL;
|
||||
|
||||
/* Update tail if our request is last. */
|
||||
if (lu->lu_watchreq->lr_owner == NULL) {
|
||||
atomic_store_rel_ptr(&lck->l_tail, lu->lu_myreq);
|
||||
atomic_store_rel_ptr(&lu->lu_myreq->lr_owner, NULL);
|
||||
} else {
|
||||
/* Remove ourselves from the list. */
|
||||
atomic_store_rel_ptr(&lu->lu_myreq->lr_owner,
|
||||
lu->lu_watchreq->lr_owner);
|
||||
atomic_store_rel_ptr(
|
||||
&lu->lu_watchreq->lr_owner->lu_myreq, lu->lu_myreq);
|
||||
}
|
||||
/*
|
||||
* The watch request now becomes our own because we've
|
||||
* traded away our previous request. Save our previous
|
||||
* request so that we can grant the lock.
|
||||
*/
|
||||
myreq = lu->lu_myreq;
|
||||
lu->lu_myreq = lu->lu_watchreq;
|
||||
lu->lu_watchreq = NULL;
|
||||
lu->lu_myreq->lr_locked = 1;
|
||||
lu->lu_myreq->lr_owner = lu;
|
||||
lu->lu_myreq->lr_watcher = NULL;
|
||||
/*
|
||||
* Traverse the list of lock requests in reverse order
|
||||
* looking for the user with the highest priority.
|
||||
*/
|
||||
for (lu_tmp = lck->l_tail->lr_watcher; lu_tmp != NULL;
|
||||
lu_tmp = lu_tmp->lu_myreq->lr_watcher) {
|
||||
if (lu_tmp->lu_priority > prio_h) {
|
||||
lu_h = lu_tmp;
|
||||
prio_h = lu_tmp->lu_priority;
|
||||
}
|
||||
}
|
||||
if (lu_h != NULL) {
|
||||
/* Give the lock to the highest priority user. */
|
||||
if (lck->l_wakeup != NULL) {
|
||||
atomic_swap_int(
|
||||
(int *)&lu_h->lu_watchreq->lr_locked,
|
||||
0, &lval);
|
||||
if (lval == 2)
|
||||
/* Notify the sleeper */
|
||||
lck->l_wakeup(lck,
|
||||
lu_h->lu_myreq->lr_watcher);
|
||||
}
|
||||
else
|
||||
atomic_store_rel_int(
|
||||
&lu_h->lu_watchreq->lr_locked, 0);
|
||||
} else {
|
||||
if (lck->l_wakeup != NULL) {
|
||||
atomic_swap_int((int *)&myreq->lr_locked,
|
||||
0, &lval);
|
||||
if (lval == 2)
|
||||
/* Notify the sleeper */
|
||||
lck->l_wakeup(lck, myreq->lr_watcher);
|
||||
}
|
||||
else
|
||||
/* Give the lock to the previous request. */
|
||||
atomic_store_rel_int(&myreq->lr_locked, 0);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* The watch request now becomes our own because we've
|
||||
* traded away our previous request. Save our previous
|
||||
* request so that we can grant the lock.
|
||||
*/
|
||||
myreq = lu->lu_myreq;
|
||||
lu->lu_myreq = lu->lu_watchreq;
|
||||
lu->lu_watchreq = NULL;
|
||||
lu->lu_myreq->lr_locked = 1;
|
||||
if (lck->l_wakeup) {
|
||||
atomic_swap_int((int *)&myreq->lr_locked, 0, &lval);
|
||||
if (lval == 2)
|
||||
/* Notify the sleeper */
|
||||
lck->l_wakeup(lck, myreq->lr_watcher);
|
||||
}
|
||||
else
|
||||
/* Give the lock to the previous request. */
|
||||
atomic_store_rel_int(&myreq->lr_locked, 0);
|
||||
}
|
||||
lu->lu_myreq->lr_active = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_lock_grant(struct lock *lck /* unused */, struct lockuser *lu)
|
||||
{
|
||||
atomic_store_rel_int(&lu->lu_watchreq->lr_locked, 3);
|
||||
}
|
||||
|
||||
void
|
||||
_lockuser_setactive(struct lockuser *lu, int active)
|
||||
{
|
||||
lu->lu_myreq->lr_active = active;
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2003 Daniel Eischen <[email protected]>.
|
||||
* 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 AUTHORS 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _LOCK_H_
|
||||
#define _LOCK_H_
|
||||
|
||||
struct lockreq;
|
||||
struct lockuser;
|
||||
struct lock;
|
||||
|
||||
enum lock_type {
|
||||
LCK_DEFAULT = 0x0000, /* default is FIFO spin locks */
|
||||
LCK_PRIORITY = 0x0001,
|
||||
LCK_ADAPTIVE = 0x0002 /* call user-supplied handlers */
|
||||
};
|
||||
|
||||
typedef void lock_handler_t(struct lock *, struct lockuser *);
|
||||
|
||||
struct lock {
|
||||
struct lockreq *l_head;
|
||||
struct lockreq *l_tail; /* only used for priority locks */
|
||||
enum lock_type l_type;
|
||||
lock_handler_t *l_wait; /* only used for adaptive locks */
|
||||
lock_handler_t *l_wakeup; /* only used for adaptive locks */
|
||||
};
|
||||
|
||||
/* Try to make this >= CACHELINESIZE */
|
||||
struct lockreq {
|
||||
struct lockuser *lr_watcher; /* only used for priority locks */
|
||||
struct lockuser *lr_owner; /* only used for priority locks */
|
||||
volatile int lr_locked; /* lock granted = 0, busy otherwise */
|
||||
volatile int lr_active; /* non-zero if the lock is last lock for thread */
|
||||
};
|
||||
|
||||
struct lockuser {
|
||||
struct lockreq *lu_myreq; /* request to give up/trade */
|
||||
struct lockreq *lu_watchreq; /* watch this request */
|
||||
int lu_priority; /* only used for priority locks */
|
||||
void *lu_private1; /* private{1,2} are initialized to */
|
||||
void *lu_private2; /* NULL and can be used by caller */
|
||||
#define lu_private lu_private1
|
||||
};
|
||||
|
||||
#define _LCK_INITIALIZER(lck_req) { &lck_req, NULL, LCK_DEFAULT, \
|
||||
NULL, NULL }
|
||||
#define _LCK_REQUEST_INITIALIZER { 0, NULL, NULL, 0 }
|
||||
|
||||
#define _LCK_BUSY(lu) ((lu)->lu_watchreq->lr_locked != 0)
|
||||
#define _LCK_ACTIVE(lu) ((lu)->lu_watchreq->lr_active != 0)
|
||||
#define _LCK_GRANTED(lu) ((lu)->lu_watchreq->lr_locked == 3)
|
||||
|
||||
#define _LCK_SET_PRIVATE(lu, p) (lu)->lu_private = (void *)(p)
|
||||
#define _LCK_GET_PRIVATE(lu) (lu)->lu_private
|
||||
#define _LCK_SET_PRIVATE2(lu, p) (lu)->lu_private2 = (void *)(p)
|
||||
#define _LCK_GET_PRIVATE2(lu) (lu)->lu_private2
|
||||
|
||||
void _lock_acquire(struct lock *, struct lockuser *, int);
|
||||
void _lock_destroy(struct lock *);
|
||||
void _lock_grant(struct lock *, struct lockuser *);
|
||||
int _lock_init(struct lock *, enum lock_type,
|
||||
lock_handler_t *, lock_handler_t *);
|
||||
int _lock_reinit(struct lock *, enum lock_type,
|
||||
lock_handler_t *, lock_handler_t *);
|
||||
void _lock_release(struct lock *, struct lockuser *);
|
||||
int _lockuser_init(struct lockuser *lu, void *priv);
|
||||
void _lockuser_destroy(struct lockuser *lu);
|
||||
int _lockuser_reinit(struct lockuser *lu, void *priv);
|
||||
void _lockuser_setactive(struct lockuser *lu, int active);
|
||||
|
||||
#endif
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
|
||||
* Copyright (c) 1994 by Chris Provenzano, proven@mit.edu
|
||||
* 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
|
||||
* and Chris Provenzano.
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include <pthread.h>
|
||||
#include "libc_private.h"
|
||||
#include "thr_private.h"
|
||||
|
||||
extern int errno;
|
||||
|
||||
int *
|
||||
__error(void)
|
||||
{
|
||||
struct pthread *curthread;
|
||||
|
||||
if (__isthreaded == 0)
|
||||
return (&errno);
|
||||
else if (_kse_in_critical())
|
||||
return &(_get_curkse()->k_error);
|
||||
else {
|
||||
curthread = _get_curthread();
|
||||
if ((curthread == NULL) || (curthread == _thr_initial))
|
||||
return (&errno);
|
||||
else
|
||||
return (&curthread->error);
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
# Automated test suite for libpthread (pthreads).
|
||||
#
|
||||
|
||||
# File lists.
|
||||
|
||||
# Tests written in C.
|
||||
CTESTS := hello_d.c hello_s.c join_leak_d.c mutex_d.c sem_d.c sigsuspend_d.c \
|
||||
sigwait_d.c
|
||||
|
||||
# C programs that are used internally by the tests. The build system merely
|
||||
# compiles these.
|
||||
BTESTS := guard_b.c hello_b.c
|
||||
|
||||
# Tests written in perl.
|
||||
PTESTS := guard_s.pl propagate_s.pl
|
||||
|
||||
# Munge the file lists to their final executable names (strip the .c).
|
||||
CTESTS := $(CTESTS:R)
|
||||
BTESTS := $(BTESTS:R)
|
||||
|
||||
CPPFLAGS := -D_LIBC_R_ -D_REENTRANT
|
||||
CFLAGS := -Wall -pipe -g3
|
||||
LDFLAGS_A := -static
|
||||
LDFLAGS_P := -pg
|
||||
LDFLAGS_S :=
|
||||
LIBS := -lkse
|
||||
|
||||
# Flags passed to verify. "-v" or "-u" may be useful.
|
||||
VERIFY = perl verify
|
||||
VFLAGS :=
|
||||
|
||||
all : default
|
||||
|
||||
# Only use the following suffixes, in order to avoid any strange built-in rules.
|
||||
.SUFFIXES :
|
||||
.SUFFIXES : .c .o .d .pl
|
||||
|
||||
# Clear out all paths, then set just one (default path) for the main build
|
||||
# directory.
|
||||
.PATH :
|
||||
.PATH : .
|
||||
|
||||
# Build the C programs.
|
||||
.for bin in $(CTESTS) $(BTESTS)
|
||||
$(bin)_a : $(bin:S/$/&.c/)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/)
|
||||
$(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_A) $(LIBS)
|
||||
@$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_a.o \2/g\" > $(@:R:S/$/&.d/)"
|
||||
|
||||
$(bin)_p : $(bin:S/$/&.c/)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/)
|
||||
$(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_P) $(LIBS)
|
||||
@$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_p.o \2/g\" > $(@:R:S/$/&.d/)"
|
||||
|
||||
$(bin)_s : $(bin:S/$/&.c/)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(bin:S/$/&.c/) -o $(@:S/$/&.o/)
|
||||
$(CC) -o $@ $(@:S/$/&.o/) $(LDFLAGS_S) $(LIBS)
|
||||
@$(SHELL) -ec "$(CC) -M $(CPPFLAGS) $(bin:S/$/&.c/) | sed \"s/\($(bin:T)\)\.o\([ :]*\)/$(bin:H:S!/!\\/!g)\/\1_s.o \2/g\" > $(@:R:S/$/&.d/)"
|
||||
.endfor
|
||||
|
||||
# Dependency file inclusion.
|
||||
.for depfile in $(CTESTS:R:S/$/&_a.d/) $(BTESTS:R:S/$/&_a.d/) \
|
||||
$(CTESTS:R:S/$/&_p.d/) $(BTESTS:R:S/$/&_p.d/) \
|
||||
$(CTESTS:R:S/$/&_s.d/) $(BTESTS:R:S/$/&_s.d/)
|
||||
.if exists($(depfile))
|
||||
.include "$(depfile)"
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
default : check
|
||||
|
||||
tests_a : $(CTESTS:S/$/&_a/) $(BTESTS:S/$/&_a/)
|
||||
tests_p : $(CTESTS:S/$/&_p/) $(BTESTS:S/$/&_p/)
|
||||
tests_s : $(CTESTS:S/$/&_s/) $(BTESTS:S/$/&_s/)
|
||||
|
||||
tests : tests_a tests_p tests_s
|
||||
|
||||
check_a : tests_a
|
||||
.for bin in $(CTESTS) $(BTESTS)
|
||||
@cp $(bin)_a $(bin)
|
||||
.endfor
|
||||
@echo "Test static library:"
|
||||
@$(VERIFY) $(VFLAGS) $(CTESTS) $(PTESTS)
|
||||
|
||||
check_p : tests_p
|
||||
.for bin in $(CTESTS) $(BTESTS)
|
||||
@cp $(bin)_p $(bin)
|
||||
.endfor
|
||||
@echo "Test profile library:"
|
||||
@$(VERIFY) $(VFLAGS) $(CTESTS) $(PTESTS)
|
||||
|
||||
check_s : tests_s
|
||||
.for bin in $(CTESTS) $(BTESTS)
|
||||
@cp $(bin)_s $(bin)
|
||||
.endfor
|
||||
@echo "Test shared library:"
|
||||
@$(VERIFY) $(VFLAGS) $(CTESTS) $(PTESTS)
|
||||
|
||||
check : check_a check_p check_s
|
||||
|
||||
clean :
|
||||
rm -f *~
|
||||
rm -f *.core
|
||||
rm -f *.out
|
||||
rm -f *.perf
|
||||
rm -f *.diff
|
||||
rm -f *.gmon
|
||||
rm -f $(CTESTS) $(BTESTS)
|
||||
rm -f $(CTESTS:S/$/&_a/) $(BTESTS:S/$/&_a/)
|
||||
rm -f $(CTESTS:S/$/&_p/) $(BTESTS:S/$/&_p/)
|
||||
rm -f $(CTESTS:S/$/&_s/) $(BTESTS:S/$/&_s/)
|
||||
rm -f *.d
|
||||
rm -f *.o
|
||||
@@ -1,28 +0,0 @@
|
||||
$FreeBSD$
|
||||
|
||||
This test suite is meant to test general functionality of pthreads, as well as
|
||||
provide a simple framework for regression tests. In general, this test suite
|
||||
can be used with any pthreads library, but in reality there are a number of
|
||||
libpthread-specific aspects to this test suite which would require some
|
||||
effort to get around if testing another pthreads library.
|
||||
|
||||
This test suite assumes that libpthread is installed.
|
||||
|
||||
There are two forms of test that the 'verify' script understands. The simpler
|
||||
form is the diff format, where the output of the test program is diff'ed with
|
||||
the correspondingly named .exp file. If there is diff output, the test fails.
|
||||
The sequence test format is somewhat more complex, and is documented in the
|
||||
command line usage output for verify. The advantage of this format is that it
|
||||
allows multiple tests to pass/fail within one program.
|
||||
|
||||
There is no driving need for test naming consistency, but the existing tests
|
||||
generally follow these conventions:
|
||||
|
||||
<name>_d.c <name>_d.exp : Diff mode C test and expected output file.
|
||||
<name>_s.c : Sequence mode C test.
|
||||
<name>_b*.c : Back end C program used by perl tests.
|
||||
<name>_d.pl <name>_d.pl.exp : Diff mode perl test and expected output file.
|
||||
<name>_s.pl : Sequence mode perl test.
|
||||
|
||||
<name> is something descriptive, such as "pr14685" in the case of a PR-related
|
||||
regression test, or "mutex" in the case of a test of mutexes.
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Jason Evans <jasone@freebsd.org>.
|
||||
* 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(s), this list of conditions and the following disclaimer
|
||||
* unmodified other than the allowable addition of one or more
|
||||
* copyright notices.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
*
|
||||
* Test thread stack guard functionality.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define FRAME_SIZE 1024
|
||||
#define FRAME_OVERHEAD 40
|
||||
|
||||
struct args
|
||||
{
|
||||
void *top; /* Top of thread's initial stack frame. */
|
||||
int cur; /* Recursion depth. */
|
||||
int max; /* Maximum recursion depth. */
|
||||
};
|
||||
|
||||
void *
|
||||
recurse(void *args)
|
||||
{
|
||||
int top;
|
||||
struct args *parms = (struct args *)args;
|
||||
char filler[FRAME_SIZE - FRAME_OVERHEAD];
|
||||
|
||||
/* Touch the memory in this stack frame. */
|
||||
top = 0xa5;
|
||||
memset(filler, 0xa5, sizeof(filler));
|
||||
|
||||
if (parms->top == NULL) {
|
||||
/* Initial stack frame. */
|
||||
parms->top = (void*)⊤
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure frame size is what we expect. Getting this right involves
|
||||
* hand tweaking, so just print a warning rather than aborting.
|
||||
*/
|
||||
if (parms->top - (void *)&top != FRAME_SIZE * parms->cur) {
|
||||
fprintf(stderr, "Stack size (%d) != expected (%d), frame %d\n",
|
||||
parms->top - (void *)&top, FRAME_SIZE * parms->cur,
|
||||
parms->cur);
|
||||
}
|
||||
|
||||
parms->cur++;
|
||||
if (parms->cur < parms->max)
|
||||
recurse(args);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
size_t def_stacksize, def_guardsize;
|
||||
size_t stacksize, guardsize;
|
||||
pthread_t thread;
|
||||
pthread_attr_t attr;
|
||||
struct args args;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage: guard_b <stacksize> <guardsize>\n");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "Test begin\n");
|
||||
|
||||
stacksize = strtoul(argv[1], NULL, 10);
|
||||
guardsize = strtoul(argv[2], NULL, 10);
|
||||
|
||||
assert(pthread_attr_init(&attr) == 0);
|
||||
/*
|
||||
* Exercise the attribute APIs more thoroughly than is strictly
|
||||
* necessary for the meat of this test program.
|
||||
*/
|
||||
assert(pthread_attr_getstacksize(&attr, &def_stacksize) == 0);
|
||||
assert(pthread_attr_getguardsize(&attr, &def_guardsize) == 0);
|
||||
if (def_stacksize != stacksize) {
|
||||
assert(pthread_attr_setstacksize(&attr, stacksize) == 0);
|
||||
assert(pthread_attr_getstacksize(&attr, &def_stacksize) == 0);
|
||||
assert(def_stacksize == stacksize);
|
||||
}
|
||||
if (def_guardsize != guardsize) {
|
||||
assert(pthread_attr_setguardsize(&attr, guardsize) == 0);
|
||||
assert(pthread_attr_getguardsize(&attr, &def_guardsize) == 0);
|
||||
assert(def_guardsize >= guardsize);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a thread that will come just short of overflowing the thread
|
||||
* stack. We need to leave a bit of breathing room in case the thread
|
||||
* is context switched, and we also have to take care not to call any
|
||||
* functions in the deepest stack frame.
|
||||
*/
|
||||
args.top = NULL;
|
||||
args.cur = 0;
|
||||
args.max = (stacksize / FRAME_SIZE) - 1;
|
||||
fprintf(stderr, "No overflow:\n");
|
||||
assert(pthread_create(&thread, &attr, recurse, &args) == 0);
|
||||
assert(pthread_join(thread, NULL) == 0);
|
||||
|
||||
/*
|
||||
* Create a thread that will barely of overflow the thread stack. This
|
||||
* should cause a segfault.
|
||||
*/
|
||||
args.top = NULL;
|
||||
args.cur = 0;
|
||||
args.max = (stacksize / FRAME_SIZE) + 1;
|
||||
fprintf(stderr, "Overflow:\n");
|
||||
assert(pthread_create(&thread, &attr, recurse, &args) == 0);
|
||||
assert(pthread_join(thread, NULL) == 0);
|
||||
|
||||
/* Not reached. */
|
||||
fprintf(stderr, "Unexpected success\n");
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
Test begin
|
||||
No overflow:
|
||||
Overflow:
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# Copyright (C) 2001 Jason Evans <[email protected]>.
|
||||
# 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(s), this list of conditions and the following disclaimer
|
||||
# unmodified other than the allowable addition of one or more
|
||||
# copyright notices.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
#
|
||||
# Test thread stack guard functionality. The C test program needs to be driven
|
||||
# by this script because it segfaults when the stack guard is hit.
|
||||
#
|
||||
|
||||
print "1..30\n";
|
||||
|
||||
$i = 0;
|
||||
# Iterates 10 times.
|
||||
for ($stacksize = 65536; $stacksize < 131072; $stacksize += 7168)
|
||||
{
|
||||
# Iterates 3 times (1024, 4096, 7168).
|
||||
for ($guardsize = 1024; $guardsize < 8192; $guardsize += 3072)
|
||||
{
|
||||
$i++;
|
||||
|
||||
print "stacksize: $stacksize, guardsize: $guardsize\n";
|
||||
|
||||
`./guard_b $stacksize $guardsize >guard_b.out 2>&1`;
|
||||
|
||||
if (! -f "./guard_b.out")
|
||||
{
|
||||
print "not ok $i\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
`diff guard_b.exp guard_b.out >guard_b.diff 2>&1`;
|
||||
if ($?)
|
||||
{
|
||||
# diff returns non-zero if there is a difference.
|
||||
print "not ok $i\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print "ok $i\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Back end C programs can be anything compilable.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Simple diff mode test.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
void *
|
||||
entry(void * a_arg)
|
||||
{
|
||||
fprintf(stderr, "Hello world\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
pthread_t thread;
|
||||
int error;
|
||||
|
||||
error = pthread_create(&thread, NULL, entry, NULL);
|
||||
if (error)
|
||||
fprintf(stderr, "Error in pthread_create(): %s\n",
|
||||
strerror(error));
|
||||
|
||||
error = pthread_join(thread, NULL);
|
||||
if (error)
|
||||
fprintf(stderr, "Error in pthread_join(): %s\n",
|
||||
strerror(error));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
Hello world
|
||||
@@ -1,47 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Simple sequence mode test.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
void *
|
||||
entry(void * a_arg)
|
||||
{
|
||||
fprintf(stderr, "ok 1\n");
|
||||
fprintf(stderr, "ok \n");
|
||||
fprintf(stderr, "ok 3\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
pthread_t thread;
|
||||
int error;
|
||||
|
||||
fprintf(stderr, "1..3\n");
|
||||
|
||||
fprintf(stderr, "Some random text\n");
|
||||
|
||||
error = pthread_create(&thread, NULL, entry, NULL);
|
||||
fprintf(stderr, "More unimportant text\n");
|
||||
if (error)
|
||||
fprintf(stderr,"Error in pthread_create(): %s\n",
|
||||
strerror(error));
|
||||
|
||||
error = pthread_join(thread, NULL);
|
||||
if (error)
|
||||
fprintf(stderr, "Error in pthread_join(): %s\n",
|
||||
strerror(error));
|
||||
|
||||
fprintf(stderr, "Hello world\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Jason Evans <jasone@freebsd.org>.
|
||||
* 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(s), this list of conditions and the following disclaimer as
|
||||
* the first lines of this file unmodified other than the possible
|
||||
* addition of one or more copyright notices.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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$
|
||||
*
|
||||
* Test for leaked joined threads.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define NITERATIONS 16384
|
||||
#define MAXGROWTH 16384
|
||||
|
||||
void *
|
||||
thread_entry(void *a_arg)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
pthread_t thread;
|
||||
int i, error;
|
||||
char *brk, *nbrk;
|
||||
unsigned growth;
|
||||
|
||||
fprintf(stderr, "Test begin\n");
|
||||
|
||||
/* Get an initial brk value. */
|
||||
brk = sbrk(0);
|
||||
|
||||
/* Create threads and join them, one at a time. */
|
||||
for (i = 0; i < NITERATIONS; i++) {
|
||||
if ((error = pthread_create(&thread, NULL, thread_entry, NULL))
|
||||
!= 0) {
|
||||
fprintf(stderr, "Error in pthread_create(): %s\n",
|
||||
strerror(error));
|
||||
exit(1);
|
||||
}
|
||||
if ((error = pthread_join(thread, NULL)) != 0) {
|
||||
fprintf(stderr, "Error in pthread_join(): %s\n",
|
||||
strerror(error));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a final brk value. */
|
||||
nbrk = sbrk(0);
|
||||
|
||||
/*
|
||||
* Check that the amount of heap space allocated is below an acceptable
|
||||
* threshold. We could just compare brk and nbrk, but the test could
|
||||
* conceivably break if the internals of the threads library changes.
|
||||
*/
|
||||
if (nbrk > brk) {
|
||||
/* Heap grows up. */
|
||||
growth = nbrk - brk;
|
||||
} else if (nbrk <= brk) {
|
||||
/* Heap grows down, or no growth. */
|
||||
growth = brk - nbrk;
|
||||
}
|
||||
|
||||
if (growth > MAXGROWTH) {
|
||||
fprintf(stderr, "Heap growth exceeded maximum (%u > %u)\n",
|
||||
growth, MAXGROWTH);
|
||||
}
|
||||
#if (0)
|
||||
else {
|
||||
fprintf(stderr, "Heap growth acceptable (%u <= %u)\n",
|
||||
growth, MAXGROWTH);
|
||||
}
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "Test end\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
Test begin
|
||||
Test end
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,290 +0,0 @@
|
||||
|
||||
Testing pthread_mutex_init
|
||||
--------------------------
|
||||
Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified) - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified) - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified) - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE - PASS
|
||||
|
||||
Testing pthread_mutex_destroy
|
||||
-----------------------------
|
||||
Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified)
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified)
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified)
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Destruction of unused mutex - PASS
|
||||
Destruction of mutex locked by self - PASS
|
||||
Destruction of mutex locked by another thread - PASS
|
||||
Destruction of mutex while being used in cond_wait - PASS
|
||||
|
||||
Testing pthread_mutex_lock
|
||||
--------------------------
|
||||
Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified)
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified)
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified)
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Lock on unlocked mutex - PASS
|
||||
Lock on invalid mutex - PASS
|
||||
Lock on mutex held by self - PASS
|
||||
|
||||
Testing pthread_mutex_unlock
|
||||
----------------------------
|
||||
Protocol PTHREAD_PRIO_NONE, Type POSIX (type not specified)
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_NONE, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type POSIX (type not specified)
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type POSIX (type not specified)
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
Protocol PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Unlock on mutex held by self - PASS
|
||||
Unlock on invalid mutex - PASS
|
||||
Unlock on mutex locked by another thread - PASS
|
||||
|
||||
Testing queueing order
|
||||
----------------------
|
||||
Queueing order on a mutex - PASS
|
||||
Queueing order on a condition variable - PASS
|
||||
|
||||
Testing priority inheritence
|
||||
----------------------------
|
||||
Protype PTHREAD_PRIO_INHERIT, Type POSIX (type not specified)
|
||||
Simple inheritence test - PASS
|
||||
Inheritence test with change of priority - PASS
|
||||
Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Simple inheritence test - PASS
|
||||
Inheritence test with change of priority - PASS
|
||||
Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Simple inheritence test - PASS
|
||||
Inheritence test with change of priority - PASS
|
||||
Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Simple inheritence test - PASS
|
||||
Inheritence test with change of priority - PASS
|
||||
Protype PTHREAD_PRIO_INHERIT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Simple inheritence test - PASS
|
||||
Inheritence test with change of priority - PASS
|
||||
|
||||
Testing priority ceilings
|
||||
-------------------------
|
||||
Protype PTHREAD_PRIO_PROTECT, Type POSIX (type not specified)
|
||||
Lock with ceiling priority < thread priority - PASS
|
||||
Lock with ceiling priority = thread priority - PASS
|
||||
Lock with ceiling priority > thread priority - PASS
|
||||
Preemption with ceiling priority < thread priority - PASS
|
||||
Preemption with ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority > thread priority - PASS
|
||||
Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_DEFAULT
|
||||
Lock with ceiling priority < thread priority - PASS
|
||||
Lock with ceiling priority = thread priority - PASS
|
||||
Lock with ceiling priority > thread priority - PASS
|
||||
Preemption with ceiling priority < thread priority - PASS
|
||||
Preemption with ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority > thread priority - PASS
|
||||
Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_ERRORCHECK
|
||||
Lock with ceiling priority < thread priority - PASS
|
||||
Lock with ceiling priority = thread priority - PASS
|
||||
Lock with ceiling priority > thread priority - PASS
|
||||
Preemption with ceiling priority < thread priority - PASS
|
||||
Preemption with ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority > thread priority - PASS
|
||||
Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_NORMAL
|
||||
Lock with ceiling priority < thread priority - PASS
|
||||
Lock with ceiling priority = thread priority - PASS
|
||||
Lock with ceiling priority > thread priority - PASS
|
||||
Preemption with ceiling priority < thread priority - PASS
|
||||
Preemption with ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority > thread priority - PASS
|
||||
Protype PTHREAD_PRIO_PROTECT, Type SS2 PTHREAD_MUTEX_RECURSIVE
|
||||
Lock with ceiling priority < thread priority - PASS
|
||||
Lock with ceiling priority = thread priority - PASS
|
||||
Lock with ceiling priority > thread priority - PASS
|
||||
Preemption with ceiling priority < thread priority - PASS
|
||||
Preemption with ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority = thread priority - PASS
|
||||
SCHED_FIFO scheduling and ceiling priority > thread priority - PASS
|
||||
|
||||
Total tests 212, passed 212, failed 0
|
||||
@@ -1,74 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# Copyright (C) 2000 Jason Evans <[email protected]>.
|
||||
# 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(s), this list of conditions and the following disclaimer as
|
||||
# the first lines of this file unmodified other than the possible
|
||||
# addition of one or more copyright notices.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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.
|
||||
#
|
||||
###########################################################################
|
||||
#
|
||||
# Verify that no cancellation points are propagated inside of libpthread.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
@CPOINTS = ("aio_suspend", "close", "creat", "fcntl", "fsync", "mq_receive",
|
||||
"mq_send", "msync", "nanosleep", "open", "pause",
|
||||
"pthread_cond_timedwait", "pthread_cond_wait", "pthread_join",
|
||||
"pthread_testcancel", "read", "sem_wait", "sigsuspend",
|
||||
"sigtimedwait", "sigwait", "sigwaitinfo", "sleep", "system",
|
||||
"tcdrain", "wait", "waitpid", "write");
|
||||
|
||||
print "1..1\n";
|
||||
|
||||
$cpoints = join '\|', @CPOINTS;
|
||||
$regexp = "\" U \\(" . $cpoints . "\\\)\$\"";
|
||||
|
||||
`nm -a /usr/lib/libc.a |grep $regexp >propagate_s.out`;
|
||||
if (!open (NMOUT, "<./propagate_s.out"))
|
||||
{
|
||||
print "not ok 1\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$propagations = 0;
|
||||
|
||||
while (<NMOUT>)
|
||||
{
|
||||
$propagations++;
|
||||
print "$_\n";
|
||||
}
|
||||
if ($propagations != 0)
|
||||
{
|
||||
print "$propagations propagation(s)\n";
|
||||
print "not ok 1\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print "ok 1\n";
|
||||
}
|
||||
close NMOUT;
|
||||
unlink "propagate_s.out";
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
|
||||
* 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(s), this list of conditions and the following disclaimer as
|
||||
* the first lines of this file unmodified other than the possible
|
||||
* addition of one or more copyright notices.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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.
|
||||
*
|
||||
****************************************************************************
|
||||
*
|
||||
* sem test.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define NTHREADS 10
|
||||
|
||||
void *
|
||||
entry(void * a_arg)
|
||||
{
|
||||
sem_t * sem = (sem_t *) a_arg;
|
||||
|
||||
sem_wait(sem);
|
||||
fprintf(stderr, "Got semaphore\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
sem_t sem_a, sem_b;
|
||||
pthread_t threads[NTHREADS];
|
||||
unsigned i;
|
||||
int val;
|
||||
|
||||
fprintf(stderr, "Test begin\n");
|
||||
|
||||
#ifdef _LIBC_R_
|
||||
assert(-1 == sem_init(&sem_b, 1, 0));
|
||||
assert(EPERM == errno);
|
||||
#endif
|
||||
|
||||
assert(0 == sem_init(&sem_b, 0, 0));
|
||||
assert(0 == sem_getvalue(&sem_b, &val));
|
||||
assert(0 == val);
|
||||
|
||||
assert(0 == sem_post(&sem_b));
|
||||
assert(0 == sem_getvalue(&sem_b, &val));
|
||||
assert(1 == val);
|
||||
|
||||
assert(0 == sem_wait(&sem_b));
|
||||
assert(-1 == sem_trywait(&sem_b));
|
||||
assert(EAGAIN == errno);
|
||||
assert(0 == sem_post(&sem_b));
|
||||
assert(0 == sem_trywait(&sem_b));
|
||||
assert(0 == sem_post(&sem_b));
|
||||
assert(0 == sem_wait(&sem_b));
|
||||
assert(0 == sem_post(&sem_b));
|
||||
|
||||
#ifdef _LIBC_R_
|
||||
assert(SEM_FAILED == sem_open("/foo", O_CREAT | O_EXCL, 0644, 0));
|
||||
assert(ENOSYS == errno);
|
||||
|
||||
assert(-1 == sem_close(&sem_b));
|
||||
assert(ENOSYS == errno);
|
||||
|
||||
assert(-1 == sem_unlink("/foo"));
|
||||
assert(ENOSYS == errno);
|
||||
#endif
|
||||
|
||||
assert(0 == sem_destroy(&sem_b));
|
||||
|
||||
assert(0 == sem_init(&sem_a, 0, 0));
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
pthread_create(&threads[i], NULL, entry, (void *) &sem_a);
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
assert(0 == sem_post(&sem_a));
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
pthread_create(&threads[i], NULL, entry, (void *) &sem_a);
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
assert(0 == sem_post(&sem_a));
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
assert(0 == sem_destroy(&sem_a));
|
||||
|
||||
fprintf(stderr, "Test end\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
Test begin
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Got semaphore
|
||||
Test end
|
||||
@@ -1,290 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com>
|
||||
* 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 Daniel M. Eischen.
|
||||
* 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 DANIEL M. EISCHEN 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$
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_LIBC_R_)
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
static int sigcounts[NSIG + 1];
|
||||
static int sigfifo[NSIG + 1];
|
||||
static int fifo_depth = 0;
|
||||
static sigset_t suspender_mask;
|
||||
static pthread_t suspender_tid;
|
||||
|
||||
|
||||
static void *
|
||||
sigsuspender (void *arg)
|
||||
{
|
||||
int save_count, status, i;
|
||||
sigset_t run_mask;
|
||||
|
||||
/* Run with all signals blocked. */
|
||||
sigfillset (&run_mask);
|
||||
sigprocmask (SIG_SETMASK, &run_mask, NULL);
|
||||
|
||||
/* Allow these signals to wake us up during a sigsuspend. */
|
||||
sigfillset (&suspender_mask); /* Default action */
|
||||
sigdelset (&suspender_mask, SIGKILL); /* Cannot catch */
|
||||
sigdelset (&suspender_mask, SIGSTOP); /* Cannot catch */
|
||||
sigdelset (&suspender_mask, SIGINT); /* terminate */
|
||||
sigdelset (&suspender_mask, SIGHUP); /* terminate */
|
||||
sigdelset (&suspender_mask, SIGQUIT); /* create core image */
|
||||
sigdelset (&suspender_mask, SIGURG); /* ignore */
|
||||
sigdelset (&suspender_mask, SIGIO); /* ignore */
|
||||
sigdelset (&suspender_mask, SIGUSR2); /* terminate */
|
||||
|
||||
while (sigcounts[SIGINT] == 0) {
|
||||
save_count = sigcounts[SIGUSR2];
|
||||
|
||||
status = sigsuspend (&suspender_mask);
|
||||
if ((status == 0) || (errno != EINTR)) {
|
||||
fprintf (stderr, "Unable to suspend for signals, "
|
||||
"errno %d, return value %d\n",
|
||||
errno, status);
|
||||
exit (1);
|
||||
}
|
||||
for (i = 0; i < fifo_depth; i++)
|
||||
fprintf (stderr, "Sigsuspend woke up by signal %d\n",
|
||||
sigfifo[i]);
|
||||
fifo_depth = 0;
|
||||
}
|
||||
|
||||
pthread_exit (arg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sighandler (int signo)
|
||||
{
|
||||
sigset_t set, suspend_set;
|
||||
pthread_t self;
|
||||
|
||||
if ((signo >= 0) && (signo <= NSIG))
|
||||
sigcounts[signo]++;
|
||||
|
||||
/*
|
||||
* If we are running on behalf of the suspender thread,
|
||||
* ensure that we have the correct mask set.
|
||||
*/
|
||||
self = pthread_self ();
|
||||
if (self == suspender_tid) {
|
||||
sigfifo[fifo_depth] = signo;
|
||||
fifo_depth++;
|
||||
fprintf (stderr,
|
||||
" -> Suspender thread signal handler caught signal %d\n",
|
||||
signo);
|
||||
|
||||
/* Get the current signal mask. */
|
||||
sigprocmask (SIG_SETMASK, NULL, &set);
|
||||
|
||||
/* The handler should run with the current signal masked. */
|
||||
suspend_set = suspender_mask;
|
||||
sigaddset(&suspend_set, signo);
|
||||
|
||||
if (memcmp(&set, &suspend_set, sizeof(set)))
|
||||
fprintf (stderr,
|
||||
" >>> FAIL: sigsuspender signal handler running "
|
||||
"with incorrect mask.\n");
|
||||
}
|
||||
else
|
||||
fprintf (stderr,
|
||||
" -> Main thread signal handler caught signal %d\n",
|
||||
signo);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
send_thread_signal (pthread_t tid, int signo)
|
||||
{
|
||||
if (pthread_kill (tid, signo) != 0) {
|
||||
fprintf (stderr, "Unable to send thread signal, errno %d.\n",
|
||||
errno);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
send_process_signal (int signo)
|
||||
{
|
||||
if (kill (getpid (), signo) != 0) {
|
||||
fprintf (stderr, "Unable to send process signal, errno %d.\n",
|
||||
errno);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
pthread_attr_t pattr;
|
||||
void * exit_status;
|
||||
struct sigaction act;
|
||||
sigset_t oldset;
|
||||
sigset_t newset;
|
||||
|
||||
/* Initialize our signal counts. */
|
||||
memset ((void *) sigcounts, 0, NSIG * sizeof (int));
|
||||
|
||||
/* Ignore signal SIGIO. */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGIO);
|
||||
act.sa_handler = SIG_IGN;
|
||||
act.sa_flags = 0;
|
||||
sigaction (SIGIO, &act, NULL);
|
||||
|
||||
/* Install a signal handler for SIGURG. */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGURG);
|
||||
act.sa_handler = sighandler;
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigaction (SIGURG, &act, NULL);
|
||||
|
||||
/* Install a signal handler for SIGXCPU */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGXCPU);
|
||||
sigaction (SIGXCPU, &act, NULL);
|
||||
|
||||
/* Get our current signal mask. */
|
||||
sigprocmask (SIG_SETMASK, NULL, &oldset);
|
||||
|
||||
/* Mask out SIGUSR1 and SIGUSR2. */
|
||||
newset = oldset;
|
||||
sigaddset (&newset, SIGUSR1);
|
||||
sigaddset (&newset, SIGUSR2);
|
||||
sigprocmask (SIG_SETMASK, &newset, NULL);
|
||||
|
||||
/* Install a signal handler for SIGUSR1 */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGUSR1);
|
||||
sigaction (SIGUSR1, &act, NULL);
|
||||
|
||||
/* Install a signal handler for SIGUSR2 */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGUSR2);
|
||||
sigaction (SIGUSR2, &act, NULL);
|
||||
|
||||
/*
|
||||
* Initialize the thread attribute.
|
||||
*/
|
||||
if ((pthread_attr_init (&pattr) != 0) ||
|
||||
(pthread_attr_setdetachstate (&pattr,
|
||||
PTHREAD_CREATE_JOINABLE) != 0)) {
|
||||
fprintf (stderr, "Unable to initialize thread attributes.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the sigsuspender thread.
|
||||
*/
|
||||
if (pthread_create (&suspender_tid, &pattr, sigsuspender, NULL) != 0) {
|
||||
fprintf (stderr, "Unable to create thread, errno %d.\n", errno);
|
||||
exit (1);
|
||||
}
|
||||
#if defined(_LIBC_R)
|
||||
pthread_set_name_np (suspender_tid, "sigsuspender");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Verify that an ignored signal doesn't cause a wakeup.
|
||||
* We don't have a handler installed for SIGIO.
|
||||
*/
|
||||
send_thread_signal (suspender_tid, SIGIO);
|
||||
sleep (1);
|
||||
send_process_signal (SIGIO);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGIO] != 0)
|
||||
fprintf (stderr, "FAIL: sigsuspend wakes up for ignored signal "
|
||||
"SIGIO.\n");
|
||||
|
||||
/*
|
||||
* Verify that a signal with a default action of ignore, for
|
||||
* which we have a signal handler installed, will release a
|
||||
* sigsuspend.
|
||||
*/
|
||||
send_thread_signal (suspender_tid, SIGURG);
|
||||
sleep (1);
|
||||
send_process_signal (SIGURG);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGURG] != 2)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigsuspend doesn't wake up for SIGURG.\n");
|
||||
|
||||
/*
|
||||
* Verify that a SIGUSR2 signal will release a sigsuspended
|
||||
* thread.
|
||||
*/
|
||||
send_thread_signal (suspender_tid, SIGUSR2);
|
||||
sleep (1);
|
||||
send_process_signal (SIGUSR2);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGUSR2] != 2)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigsuspend doesn't wake up for SIGUSR2.\n");
|
||||
|
||||
/*
|
||||
* Verify that a signal, blocked in both the main and
|
||||
* sigsuspender threads, does not cause the signal handler
|
||||
* to be called.
|
||||
*/
|
||||
send_thread_signal (suspender_tid, SIGUSR1);
|
||||
sleep (1);
|
||||
send_process_signal (SIGUSR1);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGUSR1] != 0)
|
||||
fprintf (stderr, "FAIL: signal hander called for SIGUSR1.\n");
|
||||
|
||||
/*
|
||||
* Verify that we can still kill the process for a signal
|
||||
* not being waited on by sigwait.
|
||||
*/
|
||||
send_process_signal (SIGPIPE);
|
||||
fprintf (stderr, "FAIL: SIGPIPE did not terminate process.\n");
|
||||
|
||||
/*
|
||||
* Wait for the thread to finish.
|
||||
*/
|
||||
pthread_join (suspender_tid, &exit_status);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
-> Suspender thread signal handler caught signal 16
|
||||
Sigsuspend woke up by signal 16
|
||||
-> Suspender thread signal handler caught signal 16
|
||||
Sigsuspend woke up by signal 16
|
||||
-> Suspender thread signal handler caught signal 31
|
||||
Sigsuspend woke up by signal 31
|
||||
-> Suspender thread signal handler caught signal 31
|
||||
Sigsuspend woke up by signal 31
|
||||
@@ -1,304 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998 Daniel M. Eischen <eischen@vigrid.com>
|
||||
* 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 Daniel M. Eischen.
|
||||
* 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 DANIEL M. EISCHEN 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$
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_LIBC_R_)
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
static int sigcounts[NSIG + 1];
|
||||
static sigset_t wait_mask;
|
||||
static pthread_mutex_t waiter_mutex;
|
||||
|
||||
|
||||
static void *
|
||||
sigwaiter (void *arg)
|
||||
{
|
||||
int signo;
|
||||
sigset_t mask;
|
||||
|
||||
/* Block SIGHUP */
|
||||
sigemptyset (&mask);
|
||||
sigaddset (&mask, SIGHUP);
|
||||
sigprocmask (SIG_BLOCK, &mask, NULL);
|
||||
|
||||
while (sigcounts[SIGINT] == 0) {
|
||||
if (sigwait (&wait_mask, &signo) != 0) {
|
||||
fprintf (stderr,
|
||||
"Unable to wait for signal, errno %d\n",
|
||||
errno);
|
||||
exit (1);
|
||||
}
|
||||
sigcounts[signo]++;
|
||||
fprintf (stderr, "Sigwait caught signal %d\n", signo);
|
||||
|
||||
/* Allow the main thread to prevent the sigwait. */
|
||||
pthread_mutex_lock (&waiter_mutex);
|
||||
pthread_mutex_unlock (&waiter_mutex);
|
||||
}
|
||||
|
||||
pthread_exit (arg);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sighandler (int signo)
|
||||
{
|
||||
fprintf (stderr, " -> Signal handler caught signal %d\n", signo);
|
||||
|
||||
if ((signo >= 0) && (signo <= NSIG))
|
||||
sigcounts[signo]++;
|
||||
}
|
||||
|
||||
static void
|
||||
send_thread_signal (pthread_t tid, int signo)
|
||||
{
|
||||
if (pthread_kill (tid, signo) != 0) {
|
||||
fprintf (stderr, "Unable to send thread signal, errno %d.\n",
|
||||
errno);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
send_process_signal (int signo)
|
||||
{
|
||||
if (kill (getpid (), signo) != 0) {
|
||||
fprintf (stderr, "Unable to send process signal, errno %d.\n",
|
||||
errno);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
pthread_mutexattr_t mattr;
|
||||
pthread_attr_t pattr;
|
||||
pthread_t tid;
|
||||
void * exit_status;
|
||||
struct sigaction act;
|
||||
|
||||
/* Initialize our signal counts. */
|
||||
memset ((void *) sigcounts, 0, NSIG * sizeof (int));
|
||||
|
||||
/* Setup our wait mask. */
|
||||
sigemptyset (&wait_mask); /* Default action */
|
||||
sigaddset (&wait_mask, SIGHUP); /* terminate */
|
||||
sigaddset (&wait_mask, SIGINT); /* terminate */
|
||||
sigaddset (&wait_mask, SIGQUIT); /* create core image */
|
||||
sigaddset (&wait_mask, SIGURG); /* ignore */
|
||||
sigaddset (&wait_mask, SIGIO); /* ignore */
|
||||
sigaddset (&wait_mask, SIGUSR1); /* terminate */
|
||||
|
||||
/* Ignore signals SIGHUP and SIGIO. */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGHUP);
|
||||
sigaddset (&act.sa_mask, SIGIO);
|
||||
act.sa_handler = SIG_IGN;
|
||||
act.sa_flags = 0;
|
||||
sigaction (SIGHUP, &act, NULL);
|
||||
sigaction (SIGIO, &act, NULL);
|
||||
|
||||
/* Install a signal handler for SIGURG */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGURG);
|
||||
act.sa_handler = sighandler;
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigaction (SIGURG, &act, NULL);
|
||||
|
||||
/* Install a signal handler for SIGXCPU */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGXCPU);
|
||||
sigaction (SIGXCPU, &act, NULL);
|
||||
|
||||
/*
|
||||
* Initialize the thread attribute.
|
||||
*/
|
||||
if ((pthread_attr_init (&pattr) != 0) ||
|
||||
(pthread_attr_setdetachstate (&pattr,
|
||||
PTHREAD_CREATE_JOINABLE) != 0)) {
|
||||
fprintf (stderr, "Unable to initialize thread attributes.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize and create a mutex.
|
||||
*/
|
||||
if ((pthread_mutexattr_init (&mattr) != 0) ||
|
||||
(pthread_mutex_init (&waiter_mutex, &mattr) != 0)) {
|
||||
fprintf (stderr, "Unable to create waiter mutex.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the sigwaiter thread.
|
||||
*/
|
||||
if (pthread_create (&tid, &pattr, sigwaiter, NULL) != 0) {
|
||||
fprintf (stderr, "Unable to create thread.\n");
|
||||
exit (1);
|
||||
}
|
||||
#if defined(_LIBC_R_)
|
||||
pthread_set_name_np (tid, "sigwaiter");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Verify that an ignored signal doesn't cause a wakeup.
|
||||
* We don't have a handler installed for SIGIO.
|
||||
*/
|
||||
send_thread_signal (tid, SIGIO);
|
||||
sleep (1);
|
||||
send_process_signal (SIGIO);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGIO] != 0)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigwait wakes up for ignored signal SIGIO.\n");
|
||||
|
||||
/*
|
||||
* Verify that a signal with a default action of ignore, for
|
||||
* which we have a signal handler installed, will release a sigwait.
|
||||
*/
|
||||
send_thread_signal (tid, SIGURG);
|
||||
sleep (1);
|
||||
send_process_signal (SIGURG);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGURG] != 2)
|
||||
fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGURG.\n");
|
||||
|
||||
/*
|
||||
* Verify that a signal with a default action that terminates
|
||||
* the process will release a sigwait.
|
||||
*/
|
||||
send_thread_signal (tid, SIGUSR1);
|
||||
sleep (1);
|
||||
send_process_signal (SIGUSR1);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGUSR1] != 2)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigwait doesn't wake up for SIGUSR1.\n");
|
||||
|
||||
/*
|
||||
* Verify that if we install a signal handler for a previously
|
||||
* ignored signal, an occurrence of this signal will release
|
||||
* the (already waiting) sigwait.
|
||||
*/
|
||||
|
||||
/* Install a signal handler for SIGHUP. */
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, SIGHUP);
|
||||
act.sa_handler = sighandler;
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigaction (SIGHUP, &act, NULL);
|
||||
|
||||
/* Sending SIGHUP should release the sigwait. */
|
||||
send_process_signal (SIGHUP);
|
||||
sleep (1);
|
||||
send_thread_signal (tid, SIGHUP);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGHUP] != 2)
|
||||
fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGHUP.\n");
|
||||
|
||||
/*
|
||||
* Verify that a pending signal in the waiters mask will
|
||||
* cause sigwait to return the pending signal. We do this
|
||||
* by taking the waiters mutex and signaling the waiter to
|
||||
* release him from the sigwait. The waiter will block
|
||||
* on taking the mutex, and we can then send the waiter a
|
||||
* signal which should be added to his pending signals.
|
||||
* The next time the waiter does a sigwait, he should
|
||||
* return with the pending signal.
|
||||
*/
|
||||
sigcounts[SIGHUP] = 0;
|
||||
pthread_mutex_lock (&waiter_mutex);
|
||||
/* Release the waiter from sigwait. */
|
||||
send_process_signal (SIGHUP);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGHUP] != 1)
|
||||
fprintf (stderr, "FAIL: sigwait doesn't wake up for SIGHUP.\n");
|
||||
/*
|
||||
* Add SIGHUP to the process pending signals. Since there is
|
||||
* a signal handler installed for SIGHUP and this signal is
|
||||
* blocked from the waiter thread and unblocked in the main
|
||||
* thread, the signal handler should be called once for SIGHUP.
|
||||
*/
|
||||
send_process_signal (SIGHUP);
|
||||
/* Release the waiter thread and allow him to run. */
|
||||
pthread_mutex_unlock (&waiter_mutex);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGHUP] != 2)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigwait doesn't return for pending SIGHUP.\n");
|
||||
|
||||
/*
|
||||
* Repeat the above test using pthread_kill and SIGUSR1.
|
||||
*/
|
||||
sigcounts[SIGUSR1] = 0;
|
||||
pthread_mutex_lock (&waiter_mutex);
|
||||
/* Release the waiter from sigwait. */
|
||||
send_thread_signal (tid, SIGUSR1);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGUSR1] != 1)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigwait doesn't wake up for SIGUSR1.\n");
|
||||
/* Add SIGUSR1 to the waiters pending signals. */
|
||||
send_thread_signal (tid, SIGUSR1);
|
||||
/* Release the waiter thread and allow him to run. */
|
||||
pthread_mutex_unlock (&waiter_mutex);
|
||||
sleep (1);
|
||||
if (sigcounts[SIGUSR1] != 2)
|
||||
fprintf (stderr,
|
||||
"FAIL: sigwait doesn't return for pending SIGUSR1.\n");
|
||||
|
||||
/*
|
||||
* Verify that we can still kill the process for a signal
|
||||
* not being waited on by sigwait.
|
||||
*/
|
||||
send_process_signal (SIGPIPE);
|
||||
fprintf (stderr, "FAIL: SIGPIPE did not terminate process.\n");
|
||||
|
||||
/*
|
||||
* Wait for the thread to finish.
|
||||
*/
|
||||
pthread_join (tid, &exit_status);
|
||||
|
||||
return (0);
|
||||
}
|
||||
Loaded 100 of 709 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user