IFC @ r242940
This commit is contained in:
commit
7d3d462b09
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/bhyve/; revision=242954
@ -1138,7 +1138,7 @@ _aicasm= sys/modules/aic7xxx/aicasm
|
||||
_share= share/syscons/scrnmaps
|
||||
.endif
|
||||
|
||||
.if ${MK_GCC} != "no" && ${MK_CLANG_IS_CC} == "no"
|
||||
.if ${MK_GCC} != "no" && (${MK_CLANG_IS_CC} == "no" || ${TARGET} == "pc98")
|
||||
_gcc_tools= gnu/usr.bin/cc/cc_tools
|
||||
.endif
|
||||
|
||||
@ -1200,7 +1200,7 @@ _clang= usr.bin/clang
|
||||
_clang_libs= lib/clang
|
||||
.endif
|
||||
|
||||
.if ${MK_GCC} != "no" && ${MK_CLANG_IS_CC} == "no"
|
||||
.if ${MK_GCC} != "no" && (${MK_CLANG_IS_CC} == "no" || ${TARGET} == "pc98")
|
||||
_cc= gnu/usr.bin/cc
|
||||
.endif
|
||||
|
||||
|
20
bin/ls/cmp.c
20
bin/ls/cmp.c
@ -78,7 +78,10 @@ modcmp(const FTSENT *a, const FTSENT *b)
|
||||
if (b->fts_statp->st_mtim.tv_nsec <
|
||||
a->fts_statp->st_mtim.tv_nsec)
|
||||
return (-1);
|
||||
return (strcoll(a->fts_name, b->fts_name));
|
||||
if (f_samesort)
|
||||
return (strcoll(b->fts_name, a->fts_name));
|
||||
else
|
||||
return (strcoll(a->fts_name, b->fts_name));
|
||||
}
|
||||
|
||||
int
|
||||
@ -104,7 +107,10 @@ acccmp(const FTSENT *a, const FTSENT *b)
|
||||
if (b->fts_statp->st_atim.tv_nsec <
|
||||
a->fts_statp->st_atim.tv_nsec)
|
||||
return (-1);
|
||||
return (strcoll(a->fts_name, b->fts_name));
|
||||
if (f_samesort)
|
||||
return (strcoll(b->fts_name, a->fts_name));
|
||||
else
|
||||
return (strcoll(a->fts_name, b->fts_name));
|
||||
}
|
||||
|
||||
int
|
||||
@ -130,7 +136,10 @@ birthcmp(const FTSENT *a, const FTSENT *b)
|
||||
if (b->fts_statp->st_birthtim.tv_nsec <
|
||||
a->fts_statp->st_birthtim.tv_nsec)
|
||||
return (-1);
|
||||
return (strcoll(a->fts_name, b->fts_name));
|
||||
if (f_samesort)
|
||||
return (strcoll(b->fts_name, a->fts_name));
|
||||
else
|
||||
return (strcoll(a->fts_name, b->fts_name));
|
||||
}
|
||||
|
||||
int
|
||||
@ -156,7 +165,10 @@ statcmp(const FTSENT *a, const FTSENT *b)
|
||||
if (b->fts_statp->st_ctim.tv_nsec <
|
||||
a->fts_statp->st_ctim.tv_nsec)
|
||||
return (-1);
|
||||
return (strcoll(a->fts_name, b->fts_name));
|
||||
if (f_samesort)
|
||||
return (strcoll(b->fts_name, a->fts_name));
|
||||
else
|
||||
return (strcoll(a->fts_name, b->fts_name));
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -55,12 +55,12 @@ int prn_octal(const char *);
|
||||
int prn_printable(const char *);
|
||||
#ifdef COLORLS
|
||||
void parsecolors(const char *cs);
|
||||
void colorquit(int);
|
||||
void colorquit(int);
|
||||
|
||||
extern char *ansi_fgcol;
|
||||
extern char *ansi_bgcol;
|
||||
extern char *ansi_coloff;
|
||||
extern char *attrs_off;
|
||||
extern char *enter_bold;
|
||||
extern char *ansi_fgcol;
|
||||
extern char *ansi_bgcol;
|
||||
extern char *ansi_coloff;
|
||||
extern char *attrs_off;
|
||||
extern char *enter_bold;
|
||||
#endif
|
||||
extern int termwidth;
|
||||
|
72
bin/ls/ls.1
72
bin/ls/ls.1
@ -32,7 +32,7 @@
|
||||
.\" @(#)ls.1 8.7 (Berkeley) 7/29/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 28, 2011
|
||||
.Dd November 8, 2012
|
||||
.Dt LS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -40,7 +40,7 @@
|
||||
.Nd list directory contents
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwx1
|
||||
.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,
|
||||
.Op Fl D Ar format
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
@ -130,6 +130,8 @@ This option is equivalent to defining
|
||||
.Ev CLICOLOR
|
||||
in the environment.
|
||||
(See below.)
|
||||
This functionality can be compiled out by removing the definition of
|
||||
.Ev COLORLS .
|
||||
.It Fl H
|
||||
Symbolic links on the command line are followed.
|
||||
This option is assumed if
|
||||
@ -249,12 +251,35 @@ subsection below, except (if the long format is not also requested)
|
||||
the directory totals are not output when the output is in a
|
||||
single column, even if multi-column output is requested.
|
||||
.It Fl t
|
||||
Sort by time modified (most recently modified
|
||||
first) before sorting the operands in lexicographical
|
||||
order.
|
||||
Sort by descending time modified (most recently modified first). If two files
|
||||
have the same modification timestamp, sort their names in ascending
|
||||
lexicographical order.
|
||||
The
|
||||
.Fl r
|
||||
option reverses both of these sort orders.
|
||||
.Pp
|
||||
Note that these sort orders are contradictory: the time sequence is in
|
||||
descending order, the lexicographical sort is in ascending order.
|
||||
This behavior is mandated by
|
||||
.St -p1003.2 .
|
||||
This feature can cause problems listing files stored with sequential names on
|
||||
FAT file systems, such as from digital cameras, where it is possible to have
|
||||
more than one image with the same timestamp.
|
||||
In such a case, the photos cannot be listed in the sequence in which
|
||||
they were taken.
|
||||
To ensure the same sort order for time and for lexicographical sorting, set the
|
||||
environment variable
|
||||
.Ev LS_SAMESORT
|
||||
or use the
|
||||
.Fl y
|
||||
option.
|
||||
This causes
|
||||
.Nm
|
||||
to reverse the lexicographal sort order when sorting files with the
|
||||
same modification timestamp.
|
||||
.It Fl u
|
||||
Use time of last access,
|
||||
instead of last modification
|
||||
instead of time of last modification
|
||||
of the file for sorting
|
||||
.Pq Fl t
|
||||
or printing
|
||||
@ -268,6 +293,15 @@ The same as
|
||||
.Fl C ,
|
||||
except that the multi-column output is produced with entries sorted
|
||||
across, rather than down, the columns.
|
||||
.It Fl y
|
||||
When the
|
||||
.Fl t
|
||||
option is set, sort the alphabetical output in the same order as the time output.
|
||||
This has the same effect as setting
|
||||
.Ev LS_SAMESORT .
|
||||
See the description of the
|
||||
.Fl t
|
||||
option for more details.
|
||||
.It Fl 1
|
||||
(The numeric digit
|
||||
.Dq one . )
|
||||
@ -275,6 +309,15 @@ Force output to be
|
||||
one entry per line.
|
||||
This is the default when
|
||||
output is not to a terminal.
|
||||
.It Fl ,
|
||||
(Comma) When the
|
||||
.Fl l
|
||||
option is set, print file sizes grouped and separated by thousands using the
|
||||
non-monetary separator returned by
|
||||
.Xr localeconv 3 ,
|
||||
typically a comma or period.
|
||||
If no locale is set, or the locale does not have a non-monetary separator, this
|
||||
option has no effect.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
@ -529,7 +572,7 @@ variable is defined.
|
||||
.It Ev CLICOLOR_FORCE
|
||||
Color sequences are normally disabled if the output is not directed to
|
||||
a terminal.
|
||||
This can be overridden by setting this flag.
|
||||
This can be overridden by setting this variable.
|
||||
The
|
||||
.Ev TERM
|
||||
variable still needs to reference a color capable terminal however
|
||||
@ -655,6 +698,14 @@ Not all columns have changeable widths.
|
||||
The fields are,
|
||||
in order: inode, block count, number of links, user name,
|
||||
group name, flags, file size, file name.
|
||||
.It Ev LS_SAMESORT
|
||||
If this variable is set, the
|
||||
.Fl t
|
||||
option sorts the names of files with the same modification timestamp in the same
|
||||
sense as the time sort.
|
||||
See the description of the
|
||||
.Fl t
|
||||
option for more details.
|
||||
.It Ev TERM
|
||||
The
|
||||
.Ev CLICOLOR
|
||||
@ -678,6 +729,7 @@ specification.
|
||||
.Xr getfacl 1 ,
|
||||
.Xr sort 1 ,
|
||||
.Xr xterm 1 ,
|
||||
.Xr localeconv 3 ,
|
||||
.Xr strftime 3 ,
|
||||
.Xr strmode 3 ,
|
||||
.Xr termcap 5 ,
|
||||
@ -716,3 +768,9 @@ option description might be a feature that was
|
||||
based on the fact that single-column output
|
||||
usually goes to something other than a terminal.
|
||||
It is debatable whether this is a design bug.
|
||||
.Pp
|
||||
.St -p1003.2
|
||||
mandates opposite sort orders for files with the same timestamp when
|
||||
sorting with the
|
||||
.Fl t
|
||||
option.
|
||||
|
106
bin/ls/ls.c
106
bin/ls/ls.c
@ -109,10 +109,11 @@ int termwidth = 80; /* default terminal width */
|
||||
int f_humanval; /* show human-readable file sizes */
|
||||
int f_inode; /* print inode */
|
||||
static int f_kblocks; /* print size in kilobytes */
|
||||
int f_label; /* show MAC label */
|
||||
static int f_listdir; /* list actual directory, not contents */
|
||||
static int f_listdot; /* list files beginning with . */
|
||||
static int f_noautodot; /* do not automatically enable -A for root */
|
||||
int f_longform; /* long listing format */
|
||||
static int f_noautodot; /* do not automatically enable -A for root */
|
||||
static int f_nofollow; /* don't follow symbolic link arguments */
|
||||
int f_nonprint; /* show unprintables as ? */
|
||||
static int f_nosort; /* don't sort output */
|
||||
@ -122,19 +123,21 @@ static int f_numericonly; /* don't convert uid/gid to name */
|
||||
int f_octal_escape; /* like f_octal but use C escapes if possible */
|
||||
static int f_recursive; /* ls subdirectories also */
|
||||
static int f_reversesort; /* reverse whatever sort is used */
|
||||
int f_sectime; /* print the real time for all files */
|
||||
int f_samesort; /* sort time and name in same direction */
|
||||
int f_sectime; /* print full time information */
|
||||
static int f_singlecol; /* use single column output */
|
||||
int f_size; /* list size in short listing */
|
||||
static int f_sizesort;
|
||||
int f_slash; /* similar to f_type, but only for dirs */
|
||||
int f_sortacross; /* sort across rows, not down columns */
|
||||
int f_statustime; /* use time of last mode change */
|
||||
static int f_stream; /* stream the output, separate with commas */
|
||||
int f_thousands; /* show file sizes with thousands separators */
|
||||
char *f_timeformat; /* user-specified time format */
|
||||
static int f_timesort; /* sort by time vice name */
|
||||
char *f_timeformat; /* user-specified time format */
|
||||
static int f_sizesort;
|
||||
int f_type; /* add type character for non-regular files */
|
||||
static int f_whiteout; /* show whiteout entries */
|
||||
int f_label; /* show MAC label */
|
||||
|
||||
#ifdef COLORLS
|
||||
int f_color; /* add type in color for non-regular files */
|
||||
|
||||
@ -180,8 +183,10 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
fts_options = FTS_PHYSICAL;
|
||||
while ((ch = getopt(argc, argv,
|
||||
"1ABCD:FGHILPRSTUWZabcdfghiklmnopqrstuwx")) != -1) {
|
||||
if (getenv("LS_SAMESORT"))
|
||||
f_samesort = 1;
|
||||
while ((ch = getopt(argc, argv,
|
||||
"1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
|
||||
switch (ch) {
|
||||
/*
|
||||
* The -1, -C, -x and -l options all override each other so
|
||||
@ -192,17 +197,9 @@ main(int argc, char *argv[])
|
||||
f_longform = 0;
|
||||
f_stream = 0;
|
||||
break;
|
||||
case 'B':
|
||||
f_nonprint = 0;
|
||||
f_octal = 1;
|
||||
f_octal_escape = 0;
|
||||
break;
|
||||
case 'C':
|
||||
f_sortacross = f_longform = f_singlecol = 0;
|
||||
break;
|
||||
case 'D':
|
||||
f_timeformat = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
f_longform = 1;
|
||||
f_singlecol = 0;
|
||||
@ -229,16 +226,46 @@ main(int argc, char *argv[])
|
||||
f_accesstime = 0;
|
||||
f_statustime = 0;
|
||||
break;
|
||||
case 'a':
|
||||
fts_options |= FTS_SEEDOT;
|
||||
/* FALLTHROUGH */
|
||||
case 'A':
|
||||
f_listdot = 1;
|
||||
break;
|
||||
/* The -t and -S options override each other. */
|
||||
case 'S':
|
||||
f_sizesort = 1;
|
||||
f_timesort = 0;
|
||||
break;
|
||||
case 't':
|
||||
f_timesort = 1;
|
||||
f_sizesort = 0;
|
||||
break;
|
||||
/* Other flags. Please keep alphabetic. */
|
||||
case ',':
|
||||
f_thousands = 1;
|
||||
break;
|
||||
case 'B':
|
||||
f_nonprint = 0;
|
||||
f_octal = 1;
|
||||
f_octal_escape = 0;
|
||||
break;
|
||||
case 'D':
|
||||
f_timeformat = optarg;
|
||||
break;
|
||||
case 'F':
|
||||
f_type = 1;
|
||||
f_slash = 0;
|
||||
break;
|
||||
case 'G':
|
||||
setenv("CLICOLOR", "", 1);
|
||||
break;
|
||||
case 'H':
|
||||
fts_options |= FTS_COMFOLLOW;
|
||||
f_nofollow = 0;
|
||||
break;
|
||||
case 'G':
|
||||
setenv("CLICOLOR", "", 1);
|
||||
case 'I':
|
||||
f_noautodot = 1;
|
||||
break;
|
||||
case 'L':
|
||||
fts_options &= ~FTS_PHYSICAL;
|
||||
@ -254,14 +281,19 @@ main(int argc, char *argv[])
|
||||
case 'R':
|
||||
f_recursive = 1;
|
||||
break;
|
||||
case 'a':
|
||||
fts_options |= FTS_SEEDOT;
|
||||
/* FALLTHROUGH */
|
||||
case 'A':
|
||||
f_listdot = 1;
|
||||
case 'T':
|
||||
f_sectime = 1;
|
||||
break;
|
||||
case 'I':
|
||||
f_noautodot = 1;
|
||||
case 'W':
|
||||
f_whiteout = 1;
|
||||
break;
|
||||
case 'Z':
|
||||
f_label = 1;
|
||||
break;
|
||||
case 'b':
|
||||
f_nonprint = 0;
|
||||
f_octal = 0;
|
||||
f_octal_escape = 1;
|
||||
break;
|
||||
/* The -d option turns off the -R option. */
|
||||
case 'd':
|
||||
@ -309,33 +341,13 @@ main(int argc, char *argv[])
|
||||
case 's':
|
||||
f_size = 1;
|
||||
break;
|
||||
case 'T':
|
||||
f_sectime = 1;
|
||||
break;
|
||||
/* The -t and -S options override each other. */
|
||||
case 't':
|
||||
f_timesort = 1;
|
||||
f_sizesort = 0;
|
||||
break;
|
||||
case 'S':
|
||||
f_sizesort = 1;
|
||||
f_timesort = 0;
|
||||
break;
|
||||
case 'W':
|
||||
f_whiteout = 1;
|
||||
break;
|
||||
case 'b':
|
||||
f_nonprint = 0;
|
||||
f_octal = 0;
|
||||
f_octal_escape = 1;
|
||||
break;
|
||||
case 'w':
|
||||
f_nonprint = 0;
|
||||
f_octal = 0;
|
||||
f_octal_escape = 0;
|
||||
break;
|
||||
case 'Z':
|
||||
f_label = 1;
|
||||
case 'y':
|
||||
f_samesort = 1;
|
||||
break;
|
||||
default:
|
||||
case '?':
|
||||
@ -849,6 +861,8 @@ display(const FTSENT *p, FTSENT *list, int options)
|
||||
d.s_size = sizelen;
|
||||
d.s_user = maxuser;
|
||||
}
|
||||
if (f_thousands) /* make space for commas */
|
||||
d.s_size += (d.s_size - 1) / 3;
|
||||
printfcn(&d);
|
||||
output = 1;
|
||||
|
||||
|
@ -49,12 +49,14 @@ extern int f_longform; /* long listing format */
|
||||
extern int f_octal; /* print unprintables in octal */
|
||||
extern int f_octal_escape; /* like f_octal but use C escapes if possible */
|
||||
extern int f_nonprint; /* show unprintables as ? */
|
||||
extern int f_samesort; /* sort time and name in same direction */
|
||||
extern int f_sectime; /* print the real time for all files */
|
||||
extern int f_size; /* list size in short listing */
|
||||
extern int f_slash; /* append a '/' if the file is a directory */
|
||||
extern int f_sortacross; /* sort across rows, not down columns */
|
||||
extern int f_statustime; /* use time of last mode change */
|
||||
extern char *f_timeformat; /* user-specified time format */
|
||||
extern int f_thousands; /* show file sizes with thousands separators */
|
||||
extern char *f_timeformat; /* user-specified time format */
|
||||
extern int f_notabs; /* don't use tab-separated multi-col output */
|
||||
extern int f_type; /* add type character for non-regular files */
|
||||
#ifdef COLORLS
|
||||
|
@ -606,6 +606,10 @@ printsize(size_t width, off_t bytes)
|
||||
humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
|
||||
HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
|
||||
(void)printf("%*s ", (u_int)width, buf);
|
||||
} else if (f_thousands) { /* with commas */
|
||||
/* This format assignment needed to work round gcc bug. */
|
||||
const char *format = "%*j'd ";
|
||||
(void)printf(format, (u_int)width, bytes);
|
||||
} else
|
||||
(void)printf("%*jd ", (u_int)width, bytes);
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ prn_printable(const char *s)
|
||||
* to fix this as an efficient fix would involve a lookup table. Same goes
|
||||
* for the rather inelegant code in prn_octal.
|
||||
*
|
||||
* DES 1998/04/23
|
||||
* DES 1998/04/23
|
||||
*/
|
||||
|
||||
size_t
|
||||
@ -175,7 +175,7 @@ prn_octal(const char *s)
|
||||
size_t clen;
|
||||
unsigned char ch;
|
||||
int goodchar, i, len, prtlen;
|
||||
|
||||
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
len = 0;
|
||||
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
|
||||
@ -200,9 +200,9 @@ prn_octal(const char *s)
|
||||
for (i = 0; i < prtlen; i++) {
|
||||
ch = (unsigned char)s[i];
|
||||
putchar('\\');
|
||||
putchar('0' + (ch >> 6));
|
||||
putchar('0' + ((ch >> 3) & 7));
|
||||
putchar('0' + (ch & 7));
|
||||
putchar('0' + (ch >> 6));
|
||||
putchar('0' + ((ch >> 3) & 7));
|
||||
putchar('0' + (ch & 7));
|
||||
len += 4;
|
||||
}
|
||||
}
|
||||
@ -222,9 +222,9 @@ usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
#ifdef COLORLS
|
||||
"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwx1] [-D format]"
|
||||
"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
|
||||
#else
|
||||
"usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuwx1] [-D format]"
|
||||
"usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
|
||||
#endif
|
||||
" [file ...]\n");
|
||||
exit(1);
|
||||
|
@ -68,7 +68,18 @@ setalias(const char *name, const char *val)
|
||||
if (equal(name, ap->name)) {
|
||||
INTOFF;
|
||||
ckfree(ap->val);
|
||||
/* See HACK below. */
|
||||
#ifdef notyet
|
||||
ap->val = savestr(val);
|
||||
#else
|
||||
{
|
||||
size_t len = strlen(val);
|
||||
ap->val = ckmalloc(len + 2);
|
||||
memcpy(ap->val, val, len);
|
||||
ap->val[len] = ' ';
|
||||
ap->val[len+1] = '\0';
|
||||
}
|
||||
#endif
|
||||
INTON;
|
||||
return;
|
||||
}
|
||||
|
@ -350,7 +350,7 @@ pungetc(void)
|
||||
* We handle aliases this way.
|
||||
*/
|
||||
void
|
||||
pushstring(char *s, int len, void *ap)
|
||||
pushstring(char *s, int len, struct alias *ap)
|
||||
{
|
||||
struct strpush *sp;
|
||||
|
||||
@ -365,9 +365,9 @@ pushstring(char *s, int len, void *ap)
|
||||
sp->prevstring = parsenextc;
|
||||
sp->prevnleft = parsenleft;
|
||||
sp->prevlleft = parselleft;
|
||||
sp->ap = (struct alias *)ap;
|
||||
sp->ap = ap;
|
||||
if (ap)
|
||||
((struct alias *)ap)->flag |= ALIASINUSE;
|
||||
ap->flag |= ALIASINUSE;
|
||||
parsenextc = s;
|
||||
parsenleft = len;
|
||||
INTON;
|
||||
|
@ -45,6 +45,7 @@ extern int parsenleft; /* number of characters left in input buffer */
|
||||
extern char *parsenextc; /* next character in input buffer */
|
||||
extern int init_editline; /* 0 == not setup, 1 == OK, -1 == failed */
|
||||
|
||||
struct alias;
|
||||
struct parsefile;
|
||||
|
||||
char *pfgets(char *, int);
|
||||
@ -52,7 +53,7 @@ int pgetc(void);
|
||||
int preadbuffer(void);
|
||||
int preadateof(void);
|
||||
void pungetc(void);
|
||||
void pushstring(char *, int, void *);
|
||||
void pushstring(char *, int, struct alias *);
|
||||
void setinputfile(const char *, int);
|
||||
void setinputfd(int, int);
|
||||
void setinputstring(char *, int);
|
||||
|
@ -121,8 +121,8 @@
|
||||
#include <sys/fs/zfs.h>
|
||||
#include <libnvpair.h>
|
||||
|
||||
#define ZTEST_FD_DATA 3
|
||||
#define ZTEST_FD_RAND 4
|
||||
static int ztest_fd_data = -1;
|
||||
static int ztest_fd_rand = -1;
|
||||
|
||||
typedef struct ztest_shared_hdr {
|
||||
uint64_t zh_hdr_size;
|
||||
@ -710,14 +710,17 @@ process_options(int argc, char **argv)
|
||||
UINT64_MAX >> 2);
|
||||
|
||||
if (strlen(altdir) > 0) {
|
||||
char cmd[MAXNAMELEN];
|
||||
char realaltdir[MAXNAMELEN];
|
||||
char *cmd;
|
||||
char *realaltdir;
|
||||
char *bin;
|
||||
char *ztest;
|
||||
char *isa;
|
||||
int isalen;
|
||||
|
||||
(void) realpath(getexecname(), cmd);
|
||||
cmd = umem_alloc(MAXPATHLEN, UMEM_NOFAIL);
|
||||
realaltdir = umem_alloc(MAXPATHLEN, UMEM_NOFAIL);
|
||||
|
||||
VERIFY(NULL != realpath(getexecname(), cmd));
|
||||
if (0 != access(altdir, F_OK)) {
|
||||
ztest_dump_core = B_FALSE;
|
||||
fatal(B_TRUE, "invalid alternate ztest path: %s",
|
||||
@ -748,6 +751,9 @@ process_options(int argc, char **argv)
|
||||
fatal(B_TRUE, "invalid alternate lib directory %s",
|
||||
zo->zo_alt_libpath);
|
||||
}
|
||||
|
||||
umem_free(cmd, MAXPATHLEN);
|
||||
umem_free(realaltdir, MAXPATHLEN);
|
||||
}
|
||||
}
|
||||
|
||||
@ -764,10 +770,12 @@ ztest_random(uint64_t range)
|
||||
{
|
||||
uint64_t r;
|
||||
|
||||
ASSERT3S(ztest_fd_rand, >=, 0);
|
||||
|
||||
if (range == 0)
|
||||
return (0);
|
||||
|
||||
if (read(ZTEST_FD_RAND, &r, sizeof (r)) != sizeof (r))
|
||||
if (read(ztest_fd_rand, &r, sizeof (r)) != sizeof (r))
|
||||
fatal(1, "short read from /dev/urandom");
|
||||
|
||||
return (r % range);
|
||||
@ -4703,7 +4711,18 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id)
|
||||
if (islog)
|
||||
(void) rw_unlock(&ztest_name_lock);
|
||||
} else {
|
||||
/*
|
||||
* Ideally we would like to be able to randomly
|
||||
* call vdev_[on|off]line without holding locks
|
||||
* to force unpredictable failures but the side
|
||||
* effects of vdev_[on|off]line prevent us from
|
||||
* doing so. We grab the ztest_vdev_lock here to
|
||||
* prevent a race between injection testing and
|
||||
* aux_vdev removal.
|
||||
*/
|
||||
VERIFY(mutex_lock(&ztest_vdev_lock) == 0);
|
||||
(void) vdev_online(spa, guid0, 0, NULL);
|
||||
VERIFY(mutex_unlock(&ztest_vdev_lock) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5660,29 +5679,16 @@ ztest_init(ztest_shared_t *zs)
|
||||
}
|
||||
|
||||
static void
|
||||
setup_fds(void)
|
||||
setup_data_fd(void)
|
||||
{
|
||||
int fd;
|
||||
#ifdef illumos
|
||||
static char ztest_name_data[] = "/tmp/ztest.data.XXXXXX";
|
||||
|
||||
char *tmp = tempnam(NULL, NULL);
|
||||
fd = open(tmp, O_RDWR | O_CREAT, 0700);
|
||||
ASSERT3U(fd, ==, ZTEST_FD_DATA);
|
||||
(void) unlink(tmp);
|
||||
free(tmp);
|
||||
#else
|
||||
char tmp[MAXPATHLEN];
|
||||
|
||||
strlcpy(tmp, ztest_opts.zo_dir, MAXPATHLEN);
|
||||
strlcat(tmp, "/ztest.XXXXXX", MAXPATHLEN);
|
||||
fd = mkstemp(tmp);
|
||||
ASSERT3U(fd, ==, ZTEST_FD_DATA);
|
||||
#endif
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
ASSERT3U(fd, ==, ZTEST_FD_RAND);
|
||||
ztest_fd_data = mkstemp(ztest_name_data);
|
||||
ASSERT3S(ztest_fd_data, >=, 0);
|
||||
(void) unlink(ztest_name_data);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
shared_data_size(ztest_shared_hdr_t *hdr)
|
||||
{
|
||||
@ -5703,15 +5709,11 @@ setup_hdr(void)
|
||||
int size;
|
||||
ztest_shared_hdr_t *hdr;
|
||||
|
||||
#ifndef illumos
|
||||
pwrite(ZTEST_FD_DATA, "", 1, 0);
|
||||
#endif
|
||||
|
||||
hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, ZTEST_FD_DATA, 0);
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, ztest_fd_data, 0);
|
||||
ASSERT(hdr != MAP_FAILED);
|
||||
|
||||
VERIFY3U(0, ==, ftruncate(ZTEST_FD_DATA, sizeof (ztest_shared_hdr_t)));
|
||||
VERIFY3U(0, ==, ftruncate(ztest_fd_data, sizeof (ztest_shared_hdr_t)));
|
||||
|
||||
hdr->zh_hdr_size = sizeof (ztest_shared_hdr_t);
|
||||
hdr->zh_opts_size = sizeof (ztest_shared_opts_t);
|
||||
@ -5722,7 +5724,7 @@ setup_hdr(void)
|
||||
hdr->zh_ds_count = ztest_opts.zo_datasets;
|
||||
|
||||
size = shared_data_size(hdr);
|
||||
VERIFY3U(0, ==, ftruncate(ZTEST_FD_DATA, size));
|
||||
VERIFY3U(0, ==, ftruncate(ztest_fd_data, size));
|
||||
|
||||
(void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
|
||||
}
|
||||
@ -5735,14 +5737,14 @@ setup_data(void)
|
||||
uint8_t *buf;
|
||||
|
||||
hdr = (void *)mmap(0, P2ROUNDUP(sizeof (*hdr), getpagesize()),
|
||||
PROT_READ, MAP_SHARED, ZTEST_FD_DATA, 0);
|
||||
PROT_READ, MAP_SHARED, ztest_fd_data, 0);
|
||||
ASSERT(hdr != MAP_FAILED);
|
||||
|
||||
size = shared_data_size(hdr);
|
||||
|
||||
(void) munmap((caddr_t)hdr, P2ROUNDUP(sizeof (*hdr), getpagesize()));
|
||||
hdr = ztest_shared_hdr = (void *)mmap(0, P2ROUNDUP(size, getpagesize()),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, ZTEST_FD_DATA, 0);
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED, ztest_fd_data, 0);
|
||||
ASSERT(hdr != MAP_FAILED);
|
||||
buf = (uint8_t *)hdr;
|
||||
|
||||
@ -5761,12 +5763,13 @@ exec_child(char *cmd, char *libpath, boolean_t ignorekill, int *statusp)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
char cmdbuf[MAXPATHLEN];
|
||||
char *cmdbuf = NULL;
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (cmd == NULL) {
|
||||
(void) strlcpy(cmdbuf, getexecname(), sizeof (cmdbuf));
|
||||
cmdbuf = umem_alloc(MAXPATHLEN, UMEM_NOFAIL);
|
||||
(void) strlcpy(cmdbuf, getexecname(), MAXPATHLEN);
|
||||
cmd = cmdbuf;
|
||||
}
|
||||
|
||||
@ -5775,9 +5778,16 @@ exec_child(char *cmd, char *libpath, boolean_t ignorekill, int *statusp)
|
||||
|
||||
if (pid == 0) { /* child */
|
||||
char *emptyargv[2] = { cmd, NULL };
|
||||
char fd_data_str[12];
|
||||
|
||||
struct rlimit rl = { 1024, 1024 };
|
||||
(void) setrlimit(RLIMIT_NOFILE, &rl);
|
||||
|
||||
(void) close(ztest_fd_rand);
|
||||
VERIFY3U(11, >=,
|
||||
snprintf(fd_data_str, 12, "%d", ztest_fd_data));
|
||||
VERIFY0(setenv("ZTEST_FD_DATA", fd_data_str, 1));
|
||||
|
||||
(void) enable_extended_FILE_stdio(-1, -1);
|
||||
if (libpath != NULL)
|
||||
VERIFY(0 == setenv("LD_LIBRARY_PATH", libpath, 1));
|
||||
@ -5790,6 +5800,11 @@ exec_child(char *cmd, char *libpath, boolean_t ignorekill, int *statusp)
|
||||
fatal(B_TRUE, "exec failed: %s", cmd);
|
||||
}
|
||||
|
||||
if (cmdbuf != NULL) {
|
||||
umem_free(cmdbuf, MAXPATHLEN);
|
||||
cmd = NULL;
|
||||
}
|
||||
|
||||
while (waitpid(pid, &status, 0) != pid)
|
||||
continue;
|
||||
if (statusp != NULL)
|
||||
@ -5854,39 +5869,41 @@ main(int argc, char **argv)
|
||||
char timebuf[100];
|
||||
char numbuf[6];
|
||||
spa_t *spa;
|
||||
char cmd[MAXNAMELEN];
|
||||
char *cmd;
|
||||
boolean_t hasalt;
|
||||
|
||||
boolean_t ischild = (0 == lseek(ZTEST_FD_DATA, 0, SEEK_CUR));
|
||||
ASSERT(ischild || errno == EBADF);
|
||||
char *fd_data_str = getenv("ZTEST_FD_DATA");
|
||||
|
||||
(void) setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
dprintf_setup(&argc, argv);
|
||||
|
||||
if (!ischild) {
|
||||
ztest_fd_rand = open("/dev/urandom", O_RDONLY);
|
||||
ASSERT3S(ztest_fd_rand, >=, 0);
|
||||
|
||||
if (!fd_data_str) {
|
||||
process_options(argc, argv);
|
||||
|
||||
setup_fds();
|
||||
setup_data_fd();
|
||||
setup_hdr();
|
||||
setup_data();
|
||||
bcopy(&ztest_opts, ztest_shared_opts,
|
||||
sizeof (*ztest_shared_opts));
|
||||
} else {
|
||||
ztest_fd_data = atoi(fd_data_str);
|
||||
setup_data();
|
||||
bcopy(ztest_shared_opts, &ztest_opts, sizeof (ztest_opts));
|
||||
}
|
||||
ASSERT3U(ztest_opts.zo_datasets, ==, ztest_shared_hdr->zh_ds_count);
|
||||
|
||||
/* Override location of zpool.cache */
|
||||
(void) asprintf((char **)&spa_config_path, "%s/zpool.cache",
|
||||
ztest_opts.zo_dir);
|
||||
VERIFY3U(asprintf((char **)&spa_config_path, "%s/zpool.cache",
|
||||
ztest_opts.zo_dir), !=, -1);
|
||||
|
||||
ztest_ds = umem_alloc(ztest_opts.zo_datasets * sizeof (ztest_ds_t),
|
||||
UMEM_NOFAIL);
|
||||
zs = ztest_shared;
|
||||
|
||||
if (ischild) {
|
||||
if (fd_data_str) {
|
||||
metaslab_gang_bang = ztest_opts.zo_metaslab_gang_bang;
|
||||
metaslab_df_alloc_threshold =
|
||||
zs->zs_metaslab_df_alloc_threshold;
|
||||
@ -5909,7 +5926,8 @@ main(int argc, char **argv)
|
||||
(u_longlong_t)ztest_opts.zo_time);
|
||||
}
|
||||
|
||||
(void) strlcpy(cmd, getexecname(), sizeof (cmd));
|
||||
cmd = umem_alloc(MAXNAMELEN, UMEM_NOFAIL);
|
||||
(void) strlcpy(cmd, getexecname(), MAXNAMELEN);
|
||||
|
||||
zs->zs_do_init = B_TRUE;
|
||||
if (strlen(ztest_opts.zo_alt_ztest) != 0) {
|
||||
@ -6050,5 +6068,7 @@ main(int argc, char **argv)
|
||||
kills, iters - kills, (100.0 * kills) / MAX(1, iters));
|
||||
}
|
||||
|
||||
umem_free(cmd, MAXNAMELEN);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
75
cddl/contrib/opensolaris/lib/libdtrace/powerpc/dt_isadep.c
Normal file
75
cddl/contrib/opensolaris/lib/libdtrace/powerpc/dt_isadep.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* CDDL HEADER START
|
||||
*
|
||||
* The contents of this file are subject to the terms of the
|
||||
* Common Development and Distribution License, Version 1.0 only
|
||||
* (the "License"). You may not use this file except in compliance
|
||||
* with the License.
|
||||
*
|
||||
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
||||
* or http://www.opensolaris.org/os/licensing.
|
||||
* See the License for the specific language governing permissions
|
||||
* and limitations under the License.
|
||||
*
|
||||
* When distributing Covered Code, include this CDDL HEADER in each
|
||||
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
||||
* If applicable, add the following below this CDDL HEADER, with the
|
||||
* fields enclosed by brackets "[]" replaced with your own identifying
|
||||
* information: Portions Copyright [yyyy] [name of copyright owner]
|
||||
*
|
||||
* CDDL HEADER END
|
||||
*/
|
||||
/*
|
||||
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
#pragma ident "%Z%%M% %I% %E% SMI"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include <dt_impl.h>
|
||||
#include <dt_pid.h>
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp)
|
||||
{
|
||||
|
||||
dt_dprintf("%s: unimplemented\n", __func__);
|
||||
return (DT_PROC_ERR);
|
||||
}
|
||||
|
||||
int
|
||||
dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret)
|
||||
{
|
||||
|
||||
dt_dprintf("%s: unimplemented\n", __func__);
|
||||
return (DT_PROC_ERR);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off)
|
||||
{
|
||||
|
||||
dt_dprintf("%s: unimplemented\n", __func__);
|
||||
return (DT_PROC_ERR);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp,
|
||||
fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern)
|
||||
{
|
||||
|
||||
dt_dprintf("%s: unimplemented\n", __func__);
|
||||
return (DT_PROC_ERR);
|
||||
}
|
@ -19,7 +19,8 @@ _libzpool= libzpool
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" || ${MACHINE_CPUARCH} == "mips"
|
||||
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" || \
|
||||
${MACHINE_CPUARCH} == "mips" || ${MACHINE_CPUARCH} == "powerpc"
|
||||
_drti= drti
|
||||
_libdtrace= libdtrace
|
||||
.endif
|
||||
|
@ -74,6 +74,10 @@ CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc
|
||||
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/mips
|
||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/mips
|
||||
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/mips
|
||||
.elif ${MACHINE_CPUARCH} == "powerpc"
|
||||
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/powerpc
|
||||
.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/powerpc
|
||||
.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/powerpc
|
||||
.else
|
||||
# temporary hack
|
||||
CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel
|
||||
|
@ -25,4 +25,10 @@ _lockstat= lockstat
|
||||
_dtrace= dtrace
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "powerpc"
|
||||
_dtrace= dtrace
|
||||
_dtruss= dtruss
|
||||
_lockstat= lockstat
|
||||
.endif
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
@ -232,9 +232,8 @@ c_val_print (struct type *type, char *valaddr, int embedded_offset,
|
||||
wtype = TYPE_TARGET_TYPE (type);
|
||||
}
|
||||
vt_val = value_at (wtype, vt_address, NULL);
|
||||
val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val), 0,
|
||||
VALUE_ADDRESS (vt_val), stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
common_val_print (vt_val, stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
if (pretty)
|
||||
{
|
||||
fprintf_filtered (stream, "\n");
|
||||
@ -283,15 +282,8 @@ c_val_print (struct type *type, char *valaddr, int embedded_offset,
|
||||
unpack_pointer (lookup_pointer_type (builtin_type_void),
|
||||
valaddr + embedded_offset),
|
||||
NULL);
|
||||
val_print (VALUE_TYPE (deref_val),
|
||||
VALUE_CONTENTS (deref_val),
|
||||
0,
|
||||
VALUE_ADDRESS (deref_val),
|
||||
stream,
|
||||
format,
|
||||
deref_ref,
|
||||
recurse,
|
||||
pretty);
|
||||
common_val_print (deref_val, stream, format, deref_ref,
|
||||
recurse, pretty);
|
||||
}
|
||||
else
|
||||
fputs_filtered ("???", stream);
|
||||
|
@ -361,8 +361,7 @@ cp_print_value_fields (struct type *type, struct type *real_type, char *valaddr,
|
||||
(TYPE_FIELD_TYPE (type, i),
|
||||
unpack_field_as_long (type, valaddr + offset, i));
|
||||
|
||||
val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v),
|
||||
0, 0, stream, format, 0, recurse + 1, pretty);
|
||||
common_val_print (v, stream, format, 0, recurse + 1, pretty);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -426,8 +425,7 @@ cp_print_value_fields (struct type *type, struct type *real_type, char *valaddr,
|
||||
v = value_from_pointer (lookup_pointer_type (builtin_type_unsigned_long),
|
||||
*(unsigned long *) (valaddr + offset));
|
||||
|
||||
val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
|
||||
stream, format, 0, recurse + 1, pretty);
|
||||
common_val_print (v, stream, format, 0, recurse + 1, pretty);
|
||||
fields_seen = 1;
|
||||
|
||||
if (vtblprint)
|
||||
@ -791,8 +789,7 @@ cp_print_hpacc_virtual_table_entries (struct type *type, int *vfuncs,
|
||||
VALUE_TYPE (vf) = VALUE_TYPE (v); /* make it a pointer */
|
||||
|
||||
/* print out the entry */
|
||||
val_print (VALUE_TYPE (vf), VALUE_CONTENTS (vf), 0, 0,
|
||||
stream, format, 0, recurse + 1, pretty);
|
||||
common_val_print (vf, stream, format, 0, recurse + 1, pretty);
|
||||
field_physname
|
||||
= TYPE_FN_FIELD_PHYSNAME (TYPE_FN_FIELDLIST1 (type, fn), oi);
|
||||
/* pai: (temp) FIXME Maybe this should be DMGL_ANSI */
|
||||
|
@ -492,9 +492,14 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
|
||||
data = find_location_expression (dlbaton, &size,
|
||||
frame ? get_frame_pc (frame) : 0);
|
||||
if (data == NULL)
|
||||
error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol));
|
||||
|
||||
val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, dlbaton->objfile);
|
||||
{
|
||||
val = allocate_value (SYMBOL_TYPE (symbol));
|
||||
VALUE_LVAL (val) = not_lval;
|
||||
VALUE_OPTIMIZED_OUT (val) = 1;
|
||||
}
|
||||
else
|
||||
val = dwarf2_evaluate_loc_desc (symbol, frame, data, size,
|
||||
dlbaton->objfile);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
@ -444,15 +444,8 @@ f_val_print (struct type *type, char *valaddr, int embedded_offset,
|
||||
unpack_pointer (lookup_pointer_type (builtin_type_void),
|
||||
valaddr + embedded_offset),
|
||||
NULL);
|
||||
val_print (VALUE_TYPE (deref_val),
|
||||
VALUE_CONTENTS (deref_val),
|
||||
0,
|
||||
VALUE_ADDRESS (deref_val),
|
||||
stream,
|
||||
format,
|
||||
deref_ref,
|
||||
recurse,
|
||||
pretty);
|
||||
common_val_print (deref_val, stream, format, deref_ref, recurse,
|
||||
pretty);
|
||||
}
|
||||
else
|
||||
fputs_filtered ("???", stream);
|
||||
|
@ -189,8 +189,7 @@ java_value_print (struct value *val, struct ui_file *stream, int format,
|
||||
else
|
||||
fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);
|
||||
|
||||
val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
|
||||
stream, format, 2, 1, pretty);
|
||||
common_val_print (v, stream, format, 2, 1, pretty);
|
||||
|
||||
things_printed++;
|
||||
i += reps;
|
||||
@ -242,8 +241,7 @@ java_value_print (struct value *val, struct ui_file *stream, int format,
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (val_print (type, VALUE_CONTENTS (val), 0, address,
|
||||
stream, format, 1, 0, pretty));
|
||||
return common_val_print (val, stream, format, 1, 0, pretty);
|
||||
}
|
||||
|
||||
/* TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the
|
||||
@ -391,8 +389,7 @@ java_print_value_fields (struct type *type, char *valaddr, CORE_ADDR address,
|
||||
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
|
||||
unpack_field_as_long (type, valaddr, i));
|
||||
|
||||
val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0,
|
||||
0, stream, format, 0, recurse + 1, pretty);
|
||||
common_val_print (v, stream, format, 0, recurse + 1, pretty);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -411,9 +408,8 @@ java_print_value_fields (struct type *type, char *valaddr, CORE_ADDR address,
|
||||
struct type *t = check_typedef (VALUE_TYPE (v));
|
||||
if (TYPE_CODE (t) == TYPE_CODE_STRUCT)
|
||||
v = value_addr (v);
|
||||
val_print (VALUE_TYPE (v),
|
||||
VALUE_CONTENTS (v), 0, VALUE_ADDRESS (v),
|
||||
stream, format, 0, recurse + 1, pretty);
|
||||
common_val_print (v, stream, format, 0, recurse + 1,
|
||||
pretty);
|
||||
}
|
||||
}
|
||||
else if (TYPE_FIELD_TYPE (type, i) == NULL)
|
||||
|
@ -238,9 +238,8 @@ pascal_val_print (struct type *type, char *valaddr, int embedded_offset,
|
||||
wtype = TYPE_TARGET_TYPE (type);
|
||||
}
|
||||
vt_val = value_at (wtype, vt_address, NULL);
|
||||
val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val), 0,
|
||||
VALUE_ADDRESS (vt_val), stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
common_val_print (vt_val, stream, format, deref_ref,
|
||||
recurse + 1, pretty);
|
||||
if (pretty)
|
||||
{
|
||||
fprintf_filtered (stream, "\n");
|
||||
@ -291,10 +290,8 @@ pascal_val_print (struct type *type, char *valaddr, int embedded_offset,
|
||||
unpack_pointer (lookup_pointer_type (builtin_type_void),
|
||||
valaddr + embedded_offset),
|
||||
NULL);
|
||||
val_print (VALUE_TYPE (deref_val),
|
||||
VALUE_CONTENTS (deref_val), 0,
|
||||
VALUE_ADDRESS (deref_val), stream, format,
|
||||
deref_ref, recurse + 1, pretty);
|
||||
common_val_print (deref_val, stream, format, deref_ref,
|
||||
recurse + 1, pretty);
|
||||
}
|
||||
else
|
||||
fputs_filtered ("???", stream);
|
||||
@ -565,9 +562,7 @@ pascal_value_print (struct value *val, struct ui_file *stream, int format,
|
||||
fprintf_filtered (stream, ") ");
|
||||
}
|
||||
}
|
||||
return val_print (type, VALUE_CONTENTS (val), VALUE_EMBEDDED_OFFSET (val),
|
||||
VALUE_ADDRESS (val) + VALUE_OFFSET (val),
|
||||
stream, format, 1, 0, pretty);
|
||||
return common_val_print (val, stream, format, 1, 0, pretty);
|
||||
}
|
||||
|
||||
|
||||
@ -583,7 +578,7 @@ static int pascal_static_field_print; /* Controls printing of static fields. */
|
||||
static struct obstack dont_print_vb_obstack;
|
||||
static struct obstack dont_print_statmem_obstack;
|
||||
|
||||
static void pascal_object_print_static_field (struct type *, struct value *,
|
||||
static void pascal_object_print_static_field (struct value *,
|
||||
struct ui_file *, int, int,
|
||||
enum val_prettyprint);
|
||||
|
||||
@ -844,8 +839,7 @@ pascal_object_print_value_fields (struct type *type, char *valaddr,
|
||||
v = value_from_longest (TYPE_FIELD_TYPE (type, i),
|
||||
unpack_field_as_long (type, valaddr, i));
|
||||
|
||||
val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0,
|
||||
stream, format, 0, recurse + 1, pretty);
|
||||
common_val_print (v, stream, format, 0, recurse + 1, pretty);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -864,9 +858,8 @@ pascal_object_print_value_fields (struct type *type, char *valaddr,
|
||||
if (v == NULL)
|
||||
fputs_filtered ("<optimized out>", stream);
|
||||
else
|
||||
pascal_object_print_static_field (TYPE_FIELD_TYPE (type, i), v,
|
||||
stream, format, recurse + 1,
|
||||
pretty);
|
||||
pascal_object_print_static_field (v, stream, format,
|
||||
recurse + 1, pretty);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1005,14 +998,16 @@ pascal_object_print_value (struct type *type, char *valaddr, CORE_ADDR address,
|
||||
static member classes in an obstack and refuse to print them more
|
||||
than once.
|
||||
|
||||
VAL contains the value to print, TYPE, STREAM, RECURSE, and PRETTY
|
||||
VAL contains the value to print, STREAM, RECURSE, and PRETTY
|
||||
have the same meanings as in c_val_print. */
|
||||
|
||||
static void
|
||||
pascal_object_print_static_field (struct type *type, struct value *val,
|
||||
pascal_object_print_static_field (struct value *val,
|
||||
struct ui_file *stream, int format,
|
||||
int recurse, enum val_prettyprint pretty)
|
||||
{
|
||||
struct type *type = VALUE_TYPE (val);
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
|
||||
{
|
||||
CORE_ADDR *first_dont_print;
|
||||
@ -1041,8 +1036,7 @@ pascal_object_print_static_field (struct type *type, struct value *val,
|
||||
stream, format, recurse, pretty, NULL, 1);
|
||||
return;
|
||||
}
|
||||
val_print (type, VALUE_CONTENTS (val), 0, VALUE_ADDRESS (val),
|
||||
stream, format, 0, recurse, pretty);
|
||||
common_val_print (val, stream, format, 0, recurse, pretty);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -390,6 +390,5 @@ int
|
||||
scm_value_print (struct value *val, struct ui_file *stream, int format,
|
||||
enum val_prettyprint pretty)
|
||||
{
|
||||
return (val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
|
||||
VALUE_ADDRESS (val), stream, format, 1, 0, pretty));
|
||||
return (common_val_print (val, stream, format, 1, 0, pretty));
|
||||
}
|
||||
|
@ -354,9 +354,7 @@ print_frame_args (struct symbol *func, struct frame_info *fi, int num,
|
||||
|
||||
if (val)
|
||||
{
|
||||
val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
|
||||
VALUE_ADDRESS (val),
|
||||
stb->stream, 0, 0, 2, Val_no_prettyprint);
|
||||
common_val_print (val, stb->stream, 0, 0, 2, Val_no_prettyprint);
|
||||
ui_out_field_stream (uiout, "value", stb);
|
||||
}
|
||||
else
|
||||
|
@ -150,6 +150,54 @@ val_print (struct type *type, char *valaddr, int embedded_offset,
|
||||
stream, format, deref_ref, recurse, pretty));
|
||||
}
|
||||
|
||||
/* Check whether the value VAL is printable. Return 1 if it is;
|
||||
return 0 and print an appropriate error message to STREAM if it
|
||||
is not. */
|
||||
|
||||
static int
|
||||
value_check_printable (struct value *val, struct ui_file *stream)
|
||||
{
|
||||
if (val == 0)
|
||||
{
|
||||
fprintf_filtered (stream, "<address of value unknown>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (VALUE_OPTIMIZED_OUT (val))
|
||||
{
|
||||
fprintf_filtered (stream, "<value optimized out>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Print the value VAL onto stream STREAM according to FORMAT (a
|
||||
letter, or 0 for natural format using TYPE).
|
||||
|
||||
If DEREF_REF is nonzero, then dereference references, otherwise just print
|
||||
them like pointers.
|
||||
|
||||
The PRETTY parameter controls prettyprinting.
|
||||
|
||||
If the data are a string pointer, returns the number of string characters
|
||||
printed.
|
||||
|
||||
This is a preferable interface to val_print, above, because it uses
|
||||
GDB's value mechanism. */
|
||||
|
||||
int
|
||||
common_val_print (struct value *val, struct ui_file *stream, int format,
|
||||
int deref_ref, int recurse, enum val_prettyprint pretty)
|
||||
{
|
||||
if (!value_check_printable (val, stream))
|
||||
return 0;
|
||||
|
||||
return val_print (VALUE_TYPE(val), VALUE_CONTENTS_ALL (val),
|
||||
VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
|
||||
stream, format, deref_ref, recurse, pretty);
|
||||
}
|
||||
|
||||
/* Print the value VAL in C-ish syntax on stream STREAM.
|
||||
FORMAT is a format-letter, or 0 for print in natural format of data type.
|
||||
If the object printed is a string pointer, returns
|
||||
@ -159,16 +207,9 @@ int
|
||||
value_print (struct value *val, struct ui_file *stream, int format,
|
||||
enum val_prettyprint pretty)
|
||||
{
|
||||
if (val == 0)
|
||||
{
|
||||
printf_filtered ("<address of value unknown>");
|
||||
return 0;
|
||||
}
|
||||
if (VALUE_OPTIMIZED_OUT (val))
|
||||
{
|
||||
printf_filtered ("<value optimized out>");
|
||||
return 0;
|
||||
}
|
||||
if (!value_check_printable (val, stream))
|
||||
return 0;
|
||||
|
||||
return LA_VALUE_PRINT (val, stream, format, pretty);
|
||||
}
|
||||
|
||||
|
@ -523,6 +523,11 @@ extern int val_print (struct type * type, char *valaddr,
|
||||
int deref_ref, int recurse,
|
||||
enum val_prettyprint pretty);
|
||||
|
||||
extern int common_val_print (struct value *val,
|
||||
struct ui_file *stream, int format,
|
||||
int deref_ref, int recurse,
|
||||
enum val_prettyprint pretty);
|
||||
|
||||
extern int val_print_string (CORE_ADDR addr, int len, int width, struct ui_file *stream);
|
||||
|
||||
extern void print_variable_value (struct symbol * var,
|
||||
|
@ -2093,10 +2093,8 @@ c_value_of_variable (struct varobj *var)
|
||||
|
||||
if (VALUE_LAZY (var->value))
|
||||
gdb_value_fetch_lazy (var->value);
|
||||
val_print (VALUE_TYPE (var->value),
|
||||
VALUE_CONTENTS_RAW (var->value), 0,
|
||||
VALUE_ADDRESS (var->value), stb,
|
||||
format_code[(int) var->format], 1, 0, 0);
|
||||
common_val_print (var->value, stb,
|
||||
format_code[(int) var->format], 1, 0, 0);
|
||||
thevalue = ui_file_xstrdup (stb, &dummy);
|
||||
do_cleanups (old_chain);
|
||||
return thevalue;
|
||||
|
@ -6,6 +6,47 @@ found in the git revision history:
|
||||
http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git
|
||||
git://canonware.com/jemalloc.git
|
||||
|
||||
* 3.2.0 (November 9, 2012)
|
||||
|
||||
In addition to a couple of bug fixes, this version modifies page run
|
||||
allocation and dirty page purging algorithms in order to better control
|
||||
page-level virtual memory fragmentation.
|
||||
|
||||
Incompatible changes:
|
||||
- Change the "opt.lg_dirty_mult" default from 5 to 3 (32:1 to 8:1).
|
||||
|
||||
Bug fixes:
|
||||
- Fix dss/mmap allocation precedence code to use recyclable mmap memory only
|
||||
after primary dss allocation fails.
|
||||
- Fix deadlock in the "arenas.purge" mallctl. This regression was introduced
|
||||
in 3.1.0 by the addition of the "arena.<i>.purge" mallctl.
|
||||
|
||||
* 3.1.0 (October 16, 2012)
|
||||
|
||||
New features:
|
||||
- Auto-detect whether running inside Valgrind, thus removing the need to
|
||||
manually specify MALLOC_CONF=valgrind:true.
|
||||
- Add the "arenas.extend" mallctl, which allows applications to create
|
||||
manually managed arenas.
|
||||
- Add the ALLOCM_ARENA() flag for {,r,d}allocm().
|
||||
- Add the "opt.dss", "arena.<i>.dss", and "stats.arenas.<i>.dss" mallctls,
|
||||
which provide control over dss/mmap precedence.
|
||||
- Add the "arena.<i>.purge" mallctl, which obsoletes "arenas.purge".
|
||||
- Define LG_QUANTUM for hppa.
|
||||
|
||||
Incompatible changes:
|
||||
- Disable tcache by default if running inside Valgrind, in order to avoid
|
||||
making unallocated objects appear reachable to Valgrind.
|
||||
- Drop const from malloc_usable_size() argument on Linux.
|
||||
|
||||
Bug fixes:
|
||||
- Fix heap profiling crash if sampled object is freed via realloc(p, 0).
|
||||
- Remove const from __*_hook variable declarations, so that glibc can modify
|
||||
them during process forking.
|
||||
- Fix mlockall(2)/madvise(2) interaction.
|
||||
- Fix fork(2)-related deadlocks.
|
||||
- Fix error return value for "thread.tcache.enabled" mallctl.
|
||||
|
||||
* 3.0.0 (May 11, 2012)
|
||||
|
||||
Although this version adds some major new features, the primary focus is on
|
||||
|
@ -1,5 +1,5 @@
|
||||
diff --git a/doc/jemalloc.xml.in b/doc/jemalloc.xml.in
|
||||
index 877c500..7d659a7 100644
|
||||
index 54b8747..91c4a4e 100644
|
||||
--- a/doc/jemalloc.xml.in
|
||||
+++ b/doc/jemalloc.xml.in
|
||||
@@ -51,12 +51,23 @@
|
||||
@ -27,7 +27,7 @@ index 877c500..7d659a7 100644
|
||||
<refsect2>
|
||||
<title>Standard API</title>
|
||||
<funcprototype>
|
||||
@@ -2101,4 +2112,16 @@ malloc_conf = "lg_chunk:24";]]></programlisting></para>
|
||||
@@ -2170,4 +2181,16 @@ malloc_conf = "lg_chunk:24";]]></programlisting></para>
|
||||
<para>The <function>posix_memalign<parameter/></function> function conforms
|
||||
to IEEE Std 1003.1-2001 (“POSIX.1”).</para>
|
||||
</refsect1>
|
||||
@ -45,7 +45,7 @@ index 877c500..7d659a7 100644
|
||||
+ </refsect1>
|
||||
</refentry>
|
||||
diff --git a/include/jemalloc/internal/jemalloc_internal.h.in b/include/jemalloc/internal/jemalloc_internal.h.in
|
||||
index 268cd14..2acd2eb 100644
|
||||
index 475821a..73306ac 100644
|
||||
--- a/include/jemalloc/internal/jemalloc_internal.h.in
|
||||
+++ b/include/jemalloc/internal/jemalloc_internal.h.in
|
||||
@@ -1,5 +1,8 @@
|
||||
@ -97,19 +97,19 @@ index de44e14..564d604 100644
|
||||
|
||||
bool malloc_mutex_init(malloc_mutex_t *mutex);
|
||||
diff --git a/include/jemalloc/internal/private_namespace.h b/include/jemalloc/internal/private_namespace.h
|
||||
index b816647..b8ce6b1 100644
|
||||
index 06241cd..7b19906 100644
|
||||
--- a/include/jemalloc/internal/private_namespace.h
|
||||
+++ b/include/jemalloc/internal/private_namespace.h
|
||||
@@ -186,7 +186,6 @@
|
||||
#define iqalloc JEMALLOC_N(iqalloc)
|
||||
@@ -204,7 +204,6 @@
|
||||
#define iralloc JEMALLOC_N(iralloc)
|
||||
#define irallocx JEMALLOC_N(irallocx)
|
||||
#define isalloc JEMALLOC_N(isalloc)
|
||||
-#define isthreaded JEMALLOC_N(isthreaded)
|
||||
#define ivsalloc JEMALLOC_N(ivsalloc)
|
||||
#define jemalloc_postfork_child JEMALLOC_N(jemalloc_postfork_child)
|
||||
#define jemalloc_postfork_parent JEMALLOC_N(jemalloc_postfork_parent)
|
||||
diff --git a/include/jemalloc/jemalloc.h.in b/include/jemalloc/jemalloc.h.in
|
||||
index ad06948..505dd38 100644
|
||||
index 31b1304..c3ef2f5 100644
|
||||
--- a/include/jemalloc/jemalloc.h.in
|
||||
+++ b/include/jemalloc/jemalloc.h.in
|
||||
@@ -15,6 +15,7 @@ extern "C" {
|
||||
@ -122,7 +122,7 @@ index ad06948..505dd38 100644
|
||||
#define ALLOCM_LG_ALIGN(la) (la)
|
||||
diff --git a/include/jemalloc/jemalloc_FreeBSD.h b/include/jemalloc/jemalloc_FreeBSD.h
|
||||
new file mode 100644
|
||||
index 0000000..9efab93
|
||||
index 0000000..9c97a13
|
||||
--- /dev/null
|
||||
+++ b/include/jemalloc/jemalloc_FreeBSD.h
|
||||
@@ -0,0 +1,76 @@
|
||||
@ -203,7 +203,7 @@ index 0000000..9efab93
|
||||
+#define pthread_mutex_lock _pthread_mutex_lock
|
||||
+#define pthread_mutex_unlock _pthread_mutex_unlock
|
||||
diff --git a/src/jemalloc.c b/src/jemalloc.c
|
||||
index bc54cd7..fa9fcf0 100644
|
||||
index 8a667b6..aaf5012 100644
|
||||
--- a/src/jemalloc.c
|
||||
+++ b/src/jemalloc.c
|
||||
@@ -8,6 +8,10 @@ malloc_tsd_data(, arenas, arena_t *, NULL)
|
||||
@ -217,7 +217,7 @@ index bc54cd7..fa9fcf0 100644
|
||||
/* Runtime configuration options. */
|
||||
const char *je_malloc_conf;
|
||||
#ifdef JEMALLOC_DEBUG
|
||||
@@ -429,7 +433,8 @@ malloc_conf_init(void)
|
||||
@@ -448,7 +452,8 @@ malloc_conf_init(void)
|
||||
#endif
|
||||
;
|
||||
|
||||
@ -228,12 +228,12 @@ index bc54cd7..fa9fcf0 100644
|
||||
* Do nothing; opts is already initialized to
|
||||
* the value of the MALLOC_CONF environment
|
||||
diff --git a/src/mutex.c b/src/mutex.c
|
||||
index 37a843e..4a90a05 100644
|
||||
index 55e18c2..6b6f438 100644
|
||||
--- a/src/mutex.c
|
||||
+++ b/src/mutex.c
|
||||
@@ -66,6 +66,17 @@ pthread_create(pthread_t *__restrict thread,
|
||||
#ifdef JEMALLOC_MUTEX_INIT_CB
|
||||
int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
|
||||
JEMALLOC_EXPORT int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
|
||||
void *(calloc_cb)(size_t, size_t));
|
||||
+
|
||||
+__weak_reference(_pthread_mutex_init_calloc_cb_stub,
|
||||
@ -250,7 +250,7 @@ index 37a843e..4a90a05 100644
|
||||
|
||||
bool
|
||||
diff --git a/src/util.c b/src/util.c
|
||||
index 9b73c3e..f94799f 100644
|
||||
index b3a0114..df1c5d5 100644
|
||||
--- a/src/util.c
|
||||
+++ b/src/util.c
|
||||
@@ -58,6 +58,22 @@ wrtmessage(void *cbopaque, const char *s)
|
||||
|
@ -1 +1 @@
|
||||
3.0.0-0-gfc9b1dbf69f59d7ecfc4ac68da9847e017e1d046
|
||||
3.2.0-0-g87499f6748ebe4817571e817e9f680ccb5bf54a9
|
||||
|
@ -2,12 +2,12 @@
|
||||
.\" Title: JEMALLOC
|
||||
.\" Author: Jason Evans
|
||||
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
|
||||
.\" Date: 05/12/2012
|
||||
.\" Date: 11/09/2012
|
||||
.\" Manual: User Manual
|
||||
.\" Source: jemalloc 3.0.0-0-gfc9b1dbf69f59d7ecfc4ac68da9847e017e1d046
|
||||
.\" Source: jemalloc 3.2.0-0-g87499f6748ebe4817571e817e9f680ccb5bf54a9
|
||||
.\" Language: English
|
||||
.\"
|
||||
.TH "JEMALLOC" "3" "05/12/2012" "jemalloc 3.0.0-0-gfc9b1dbf69f5" "User Manual"
|
||||
.TH "JEMALLOC" "3" "11/09/2012" "jemalloc 3.2.0-0-g87499f6748eb" "User Manual"
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * Define some portability stuff
|
||||
.\" -----------------------------------------------------------------
|
||||
@ -31,7 +31,7 @@
|
||||
jemalloc \- general purpose memory allocation functions
|
||||
.SH "LIBRARY"
|
||||
.PP
|
||||
This manual describes jemalloc 3\&.0\&.0\-0\-gfc9b1dbf69f59d7ecfc4ac68da9847e017e1d046\&. More information can be found at the
|
||||
This manual describes jemalloc 3\&.2\&.0\-0\-g87499f6748ebe4817571e817e9f680ccb5bf54a9\&. More information can be found at the
|
||||
\m[blue]\fBjemalloc website\fR\m[]\&\s-2\u[1]\d\s+2\&.
|
||||
.PP
|
||||
The following configuration options are enabled in libc\*(Aqs built\-in jemalloc:
|
||||
@ -310,6 +310,14 @@ Initialize newly allocated memory to contain zero bytes\&. In the growing reallo
|
||||
For reallocation, fail rather than moving the object\&. This constraint can apply to both growth and shrinkage\&.
|
||||
.RE
|
||||
.PP
|
||||
\fBALLOCM_ARENA(\fR\fB\fIa\fR\fR\fB) \fR
|
||||
.RS 4
|
||||
Use the arena specified by the index
|
||||
\fIa\fR\&. This macro does not validate that
|
||||
\fIa\fR
|
||||
specifies an arena in the valid range\&.
|
||||
.RE
|
||||
.PP
|
||||
The
|
||||
\fBallocm\fR\fB\fR
|
||||
function allocates at least
|
||||
@ -647,16 +655,23 @@ is specified during configuration, in which case it is enabled by default\&.
|
||||
Virtual memory chunk size (log base 2)\&. The default chunk size is 4 MiB (2^22)\&.
|
||||
.RE
|
||||
.PP
|
||||
"opt\&.dss" (\fBconst char *\fR) r\-
|
||||
.RS 4
|
||||
dss (\fBsbrk\fR(2)) allocation precedence as related to
|
||||
\fBmmap\fR(2)
|
||||
allocation\&. The following settings are supported: \(lqdisabled\(rq, \(lqprimary\(rq, and \(lqsecondary\(rq (default)\&.
|
||||
.RE
|
||||
.PP
|
||||
"opt\&.narenas" (\fBsize_t\fR) r\-
|
||||
.RS 4
|
||||
Maximum number of arenas to use\&. The default maximum number of arenas is four times the number of CPUs, or one if there is a single CPU\&.
|
||||
Maximum number of arenas to use for automatic multiplexing of threads and arenas\&. The default is four times the number of CPUs, or one if there is a single CPU\&.
|
||||
.RE
|
||||
.PP
|
||||
"opt\&.lg_dirty_mult" (\fBssize_t\fR) r\-
|
||||
.RS 4
|
||||
Per\-arena minimum ratio (log base 2) of active to dirty pages\&. Some dirty unused pages may be allowed to accumulate, within the limit set by the ratio (or one chunk worth of dirty pages, whichever is greater), before informing the kernel about some of those pages via
|
||||
\fBmadvise\fR(2)
|
||||
or a similar system call\&. This provides the kernel with sufficient information to recycle dirty pages if physical memory becomes scarce and the pages remain unused\&. The default minimum ratio is 32:1 (2^5:1); an option value of \-1 will disable dirty page purging\&.
|
||||
or a similar system call\&. This provides the kernel with sufficient information to recycle dirty pages if physical memory becomes scarce and the pages remain unused\&. The default minimum ratio is 8:1 (2^3:1); an option value of \-1 will disable dirty page purging\&.
|
||||
.RE
|
||||
.PP
|
||||
"opt\&.stats_print" (\fBbool\fR) r\-
|
||||
@ -676,7 +691,8 @@ Junk filling enabled/disabled\&. If enabled, each byte of uninitialized allocate
|
||||
0xa5\&. All deallocated memory will be initialized to
|
||||
0x5a\&. This is intended for debugging and will impact performance negatively\&. This option is disabled by default unless
|
||||
\fB\-\-enable\-debug\fR
|
||||
is specified during configuration, in which case it is enabled by default\&.
|
||||
is specified during configuration, in which case it is enabled by default unless running inside
|
||||
\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2\&.
|
||||
.RE
|
||||
.PP
|
||||
"opt\&.quarantine" (\fBsize_t\fR) r\- [\fB\-\-enable\-fill\fR]
|
||||
@ -684,7 +700,7 @@ is specified during configuration, in which case it is enabled by default\&.
|
||||
Per thread quarantine size in bytes\&. If non\-zero, each thread maintains a FIFO object quarantine that stores up to the specified number of bytes of memory\&. The quarantined memory is not freed until it is released from quarantine, though it is immediately junk\-filled if the
|
||||
"opt\&.junk"
|
||||
option is enabled\&. This feature is of particular use in combination with
|
||||
\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2, which can detect attempts to access quarantined objects\&. This is intended for debugging and will impact performance negatively\&. The default quarantine size is 0\&.
|
||||
\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2, which can detect attempts to access quarantined objects\&. This is intended for debugging and will impact performance negatively\&. The default quarantine size is 0 unless running inside Valgrind, in which case the default is 16 MiB\&.
|
||||
.RE
|
||||
.PP
|
||||
"opt\&.redzone" (\fBbool\fR) r\- [\fB\-\-enable\-fill\fR]
|
||||
@ -692,7 +708,7 @@ option is enabled\&. This feature is of particular use in combination with
|
||||
Redzones enabled/disabled\&. If enabled, small allocations have redzones before and after them\&. Furthermore, if the
|
||||
"opt\&.junk"
|
||||
option is enabled, the redzones are checked for corruption during deallocation\&. However, the primary intended purpose of this feature is to be used in combination with
|
||||
\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2, which needs redzones in order to do effective buffer overflow/underflow detection\&. This option is intended for debugging and will impact performance negatively\&. This option is disabled by default\&.
|
||||
\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2, which needs redzones in order to do effective buffer overflow/underflow detection\&. This option is intended for debugging and will impact performance negatively\&. This option is disabled by default unless running inside Valgrind\&.
|
||||
.RE
|
||||
.PP
|
||||
"opt\&.zero" (\fBbool\fR) r\- [\fB\-\-enable\-fill\fR]
|
||||
@ -714,15 +730,7 @@ enabled/disabled\&. This option is disabled by default\&.
|
||||
"opt\&.valgrind" (\fBbool\fR) r\- [\fB\-\-enable\-valgrind\fR]
|
||||
.RS 4
|
||||
\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2
|
||||
support enabled/disabled\&. If enabled, several other options are automatically modified during options processing to work well with Valgrind:
|
||||
"opt\&.junk"
|
||||
and
|
||||
"opt\&.zero"
|
||||
are set to false,
|
||||
"opt\&.quarantine"
|
||||
is set to 16 MiB, and
|
||||
"opt\&.redzone"
|
||||
is set to true\&. This option is disabled by default\&.
|
||||
support enabled/disabled\&. This option is vestigal because jemalloc auto\-detects whether it is running inside Valgrind\&. This option is disabled by default, unless running inside Valgrind\&.
|
||||
.RE
|
||||
.PP
|
||||
"opt\&.xmalloc" (\fBbool\fR) r\- [\fB\-\-enable\-xmalloc\fR]
|
||||
@ -749,7 +757,8 @@ This option is disabled by default\&.
|
||||
.RS 4
|
||||
Thread\-specific caching enabled/disabled\&. When there are multiple threads, each thread uses a thread\-specific cache for objects up to a certain size\&. Thread\-specific caching allows many allocations to be satisfied without performing any thread synchronization, at the cost of increased memory use\&. See the
|
||||
"opt\&.lg_tcache_max"
|
||||
option for related tuning information\&. This option is enabled by default\&.
|
||||
option for related tuning information\&. This option is enabled by default unless running inside
|
||||
\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2\&.
|
||||
.RE
|
||||
.PP
|
||||
"opt\&.lg_tcache_max" (\fBsize_t\fR) r\- [\fB\-\-enable\-tcache\fR]
|
||||
@ -845,9 +854,7 @@ option for information on analyzing heap profile output\&. This option is disabl
|
||||
.PP
|
||||
"thread\&.arena" (\fBunsigned\fR) rw
|
||||
.RS 4
|
||||
Get or set the arena associated with the calling thread\&. The arena index must be less than the maximum number of arenas (see the
|
||||
"arenas\&.narenas"
|
||||
mallctl)\&. If the specified arena was not initialized beforehand (see the
|
||||
Get or set the arena associated with the calling thread\&. If the specified arena was not initialized beforehand (see the
|
||||
"arenas\&.initialized"
|
||||
mallctl), it will be automatically initialized as a side effect of calling this interface\&.
|
||||
.RE
|
||||
@ -891,9 +898,23 @@ Enable/disable calling thread\*(Aqs tcache\&. The tcache is implicitly flushed a
|
||||
Flush calling thread\*(Aqs tcache\&. This interface releases all cached objects and internal data structures associated with the calling thread\*(Aqs thread\-specific cache\&. Ordinarily, this interface need not be called, since automatic periodic incremental garbage collection occurs, and the thread cache is automatically discarded when a thread exits\&. However, garbage collection is triggered by allocation activity, so it is possible for a thread that stops allocating/deallocating to retain its cache indefinitely, in which case the developer may find manual flushing useful\&.
|
||||
.RE
|
||||
.PP
|
||||
"arena\&.<i>\&.purge" (\fBunsigned\fR) \-\-
|
||||
.RS 4
|
||||
Purge unused dirty pages for arena <i>, or for all arenas if <i> equals
|
||||
"arenas\&.narenas"\&.
|
||||
.RE
|
||||
.PP
|
||||
"arena\&.<i>\&.dss" (\fBconst char *\fR) rw
|
||||
.RS 4
|
||||
Set the precedence of dss allocation as related to mmap allocation for arena <i>, or for all arenas if <i> equals
|
||||
"arenas\&.narenas"\&. See
|
||||
"opt\&.dss"
|
||||
for supported settings\&.
|
||||
.RE
|
||||
.PP
|
||||
"arenas\&.narenas" (\fBunsigned\fR) r\-
|
||||
.RS 4
|
||||
Maximum number of arenas\&.
|
||||
Current limit on number of arenas\&.
|
||||
.RE
|
||||
.PP
|
||||
"arenas\&.initialized" (\fBbool *\fR) r\-
|
||||
@ -958,6 +979,11 @@ Maximum size supported by this large size class\&.
|
||||
Purge unused dirty pages for the specified arena, or for all arenas if none is specified\&.
|
||||
.RE
|
||||
.PP
|
||||
"arenas\&.extend" (\fBunsigned\fR) r\-
|
||||
.RS 4
|
||||
Extend the array of arenas by appending a new arena, and returning the new arena index\&.
|
||||
.RE
|
||||
.PP
|
||||
"prof\&.active" (\fBbool\fR) rw [\fB\-\-enable\-prof\fR]
|
||||
.RS 4
|
||||
Control whether sampling is currently active\&. See the
|
||||
@ -997,7 +1023,9 @@ Total number of bytes allocated by the application\&.
|
||||
"stats\&.active" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR]
|
||||
.RS 4
|
||||
Total number of bytes in active pages allocated by the application\&. This is a multiple of the page size, and greater than or equal to
|
||||
"stats\&.allocated"\&.
|
||||
"stats\&.allocated"\&. This does not include
|
||||
"stats\&.arenas\&.<i>\&.pdirty"
|
||||
and pages entirely devoted to allocator metadata\&.
|
||||
.RE
|
||||
.PP
|
||||
"stats\&.mapped" (\fBsize_t\fR) r\- [\fB\-\-enable\-stats\fR]
|
||||
@ -1036,6 +1064,15 @@ Cumulative number of huge allocation requests\&.
|
||||
Cumulative number of huge deallocation requests\&.
|
||||
.RE
|
||||
.PP
|
||||
"stats\&.arenas\&.<i>\&.dss" (\fBconst char *\fR) r\-
|
||||
.RS 4
|
||||
dss (\fBsbrk\fR(2)) allocation precedence as related to
|
||||
\fBmmap\fR(2)
|
||||
allocation\&. See
|
||||
"opt\&.dss"
|
||||
for details\&.
|
||||
.RE
|
||||
.PP
|
||||
"stats\&.arenas\&.<i>\&.nthreads" (\fBunsigned\fR) r\-
|
||||
.RS 4
|
||||
Number of threads currently assigned to arena\&.
|
||||
@ -1197,9 +1234,7 @@ This implementation does not provide much detail about the problems it detects,
|
||||
\m[blue]\fBValgrind\fR\m[]\&\s-2\u[2]\d\s+2
|
||||
tool if the
|
||||
\fB\-\-enable\-valgrind\fR
|
||||
configuration option is enabled and the
|
||||
"opt\&.valgrind"
|
||||
option is enabled\&.
|
||||
configuration option is enabled\&.
|
||||
.SH "DIAGNOSTIC MESSAGES"
|
||||
.PP
|
||||
If any of the memory allocation/deallocation functions detect an error or warning condition, a message will be printed to file descriptor
|
||||
|
@ -38,10 +38,10 @@
|
||||
*
|
||||
* (nactive >> opt_lg_dirty_mult) >= ndirty
|
||||
*
|
||||
* So, supposing that opt_lg_dirty_mult is 5, there can be no less than 32
|
||||
* times as many active pages as dirty pages.
|
||||
* So, supposing that opt_lg_dirty_mult is 3, there can be no less than 8 times
|
||||
* as many active pages as dirty pages.
|
||||
*/
|
||||
#define LG_DIRTY_MULT_DEFAULT 5
|
||||
#define LG_DIRTY_MULT_DEFAULT 3
|
||||
|
||||
typedef struct arena_chunk_map_s arena_chunk_map_t;
|
||||
typedef struct arena_chunk_s arena_chunk_t;
|
||||
@ -69,7 +69,7 @@ struct arena_chunk_map_s {
|
||||
/*
|
||||
* Linkage for run trees. There are two disjoint uses:
|
||||
*
|
||||
* 1) arena_t's runs_avail_{clean,dirty} trees.
|
||||
* 1) arena_t's runs_avail tree.
|
||||
* 2) arena_run_t conceptually uses this linkage for in-use
|
||||
* non-full runs, rather than directly embedding linkage.
|
||||
*/
|
||||
@ -162,20 +162,24 @@ typedef rb_tree(arena_chunk_map_t) arena_run_tree_t;
|
||||
/* Arena chunk header. */
|
||||
struct arena_chunk_s {
|
||||
/* Arena that owns the chunk. */
|
||||
arena_t *arena;
|
||||
arena_t *arena;
|
||||
|
||||
/* Linkage for the arena's chunks_dirty list. */
|
||||
ql_elm(arena_chunk_t) link_dirty;
|
||||
|
||||
/*
|
||||
* True if the chunk is currently in the chunks_dirty list, due to
|
||||
* having at some point contained one or more dirty pages. Removal
|
||||
* from chunks_dirty is lazy, so (dirtied && ndirty == 0) is possible.
|
||||
*/
|
||||
bool dirtied;
|
||||
/* Linkage for tree of arena chunks that contain dirty runs. */
|
||||
rb_node(arena_chunk_t) dirty_link;
|
||||
|
||||
/* Number of dirty pages. */
|
||||
size_t ndirty;
|
||||
size_t ndirty;
|
||||
|
||||
/* Number of available runs. */
|
||||
size_t nruns_avail;
|
||||
|
||||
/*
|
||||
* Number of available run adjacencies. Clean and dirty available runs
|
||||
* are not coalesced, which causes virtual memory fragmentation. The
|
||||
* ratio of (nruns_avail-nruns_adjac):nruns_adjac is used for tracking
|
||||
* this fragmentation.
|
||||
* */
|
||||
size_t nruns_adjac;
|
||||
|
||||
/*
|
||||
* Map of pages within chunk that keeps track of free/large/small. The
|
||||
@ -183,7 +187,7 @@ struct arena_chunk_s {
|
||||
* need to be tracked in the map. This omission saves a header page
|
||||
* for common chunk sizes (e.g. 4 MiB).
|
||||
*/
|
||||
arena_chunk_map_t map[1]; /* Dynamically sized. */
|
||||
arena_chunk_map_t map[1]; /* Dynamically sized. */
|
||||
};
|
||||
typedef rb_tree(arena_chunk_t) arena_chunk_tree_t;
|
||||
|
||||
@ -331,8 +335,10 @@ struct arena_s {
|
||||
|
||||
uint64_t prof_accumbytes;
|
||||
|
||||
/* List of dirty-page-containing chunks this arena manages. */
|
||||
ql_head(arena_chunk_t) chunks_dirty;
|
||||
dss_prec_t dss_prec;
|
||||
|
||||
/* Tree of dirty-page-containing chunks this arena manages. */
|
||||
arena_chunk_tree_t chunks_dirty;
|
||||
|
||||
/*
|
||||
* In order to avoid rapid chunk allocation/deallocation when an arena
|
||||
@ -367,18 +373,9 @@ struct arena_s {
|
||||
|
||||
/*
|
||||
* Size/address-ordered trees of this arena's available runs. The trees
|
||||
* are used for first-best-fit run allocation. The dirty tree contains
|
||||
* runs with dirty pages (i.e. very likely to have been touched and
|
||||
* therefore have associated physical pages), whereas the clean tree
|
||||
* contains runs with pages that either have no associated physical
|
||||
* pages, or have pages that the kernel may recycle at any time due to
|
||||
* previous madvise(2) calls. The dirty tree is used in preference to
|
||||
* the clean tree for allocations, because using dirty pages reduces
|
||||
* the amount of dirty purging necessary to keep the active:dirty page
|
||||
* ratio below the purge threshold.
|
||||
* are used for first-best-fit run allocation.
|
||||
*/
|
||||
arena_avail_tree_t runs_avail_clean;
|
||||
arena_avail_tree_t runs_avail_dirty;
|
||||
arena_avail_tree_t runs_avail;
|
||||
|
||||
/* bins is used to store trees of free regions. */
|
||||
arena_bin_t bins[NBINS];
|
||||
@ -422,13 +419,16 @@ void arena_dalloc_small(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
||||
void arena_dalloc_large_locked(arena_t *arena, arena_chunk_t *chunk,
|
||||
void *ptr);
|
||||
void arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk, void *ptr);
|
||||
void arena_stats_merge(arena_t *arena, size_t *nactive, size_t *ndirty,
|
||||
arena_stats_t *astats, malloc_bin_stats_t *bstats,
|
||||
malloc_large_stats_t *lstats);
|
||||
void *arena_ralloc_no_move(void *ptr, size_t oldsize, size_t size,
|
||||
size_t extra, bool zero);
|
||||
void *arena_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
|
||||
size_t alignment, bool zero, bool try_tcache);
|
||||
void *arena_ralloc(arena_t *arena, void *ptr, size_t oldsize, size_t size,
|
||||
size_t extra, size_t alignment, bool zero, bool try_tcache_alloc,
|
||||
bool try_tcache_dalloc);
|
||||
dss_prec_t arena_dss_prec_get(arena_t *arena);
|
||||
void arena_dss_prec_set(arena_t *arena, dss_prec_t dss_prec);
|
||||
void arena_stats_merge(arena_t *arena, const char **dss, size_t *nactive,
|
||||
size_t *ndirty, arena_stats_t *astats, malloc_bin_stats_t *bstats,
|
||||
malloc_large_stats_t *lstats);
|
||||
bool arena_new(arena_t *arena, unsigned ind);
|
||||
void arena_boot(void);
|
||||
void arena_prefork(arena_t *arena);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#ifdef JEMALLOC_H_EXTERNS
|
||||
|
||||
extern size_t opt_lg_chunk;
|
||||
extern const char *opt_dss;
|
||||
|
||||
/* Protects stats_chunks; currently not used for any other purpose. */
|
||||
extern malloc_mutex_t chunks_mtx;
|
||||
@ -42,9 +43,14 @@ extern size_t chunk_npages;
|
||||
extern size_t map_bias; /* Number of arena chunk header pages. */
|
||||
extern size_t arena_maxclass; /* Max size class for arenas. */
|
||||
|
||||
void *chunk_alloc(size_t size, size_t alignment, bool base, bool *zero);
|
||||
void *chunk_alloc(size_t size, size_t alignment, bool base, bool *zero,
|
||||
dss_prec_t dss_prec);
|
||||
void chunk_unmap(void *chunk, size_t size);
|
||||
void chunk_dealloc(void *chunk, size_t size, bool unmap);
|
||||
bool chunk_boot(void);
|
||||
void chunk_prefork(void);
|
||||
void chunk_postfork_parent(void);
|
||||
void chunk_postfork_child(void);
|
||||
|
||||
#endif /* JEMALLOC_H_EXTERNS */
|
||||
/******************************************************************************/
|
||||
|
@ -1,14 +1,28 @@
|
||||
/******************************************************************************/
|
||||
#ifdef JEMALLOC_H_TYPES
|
||||
|
||||
typedef enum {
|
||||
dss_prec_disabled = 0,
|
||||
dss_prec_primary = 1,
|
||||
dss_prec_secondary = 2,
|
||||
|
||||
dss_prec_limit = 3
|
||||
} dss_prec_t ;
|
||||
#define DSS_PREC_DEFAULT dss_prec_secondary
|
||||
#define DSS_DEFAULT "secondary"
|
||||
|
||||
#endif /* JEMALLOC_H_TYPES */
|
||||
/******************************************************************************/
|
||||
#ifdef JEMALLOC_H_STRUCTS
|
||||
|
||||
extern const char *dss_prec_names[];
|
||||
|
||||
#endif /* JEMALLOC_H_STRUCTS */
|
||||
/******************************************************************************/
|
||||
#ifdef JEMALLOC_H_EXTERNS
|
||||
|
||||
dss_prec_t chunk_dss_prec_get(void);
|
||||
bool chunk_dss_prec_set(dss_prec_t dss_prec);
|
||||
void *chunk_alloc_dss(size_t size, size_t alignment, bool *zero);
|
||||
bool chunk_in_dss(void *chunk);
|
||||
bool chunk_dss_boot(void);
|
||||
|
@ -9,7 +9,7 @@
|
||||
/******************************************************************************/
|
||||
#ifdef JEMALLOC_H_EXTERNS
|
||||
|
||||
void pages_purge(void *addr, size_t length);
|
||||
bool pages_purge(void *addr, size_t length);
|
||||
|
||||
void *chunk_alloc_mmap(size_t size, size_t alignment, bool *zero);
|
||||
bool chunk_dealloc_mmap(void *chunk, size_t size);
|
||||
|
@ -33,6 +33,7 @@ struct ctl_indexed_node_s {
|
||||
struct ctl_arena_stats_s {
|
||||
bool initialized;
|
||||
unsigned nthreads;
|
||||
const char *dss;
|
||||
size_t pactive;
|
||||
size_t pdirty;
|
||||
arena_stats_t astats;
|
||||
@ -61,6 +62,7 @@ struct ctl_stats_s {
|
||||
uint64_t nmalloc; /* huge_nmalloc */
|
||||
uint64_t ndalloc; /* huge_ndalloc */
|
||||
} huge;
|
||||
unsigned narenas;
|
||||
ctl_arena_stats_t *arenas; /* (narenas + 1) elements. */
|
||||
};
|
||||
|
||||
@ -75,6 +77,9 @@ int ctl_nametomib(const char *name, size_t *mibp, size_t *miblenp);
|
||||
int ctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
||||
void *newp, size_t newlen);
|
||||
bool ctl_boot(void);
|
||||
void ctl_prefork(void);
|
||||
void ctl_postfork_parent(void);
|
||||
void ctl_postfork_child(void);
|
||||
|
||||
#define xmallctl(name, oldp, oldlenp, newp, newlen) do { \
|
||||
if (je_mallctl(name, oldp, oldlenp, newp, newlen) \
|
||||
|
@ -23,6 +23,9 @@ struct extent_node_s {
|
||||
|
||||
/* Total region size. */
|
||||
size_t size;
|
||||
|
||||
/* True if zero-filled; used by chunk recycling code. */
|
||||
bool zeroed;
|
||||
};
|
||||
typedef rb_tree(extent_node_t) extent_tree_t;
|
||||
|
||||
|
@ -22,7 +22,7 @@ void *huge_palloc(size_t size, size_t alignment, bool zero);
|
||||
void *huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size,
|
||||
size_t extra);
|
||||
void *huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
|
||||
size_t alignment, bool zero);
|
||||
size_t alignment, bool zero, bool try_tcache_dalloc);
|
||||
void huge_dalloc(void *ptr, bool unmap);
|
||||
size_t huge_salloc(const void *ptr);
|
||||
prof_ctx_t *huge_prof_ctx_get(const void *ptr);
|
||||
|
@ -270,6 +270,9 @@ static const bool config_ivsalloc =
|
||||
# ifdef __arm__
|
||||
# define LG_QUANTUM 3
|
||||
# endif
|
||||
# ifdef __hppa__
|
||||
# define LG_QUANTUM 4
|
||||
# endif
|
||||
# ifdef __mips__
|
||||
# define LG_QUANTUM 3
|
||||
# endif
|
||||
@ -424,6 +427,7 @@ static const bool config_ivsalloc =
|
||||
VALGRIND_FREELIKE_BLOCK(ptr, rzsize); \
|
||||
} while (0)
|
||||
#else
|
||||
#define RUNNING_ON_VALGRIND ((unsigned)0)
|
||||
#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)
|
||||
#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB)
|
||||
#define VALGRIND_FREELIKE_BLOCK(addr, rzB)
|
||||
@ -510,13 +514,19 @@ extern size_t opt_narenas;
|
||||
/* Number of CPUs. */
|
||||
extern unsigned ncpus;
|
||||
|
||||
extern malloc_mutex_t arenas_lock; /* Protects arenas initialization. */
|
||||
/* Protects arenas initialization (arenas, arenas_total). */
|
||||
extern malloc_mutex_t arenas_lock;
|
||||
/*
|
||||
* Arenas that are used to service external requests. Not all elements of the
|
||||
* arenas array are necessarily used; arenas are created lazily as needed.
|
||||
*
|
||||
* arenas[0..narenas_auto) are used for automatic multiplexing of threads and
|
||||
* arenas. arenas[narenas_auto..narenas_total) are only used if the application
|
||||
* takes some action to create them and allocate from them.
|
||||
*/
|
||||
extern arena_t **arenas;
|
||||
extern unsigned narenas;
|
||||
extern unsigned narenas_total;
|
||||
extern unsigned narenas_auto; /* Read-only after initialization. */
|
||||
|
||||
arena_t *arenas_extend(unsigned ind);
|
||||
void arenas_cleanup(void *arg);
|
||||
@ -571,6 +581,7 @@ malloc_tsd_protos(JEMALLOC_ATTR(unused), arenas, arena_t *)
|
||||
|
||||
size_t s2u(size_t size);
|
||||
size_t sa2u(size_t size, size_t alignment);
|
||||
unsigned narenas_total_get(void);
|
||||
arena_t *choose_arena(arena_t *arena);
|
||||
#endif
|
||||
|
||||
@ -675,6 +686,18 @@ sa2u(size_t size, size_t alignment)
|
||||
}
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE unsigned
|
||||
narenas_total_get(void)
|
||||
{
|
||||
unsigned narenas;
|
||||
|
||||
malloc_mutex_lock(&arenas_lock);
|
||||
narenas = narenas_total;
|
||||
malloc_mutex_unlock(&arenas_lock);
|
||||
|
||||
return (narenas);
|
||||
}
|
||||
|
||||
/* Choose an arena based on a per-thread value. */
|
||||
JEMALLOC_INLINE arena_t *
|
||||
choose_arena(arena_t *arena)
|
||||
@ -710,15 +733,24 @@ choose_arena(arena_t *arena)
|
||||
#include "jemalloc/internal/quarantine.h"
|
||||
|
||||
#ifndef JEMALLOC_ENABLE_INLINE
|
||||
void *imallocx(size_t size, bool try_tcache, arena_t *arena);
|
||||
void *imalloc(size_t size);
|
||||
void *icallocx(size_t size, bool try_tcache, arena_t *arena);
|
||||
void *icalloc(size_t size);
|
||||
void *ipallocx(size_t usize, size_t alignment, bool zero, bool try_tcache,
|
||||
arena_t *arena);
|
||||
void *ipalloc(size_t usize, size_t alignment, bool zero);
|
||||
size_t isalloc(const void *ptr, bool demote);
|
||||
size_t ivsalloc(const void *ptr, bool demote);
|
||||
size_t u2rz(size_t usize);
|
||||
size_t p2rz(const void *ptr);
|
||||
void idallocx(void *ptr, bool try_tcache);
|
||||
void idalloc(void *ptr);
|
||||
void iqallocx(void *ptr, bool try_tcache);
|
||||
void iqalloc(void *ptr);
|
||||
void *irallocx(void *ptr, size_t size, size_t extra, size_t alignment,
|
||||
bool zero, bool no_move, bool try_tcache_alloc, bool try_tcache_dalloc,
|
||||
arena_t *arena);
|
||||
void *iralloc(void *ptr, size_t size, size_t extra, size_t alignment,
|
||||
bool zero, bool no_move);
|
||||
malloc_tsd_protos(JEMALLOC_ATTR(unused), thread_allocated, thread_allocated_t)
|
||||
@ -726,29 +758,44 @@ malloc_tsd_protos(JEMALLOC_ATTR(unused), thread_allocated, thread_allocated_t)
|
||||
|
||||
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_))
|
||||
JEMALLOC_INLINE void *
|
||||
imalloc(size_t size)
|
||||
imallocx(size_t size, bool try_tcache, arena_t *arena)
|
||||
{
|
||||
|
||||
assert(size != 0);
|
||||
|
||||
if (size <= arena_maxclass)
|
||||
return (arena_malloc(NULL, size, false, true));
|
||||
return (arena_malloc(arena, size, false, try_tcache));
|
||||
else
|
||||
return (huge_malloc(size, false));
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void *
|
||||
imalloc(size_t size)
|
||||
{
|
||||
|
||||
return (imallocx(size, true, NULL));
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void *
|
||||
icallocx(size_t size, bool try_tcache, arena_t *arena)
|
||||
{
|
||||
|
||||
if (size <= arena_maxclass)
|
||||
return (arena_malloc(arena, size, true, try_tcache));
|
||||
else
|
||||
return (huge_malloc(size, true));
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void *
|
||||
icalloc(size_t size)
|
||||
{
|
||||
|
||||
if (size <= arena_maxclass)
|
||||
return (arena_malloc(NULL, size, true, true));
|
||||
else
|
||||
return (huge_malloc(size, true));
|
||||
return (icallocx(size, true, NULL));
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void *
|
||||
ipalloc(size_t usize, size_t alignment, bool zero)
|
||||
ipallocx(size_t usize, size_t alignment, bool zero, bool try_tcache,
|
||||
arena_t *arena)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
@ -756,11 +803,11 @@ ipalloc(size_t usize, size_t alignment, bool zero)
|
||||
assert(usize == sa2u(usize, alignment));
|
||||
|
||||
if (usize <= arena_maxclass && alignment <= PAGE)
|
||||
ret = arena_malloc(NULL, usize, zero, true);
|
||||
ret = arena_malloc(arena, usize, zero, try_tcache);
|
||||
else {
|
||||
if (usize <= arena_maxclass) {
|
||||
ret = arena_palloc(choose_arena(NULL), usize, alignment,
|
||||
zero);
|
||||
ret = arena_palloc(choose_arena(arena), usize,
|
||||
alignment, zero);
|
||||
} else if (alignment <= chunksize)
|
||||
ret = huge_malloc(usize, zero);
|
||||
else
|
||||
@ -771,6 +818,13 @@ ipalloc(size_t usize, size_t alignment, bool zero)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void *
|
||||
ipalloc(size_t usize, size_t alignment, bool zero)
|
||||
{
|
||||
|
||||
return (ipallocx(usize, alignment, zero, true, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
* Typical usage:
|
||||
* void *ptr = [...]
|
||||
@ -829,7 +883,7 @@ p2rz(const void *ptr)
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void
|
||||
idalloc(void *ptr)
|
||||
idallocx(void *ptr, bool try_tcache)
|
||||
{
|
||||
arena_chunk_t *chunk;
|
||||
|
||||
@ -837,24 +891,38 @@ idalloc(void *ptr)
|
||||
|
||||
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
||||
if (chunk != ptr)
|
||||
arena_dalloc(chunk->arena, chunk, ptr, true);
|
||||
arena_dalloc(chunk->arena, chunk, ptr, try_tcache);
|
||||
else
|
||||
huge_dalloc(ptr, true);
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void
|
||||
idalloc(void *ptr)
|
||||
{
|
||||
|
||||
idallocx(ptr, true);
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void
|
||||
iqallocx(void *ptr, bool try_tcache)
|
||||
{
|
||||
|
||||
if (config_fill && opt_quarantine)
|
||||
quarantine(ptr);
|
||||
else
|
||||
idallocx(ptr, try_tcache);
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void
|
||||
iqalloc(void *ptr)
|
||||
{
|
||||
|
||||
if (config_fill && opt_quarantine)
|
||||
quarantine(ptr);
|
||||
else
|
||||
idalloc(ptr);
|
||||
iqallocx(ptr, true);
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void *
|
||||
iralloc(void *ptr, size_t size, size_t extra, size_t alignment, bool zero,
|
||||
bool no_move)
|
||||
irallocx(void *ptr, size_t size, size_t extra, size_t alignment, bool zero,
|
||||
bool no_move, bool try_tcache_alloc, bool try_tcache_dalloc, arena_t *arena)
|
||||
{
|
||||
void *ret;
|
||||
size_t oldsize;
|
||||
@ -877,7 +945,7 @@ iralloc(void *ptr, size_t size, size_t extra, size_t alignment, bool zero,
|
||||
usize = sa2u(size + extra, alignment);
|
||||
if (usize == 0)
|
||||
return (NULL);
|
||||
ret = ipalloc(usize, alignment, zero);
|
||||
ret = ipallocx(usize, alignment, zero, try_tcache_alloc, arena);
|
||||
if (ret == NULL) {
|
||||
if (extra == 0)
|
||||
return (NULL);
|
||||
@ -885,7 +953,8 @@ iralloc(void *ptr, size_t size, size_t extra, size_t alignment, bool zero,
|
||||
usize = sa2u(size, alignment);
|
||||
if (usize == 0)
|
||||
return (NULL);
|
||||
ret = ipalloc(usize, alignment, zero);
|
||||
ret = ipallocx(usize, alignment, zero, try_tcache_alloc,
|
||||
arena);
|
||||
if (ret == NULL)
|
||||
return (NULL);
|
||||
}
|
||||
@ -896,7 +965,7 @@ iralloc(void *ptr, size_t size, size_t extra, size_t alignment, bool zero,
|
||||
*/
|
||||
copysize = (size < oldsize) ? size : oldsize;
|
||||
memcpy(ret, ptr, copysize);
|
||||
iqalloc(ptr);
|
||||
iqallocx(ptr, try_tcache_dalloc);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -910,15 +979,25 @@ iralloc(void *ptr, size_t size, size_t extra, size_t alignment, bool zero,
|
||||
}
|
||||
} else {
|
||||
if (size + extra <= arena_maxclass) {
|
||||
return (arena_ralloc(ptr, oldsize, size, extra,
|
||||
alignment, zero, true));
|
||||
return (arena_ralloc(arena, ptr, oldsize, size, extra,
|
||||
alignment, zero, try_tcache_alloc,
|
||||
try_tcache_dalloc));
|
||||
} else {
|
||||
return (huge_ralloc(ptr, oldsize, size, extra,
|
||||
alignment, zero));
|
||||
alignment, zero, try_tcache_dalloc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JEMALLOC_INLINE void *
|
||||
iralloc(void *ptr, size_t size, size_t extra, size_t alignment, bool zero,
|
||||
bool no_move)
|
||||
{
|
||||
|
||||
return (irallocx(ptr, size, extra, alignment, zero, no_move, true, true,
|
||||
NULL));
|
||||
}
|
||||
|
||||
malloc_tsd_externs(thread_allocated, thread_allocated_t)
|
||||
malloc_tsd_funcs(JEMALLOC_INLINE, thread_allocated, thread_allocated_t,
|
||||
THREAD_ALLOCATED_INITIALIZER, malloc_tsd_no_cleanup)
|
||||
|
@ -12,6 +12,8 @@
|
||||
#define arena_dalloc_large JEMALLOC_N(arena_dalloc_large)
|
||||
#define arena_dalloc_large_locked JEMALLOC_N(arena_dalloc_large_locked)
|
||||
#define arena_dalloc_small JEMALLOC_N(arena_dalloc_small)
|
||||
#define arena_dss_prec_get JEMALLOC_N(arena_dss_prec_get)
|
||||
#define arena_dss_prec_set JEMALLOC_N(arena_dss_prec_set)
|
||||
#define arena_malloc JEMALLOC_N(arena_malloc)
|
||||
#define arena_malloc_large JEMALLOC_N(arena_malloc_large)
|
||||
#define arena_malloc_small JEMALLOC_N(arena_malloc_small)
|
||||
@ -51,14 +53,13 @@
|
||||
#define arena_stats_merge JEMALLOC_N(arena_stats_merge)
|
||||
#define arena_tcache_fill_small JEMALLOC_N(arena_tcache_fill_small)
|
||||
#define arenas JEMALLOC_N(arenas)
|
||||
#define arenas_bin_i_index JEMALLOC_N(arenas_bin_i_index)
|
||||
#define arenas_booted JEMALLOC_N(arenas_booted)
|
||||
#define arenas_cleanup JEMALLOC_N(arenas_cleanup)
|
||||
#define arenas_extend JEMALLOC_N(arenas_extend)
|
||||
#define arenas_initialized JEMALLOC_N(arenas_initialized)
|
||||
#define arenas_lock JEMALLOC_N(arenas_lock)
|
||||
#define arenas_lrun_i_index JEMALLOC_N(arenas_lrun_i_index)
|
||||
#define arenas_tls JEMALLOC_N(arenas_tls)
|
||||
#define arenas_tsd JEMALLOC_N(arenas_tsd)
|
||||
#define arenas_tsd_boot JEMALLOC_N(arenas_tsd_boot)
|
||||
#define arenas_tsd_cleanup_wrapper JEMALLOC_N(arenas_tsd_cleanup_wrapper)
|
||||
#define arenas_tsd_get JEMALLOC_N(arenas_tsd_get)
|
||||
@ -101,9 +102,15 @@
|
||||
#define chunk_dss_boot JEMALLOC_N(chunk_dss_boot)
|
||||
#define chunk_dss_postfork_child JEMALLOC_N(chunk_dss_postfork_child)
|
||||
#define chunk_dss_postfork_parent JEMALLOC_N(chunk_dss_postfork_parent)
|
||||
#define chunk_dss_prec_get JEMALLOC_N(chunk_dss_prec_get)
|
||||
#define chunk_dss_prec_set JEMALLOC_N(chunk_dss_prec_set)
|
||||
#define chunk_dss_prefork JEMALLOC_N(chunk_dss_prefork)
|
||||
#define chunk_in_dss JEMALLOC_N(chunk_in_dss)
|
||||
#define chunk_npages JEMALLOC_N(chunk_npages)
|
||||
#define chunk_postfork_child JEMALLOC_N(chunk_postfork_child)
|
||||
#define chunk_postfork_parent JEMALLOC_N(chunk_postfork_parent)
|
||||
#define chunk_prefork JEMALLOC_N(chunk_prefork)
|
||||
#define chunk_unmap JEMALLOC_N(chunk_unmap)
|
||||
#define chunks_mtx JEMALLOC_N(chunks_mtx)
|
||||
#define chunks_rtree JEMALLOC_N(chunks_rtree)
|
||||
#define chunksize JEMALLOC_N(chunksize)
|
||||
@ -129,6 +136,10 @@
|
||||
#define ctl_bymib JEMALLOC_N(ctl_bymib)
|
||||
#define ctl_byname JEMALLOC_N(ctl_byname)
|
||||
#define ctl_nametomib JEMALLOC_N(ctl_nametomib)
|
||||
#define ctl_postfork_child JEMALLOC_N(ctl_postfork_child)
|
||||
#define ctl_postfork_parent JEMALLOC_N(ctl_postfork_parent)
|
||||
#define ctl_prefork JEMALLOC_N(ctl_prefork)
|
||||
#define dss_prec_names JEMALLOC_N(dss_prec_names)
|
||||
#define extent_tree_ad_first JEMALLOC_N(extent_tree_ad_first)
|
||||
#define extent_tree_ad_insert JEMALLOC_N(extent_tree_ad_insert)
|
||||
#define extent_tree_ad_iter JEMALLOC_N(extent_tree_ad_iter)
|
||||
@ -161,6 +172,7 @@
|
||||
#define extent_tree_szad_reverse_iter_recurse JEMALLOC_N(extent_tree_szad_reverse_iter_recurse)
|
||||
#define extent_tree_szad_reverse_iter_start JEMALLOC_N(extent_tree_szad_reverse_iter_start)
|
||||
#define extent_tree_szad_search JEMALLOC_N(extent_tree_szad_search)
|
||||
#define get_errno JEMALLOC_N(get_errno)
|
||||
#define hash JEMALLOC_N(hash)
|
||||
#define huge_allocated JEMALLOC_N(huge_allocated)
|
||||
#define huge_boot JEMALLOC_N(huge_boot)
|
||||
@ -180,11 +192,17 @@
|
||||
#define huge_salloc JEMALLOC_N(huge_salloc)
|
||||
#define iallocm JEMALLOC_N(iallocm)
|
||||
#define icalloc JEMALLOC_N(icalloc)
|
||||
#define icallocx JEMALLOC_N(icallocx)
|
||||
#define idalloc JEMALLOC_N(idalloc)
|
||||
#define idallocx JEMALLOC_N(idallocx)
|
||||
#define imalloc JEMALLOC_N(imalloc)
|
||||
#define imallocx JEMALLOC_N(imallocx)
|
||||
#define ipalloc JEMALLOC_N(ipalloc)
|
||||
#define ipallocx JEMALLOC_N(ipallocx)
|
||||
#define iqalloc JEMALLOC_N(iqalloc)
|
||||
#define iqallocx JEMALLOC_N(iqallocx)
|
||||
#define iralloc JEMALLOC_N(iralloc)
|
||||
#define irallocx JEMALLOC_N(irallocx)
|
||||
#define isalloc JEMALLOC_N(isalloc)
|
||||
#define ivsalloc JEMALLOC_N(ivsalloc)
|
||||
#define jemalloc_postfork_child JEMALLOC_N(jemalloc_postfork_child)
|
||||
@ -211,7 +229,9 @@
|
||||
#define map_bias JEMALLOC_N(map_bias)
|
||||
#define mb_write JEMALLOC_N(mb_write)
|
||||
#define mutex_boot JEMALLOC_N(mutex_boot)
|
||||
#define narenas JEMALLOC_N(narenas)
|
||||
#define narenas_auto JEMALLOC_N(narenas_auto)
|
||||
#define narenas_total JEMALLOC_N(narenas_total)
|
||||
#define narenas_total_get JEMALLOC_N(narenas_total_get)
|
||||
#define ncpus JEMALLOC_N(ncpus)
|
||||
#define nhbins JEMALLOC_N(nhbins)
|
||||
#define opt_abort JEMALLOC_N(opt_abort)
|
||||
@ -253,6 +273,9 @@
|
||||
#define prof_lookup JEMALLOC_N(prof_lookup)
|
||||
#define prof_malloc JEMALLOC_N(prof_malloc)
|
||||
#define prof_mdump JEMALLOC_N(prof_mdump)
|
||||
#define prof_postfork_child JEMALLOC_N(prof_postfork_child)
|
||||
#define prof_postfork_parent JEMALLOC_N(prof_postfork_parent)
|
||||
#define prof_prefork JEMALLOC_N(prof_prefork)
|
||||
#define prof_promote JEMALLOC_N(prof_promote)
|
||||
#define prof_realloc JEMALLOC_N(prof_realloc)
|
||||
#define prof_sample_accum_update JEMALLOC_N(prof_sample_accum_update)
|
||||
@ -263,6 +286,7 @@
|
||||
#define prof_tdata_init JEMALLOC_N(prof_tdata_init)
|
||||
#define prof_tdata_initialized JEMALLOC_N(prof_tdata_initialized)
|
||||
#define prof_tdata_tls JEMALLOC_N(prof_tdata_tls)
|
||||
#define prof_tdata_tsd JEMALLOC_N(prof_tdata_tsd)
|
||||
#define prof_tdata_tsd_boot JEMALLOC_N(prof_tdata_tsd_boot)
|
||||
#define prof_tdata_tsd_cleanup_wrapper JEMALLOC_N(prof_tdata_tsd_cleanup_wrapper)
|
||||
#define prof_tdata_tsd_get JEMALLOC_N(prof_tdata_tsd_get)
|
||||
@ -277,12 +301,13 @@
|
||||
#define rtree_get JEMALLOC_N(rtree_get)
|
||||
#define rtree_get_locked JEMALLOC_N(rtree_get_locked)
|
||||
#define rtree_new JEMALLOC_N(rtree_new)
|
||||
#define rtree_postfork_child JEMALLOC_N(rtree_postfork_child)
|
||||
#define rtree_postfork_parent JEMALLOC_N(rtree_postfork_parent)
|
||||
#define rtree_prefork JEMALLOC_N(rtree_prefork)
|
||||
#define rtree_set JEMALLOC_N(rtree_set)
|
||||
#define s2u JEMALLOC_N(s2u)
|
||||
#define sa2u JEMALLOC_N(sa2u)
|
||||
#define stats_arenas_i_bins_j_index JEMALLOC_N(stats_arenas_i_bins_j_index)
|
||||
#define stats_arenas_i_index JEMALLOC_N(stats_arenas_i_index)
|
||||
#define stats_arenas_i_lruns_j_index JEMALLOC_N(stats_arenas_i_lruns_j_index)
|
||||
#define set_errno JEMALLOC_N(set_errno)
|
||||
#define stats_cactive JEMALLOC_N(stats_cactive)
|
||||
#define stats_cactive_add JEMALLOC_N(stats_cactive_add)
|
||||
#define stats_cactive_get JEMALLOC_N(stats_cactive_get)
|
||||
@ -310,6 +335,7 @@
|
||||
#define tcache_enabled_initialized JEMALLOC_N(tcache_enabled_initialized)
|
||||
#define tcache_enabled_set JEMALLOC_N(tcache_enabled_set)
|
||||
#define tcache_enabled_tls JEMALLOC_N(tcache_enabled_tls)
|
||||
#define tcache_enabled_tsd JEMALLOC_N(tcache_enabled_tsd)
|
||||
#define tcache_enabled_tsd_boot JEMALLOC_N(tcache_enabled_tsd_boot)
|
||||
#define tcache_enabled_tsd_cleanup_wrapper JEMALLOC_N(tcache_enabled_tsd_cleanup_wrapper)
|
||||
#define tcache_enabled_tsd_get JEMALLOC_N(tcache_enabled_tsd_get)
|
||||
@ -324,6 +350,7 @@
|
||||
#define tcache_stats_merge JEMALLOC_N(tcache_stats_merge)
|
||||
#define tcache_thread_cleanup JEMALLOC_N(tcache_thread_cleanup)
|
||||
#define tcache_tls JEMALLOC_N(tcache_tls)
|
||||
#define tcache_tsd JEMALLOC_N(tcache_tsd)
|
||||
#define tcache_tsd_boot JEMALLOC_N(tcache_tsd_boot)
|
||||
#define tcache_tsd_cleanup_wrapper JEMALLOC_N(tcache_tsd_cleanup_wrapper)
|
||||
#define tcache_tsd_get JEMALLOC_N(tcache_tsd_get)
|
||||
@ -331,6 +358,7 @@
|
||||
#define thread_allocated_booted JEMALLOC_N(thread_allocated_booted)
|
||||
#define thread_allocated_initialized JEMALLOC_N(thread_allocated_initialized)
|
||||
#define thread_allocated_tls JEMALLOC_N(thread_allocated_tls)
|
||||
#define thread_allocated_tsd JEMALLOC_N(thread_allocated_tsd)
|
||||
#define thread_allocated_tsd_boot JEMALLOC_N(thread_allocated_tsd_boot)
|
||||
#define thread_allocated_tsd_cleanup_wrapper JEMALLOC_N(thread_allocated_tsd_cleanup_wrapper)
|
||||
#define thread_allocated_tsd_get JEMALLOC_N(thread_allocated_tsd_get)
|
||||
|
@ -223,6 +223,9 @@ void prof_tdata_cleanup(void *arg);
|
||||
void prof_boot0(void);
|
||||
void prof_boot1(void);
|
||||
bool prof_boot2(void);
|
||||
void prof_prefork(void);
|
||||
void prof_postfork_parent(void);
|
||||
void prof_postfork_child(void);
|
||||
|
||||
#endif /* JEMALLOC_H_EXTERNS */
|
||||
/******************************************************************************/
|
||||
@ -506,7 +509,7 @@ prof_realloc(const void *ptr, size_t size, prof_thr_cnt_t *cnt,
|
||||
if ((uintptr_t)cnt > (uintptr_t)1U) {
|
||||
prof_ctx_set(ptr, cnt->ctx);
|
||||
cnt->epoch++;
|
||||
} else
|
||||
} else if (ptr != NULL)
|
||||
prof_ctx_set(ptr, (prof_ctx_t *)(uintptr_t)1U);
|
||||
/*********/
|
||||
mb_write();
|
||||
|
@ -36,6 +36,9 @@ struct rtree_s {
|
||||
#ifdef JEMALLOC_H_EXTERNS
|
||||
|
||||
rtree_t *rtree_new(unsigned bits);
|
||||
void rtree_prefork(rtree_t *rtree);
|
||||
void rtree_postfork_parent(rtree_t *rtree);
|
||||
void rtree_postfork_child(rtree_t *rtree);
|
||||
|
||||
#endif /* JEMALLOC_H_EXTERNS */
|
||||
/******************************************************************************/
|
||||
|
@ -7,12 +7,12 @@ extern "C" {
|
||||
#include <limits.h>
|
||||
#include <strings.h>
|
||||
|
||||
#define JEMALLOC_VERSION "3.0.0-0-gfc9b1dbf69f59d7ecfc4ac68da9847e017e1d046"
|
||||
#define JEMALLOC_VERSION "3.2.0-0-g87499f6748ebe4817571e817e9f680ccb5bf54a9"
|
||||
#define JEMALLOC_VERSION_MAJOR 3
|
||||
#define JEMALLOC_VERSION_MINOR 0
|
||||
#define JEMALLOC_VERSION_MINOR 2
|
||||
#define JEMALLOC_VERSION_BUGFIX 0
|
||||
#define JEMALLOC_VERSION_NREV 0
|
||||
#define JEMALLOC_VERSION_GID "fc9b1dbf69f59d7ecfc4ac68da9847e017e1d046"
|
||||
#define JEMALLOC_VERSION_GID "87499f6748ebe4817571e817e9f680ccb5bf54a9"
|
||||
|
||||
#include "jemalloc_defs.h"
|
||||
#include "jemalloc_FreeBSD.h"
|
||||
@ -26,6 +26,8 @@ extern "C" {
|
||||
#endif
|
||||
#define ALLOCM_ZERO ((int)0x40)
|
||||
#define ALLOCM_NO_MOVE ((int)0x80)
|
||||
/* Bias arena index bits so that 0 encodes "ALLOCM_ARENA() unspecified". */
|
||||
#define ALLOCM_ARENA(a) ((int)(((a)+1) << 8))
|
||||
|
||||
#define ALLOCM_SUCCESS 0
|
||||
#define ALLOCM_ERR_OOM 1
|
||||
@ -60,7 +62,8 @@ JEMALLOC_EXPORT void * je_memalign(size_t alignment, size_t size)
|
||||
JEMALLOC_EXPORT void * je_valloc(size_t size) JEMALLOC_ATTR(malloc);
|
||||
#endif
|
||||
|
||||
JEMALLOC_EXPORT size_t je_malloc_usable_size(const void *ptr);
|
||||
JEMALLOC_EXPORT size_t je_malloc_usable_size(
|
||||
JEMALLOC_USABLE_SIZE_CONST void *ptr);
|
||||
JEMALLOC_EXPORT void je_malloc_stats_print(void (*write_cb)(void *,
|
||||
const char *), void *je_cbopaque, const char *opts);
|
||||
JEMALLOC_EXPORT int je_mallctl(const char *name, void *oldp,
|
||||
|
@ -222,6 +222,15 @@
|
||||
/* #undef JEMALLOC_OVERRIDE_MEMALIGN */
|
||||
#define JEMALLOC_OVERRIDE_VALLOC
|
||||
|
||||
/*
|
||||
* At least Linux omits the "const" in:
|
||||
*
|
||||
* size_t malloc_usable_size(const void *ptr);
|
||||
*
|
||||
* Match the operating system's prototype.
|
||||
*/
|
||||
#define JEMALLOC_USABLE_SIZE_CONST const
|
||||
|
||||
/*
|
||||
* Darwin (OS X) uses zones to work around Mach-O symbol override shortcomings.
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,8 @@ base_pages_alloc(size_t minsize)
|
||||
assert(minsize != 0);
|
||||
csize = CHUNK_CEILING(minsize);
|
||||
zero = false;
|
||||
base_pages = chunk_alloc(csize, chunksize, true, &zero);
|
||||
base_pages = chunk_alloc(csize, chunksize, true, &zero,
|
||||
chunk_dss_prec_get());
|
||||
if (base_pages == NULL)
|
||||
return (true);
|
||||
base_next_addr = base_pages;
|
||||
|
@ -4,7 +4,8 @@
|
||||
/******************************************************************************/
|
||||
/* Data. */
|
||||
|
||||
size_t opt_lg_chunk = LG_CHUNK_DEFAULT;
|
||||
const char *opt_dss = DSS_DEFAULT;
|
||||
size_t opt_lg_chunk = LG_CHUNK_DEFAULT;
|
||||
|
||||
malloc_mutex_t chunks_mtx;
|
||||
chunk_stats_t stats_chunks;
|
||||
@ -15,8 +16,10 @@ chunk_stats_t stats_chunks;
|
||||
* address space. Depending on function, different tree orderings are needed,
|
||||
* which is why there are two trees with the same contents.
|
||||
*/
|
||||
static extent_tree_t chunks_szad;
|
||||
static extent_tree_t chunks_ad;
|
||||
static extent_tree_t chunks_szad_mmap;
|
||||
static extent_tree_t chunks_ad_mmap;
|
||||
static extent_tree_t chunks_szad_dss;
|
||||
static extent_tree_t chunks_ad_dss;
|
||||
|
||||
rtree_t *chunks_rtree;
|
||||
|
||||
@ -30,19 +33,23 @@ size_t arena_maxclass; /* Max size class for arenas. */
|
||||
/******************************************************************************/
|
||||
/* Function prototypes for non-inline static functions. */
|
||||
|
||||
static void *chunk_recycle(size_t size, size_t alignment, bool base,
|
||||
static void *chunk_recycle(extent_tree_t *chunks_szad,
|
||||
extent_tree_t *chunks_ad, size_t size, size_t alignment, bool base,
|
||||
bool *zero);
|
||||
static void chunk_record(void *chunk, size_t size);
|
||||
static void chunk_record(extent_tree_t *chunks_szad,
|
||||
extent_tree_t *chunks_ad, void *chunk, size_t size);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void *
|
||||
chunk_recycle(size_t size, size_t alignment, bool base, bool *zero)
|
||||
chunk_recycle(extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, size_t size,
|
||||
size_t alignment, bool base, bool *zero)
|
||||
{
|
||||
void *ret;
|
||||
extent_node_t *node;
|
||||
extent_node_t key;
|
||||
size_t alloc_size, leadsize, trailsize;
|
||||
bool zeroed;
|
||||
|
||||
if (base) {
|
||||
/*
|
||||
@ -61,7 +68,7 @@ chunk_recycle(size_t size, size_t alignment, bool base, bool *zero)
|
||||
key.addr = NULL;
|
||||
key.size = alloc_size;
|
||||
malloc_mutex_lock(&chunks_mtx);
|
||||
node = extent_tree_szad_nsearch(&chunks_szad, &key);
|
||||
node = extent_tree_szad_nsearch(chunks_szad, &key);
|
||||
if (node == NULL) {
|
||||
malloc_mutex_unlock(&chunks_mtx);
|
||||
return (NULL);
|
||||
@ -72,13 +79,13 @@ chunk_recycle(size_t size, size_t alignment, bool base, bool *zero)
|
||||
trailsize = node->size - leadsize - size;
|
||||
ret = (void *)((uintptr_t)node->addr + leadsize);
|
||||
/* Remove node from the tree. */
|
||||
extent_tree_szad_remove(&chunks_szad, node);
|
||||
extent_tree_ad_remove(&chunks_ad, node);
|
||||
extent_tree_szad_remove(chunks_szad, node);
|
||||
extent_tree_ad_remove(chunks_ad, node);
|
||||
if (leadsize != 0) {
|
||||
/* Insert the leading space as a smaller chunk. */
|
||||
node->size = leadsize;
|
||||
extent_tree_szad_insert(&chunks_szad, node);
|
||||
extent_tree_ad_insert(&chunks_ad, node);
|
||||
extent_tree_szad_insert(chunks_szad, node);
|
||||
extent_tree_ad_insert(chunks_ad, node);
|
||||
node = NULL;
|
||||
}
|
||||
if (trailsize != 0) {
|
||||
@ -101,23 +108,24 @@ chunk_recycle(size_t size, size_t alignment, bool base, bool *zero)
|
||||
}
|
||||
node->addr = (void *)((uintptr_t)(ret) + size);
|
||||
node->size = trailsize;
|
||||
extent_tree_szad_insert(&chunks_szad, node);
|
||||
extent_tree_ad_insert(&chunks_ad, node);
|
||||
extent_tree_szad_insert(chunks_szad, node);
|
||||
extent_tree_ad_insert(chunks_ad, node);
|
||||
node = NULL;
|
||||
}
|
||||
malloc_mutex_unlock(&chunks_mtx);
|
||||
|
||||
if (node != NULL)
|
||||
zeroed = false;
|
||||
if (node != NULL) {
|
||||
if (node->zeroed) {
|
||||
zeroed = true;
|
||||
*zero = true;
|
||||
}
|
||||
base_node_dealloc(node);
|
||||
#ifdef JEMALLOC_PURGE_MADVISE_DONTNEED
|
||||
/* Pages are zeroed as a side effect of pages_purge(). */
|
||||
*zero = true;
|
||||
#else
|
||||
if (*zero) {
|
||||
}
|
||||
if (zeroed == false && *zero) {
|
||||
VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
|
||||
memset(ret, 0, size);
|
||||
}
|
||||
#endif
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -128,7 +136,8 @@ chunk_recycle(size_t size, size_t alignment, bool base, bool *zero)
|
||||
* advantage of them if they are returned.
|
||||
*/
|
||||
void *
|
||||
chunk_alloc(size_t size, size_t alignment, bool base, bool *zero)
|
||||
chunk_alloc(size_t size, size_t alignment, bool base, bool *zero,
|
||||
dss_prec_t dss_prec)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
@ -137,17 +146,26 @@ chunk_alloc(size_t size, size_t alignment, bool base, bool *zero)
|
||||
assert(alignment != 0);
|
||||
assert((alignment & chunksize_mask) == 0);
|
||||
|
||||
ret = chunk_recycle(size, alignment, base, zero);
|
||||
if (ret != NULL)
|
||||
/* "primary" dss. */
|
||||
if (config_dss && dss_prec == dss_prec_primary) {
|
||||
if ((ret = chunk_recycle(&chunks_szad_dss, &chunks_ad_dss, size,
|
||||
alignment, base, zero)) != NULL)
|
||||
goto label_return;
|
||||
if ((ret = chunk_alloc_dss(size, alignment, zero)) != NULL)
|
||||
goto label_return;
|
||||
}
|
||||
/* mmap. */
|
||||
if ((ret = chunk_recycle(&chunks_szad_mmap, &chunks_ad_mmap, size,
|
||||
alignment, base, zero)) != NULL)
|
||||
goto label_return;
|
||||
|
||||
ret = chunk_alloc_mmap(size, alignment, zero);
|
||||
if (ret != NULL)
|
||||
if ((ret = chunk_alloc_mmap(size, alignment, zero)) != NULL)
|
||||
goto label_return;
|
||||
|
||||
if (config_dss) {
|
||||
ret = chunk_alloc_dss(size, alignment, zero);
|
||||
if (ret != NULL)
|
||||
/* "secondary" dss. */
|
||||
if (config_dss && dss_prec == dss_prec_secondary) {
|
||||
if ((ret = chunk_recycle(&chunks_szad_dss, &chunks_ad_dss, size,
|
||||
alignment, base, zero)) != NULL)
|
||||
goto label_return;
|
||||
if ((ret = chunk_alloc_dss(size, alignment, zero)) != NULL)
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
@ -189,11 +207,13 @@ chunk_alloc(size_t size, size_t alignment, bool base, bool *zero)
|
||||
}
|
||||
|
||||
static void
|
||||
chunk_record(void *chunk, size_t size)
|
||||
chunk_record(extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, void *chunk,
|
||||
size_t size)
|
||||
{
|
||||
bool unzeroed;
|
||||
extent_node_t *xnode, *node, *prev, key;
|
||||
|
||||
pages_purge(chunk, size);
|
||||
unzeroed = pages_purge(chunk, size);
|
||||
|
||||
/*
|
||||
* Allocate a node before acquiring chunks_mtx even though it might not
|
||||
@ -205,7 +225,7 @@ chunk_record(void *chunk, size_t size)
|
||||
|
||||
malloc_mutex_lock(&chunks_mtx);
|
||||
key.addr = (void *)((uintptr_t)chunk + size);
|
||||
node = extent_tree_ad_nsearch(&chunks_ad, &key);
|
||||
node = extent_tree_ad_nsearch(chunks_ad, &key);
|
||||
/* Try to coalesce forward. */
|
||||
if (node != NULL && node->addr == key.addr) {
|
||||
/*
|
||||
@ -213,10 +233,11 @@ chunk_record(void *chunk, size_t size)
|
||||
* not change the position within chunks_ad, so only
|
||||
* remove/insert from/into chunks_szad.
|
||||
*/
|
||||
extent_tree_szad_remove(&chunks_szad, node);
|
||||
extent_tree_szad_remove(chunks_szad, node);
|
||||
node->addr = chunk;
|
||||
node->size += size;
|
||||
extent_tree_szad_insert(&chunks_szad, node);
|
||||
node->zeroed = (node->zeroed && (unzeroed == false));
|
||||
extent_tree_szad_insert(chunks_szad, node);
|
||||
if (xnode != NULL)
|
||||
base_node_dealloc(xnode);
|
||||
} else {
|
||||
@ -234,12 +255,13 @@ chunk_record(void *chunk, size_t size)
|
||||
node = xnode;
|
||||
node->addr = chunk;
|
||||
node->size = size;
|
||||
extent_tree_ad_insert(&chunks_ad, node);
|
||||
extent_tree_szad_insert(&chunks_szad, node);
|
||||
node->zeroed = (unzeroed == false);
|
||||
extent_tree_ad_insert(chunks_ad, node);
|
||||
extent_tree_szad_insert(chunks_szad, node);
|
||||
}
|
||||
|
||||
/* Try to coalesce backward. */
|
||||
prev = extent_tree_ad_prev(&chunks_ad, node);
|
||||
prev = extent_tree_ad_prev(chunks_ad, node);
|
||||
if (prev != NULL && (void *)((uintptr_t)prev->addr + prev->size) ==
|
||||
chunk) {
|
||||
/*
|
||||
@ -247,19 +269,34 @@ chunk_record(void *chunk, size_t size)
|
||||
* not change the position within chunks_ad, so only
|
||||
* remove/insert node from/into chunks_szad.
|
||||
*/
|
||||
extent_tree_szad_remove(&chunks_szad, prev);
|
||||
extent_tree_ad_remove(&chunks_ad, prev);
|
||||
extent_tree_szad_remove(chunks_szad, prev);
|
||||
extent_tree_ad_remove(chunks_ad, prev);
|
||||
|
||||
extent_tree_szad_remove(&chunks_szad, node);
|
||||
extent_tree_szad_remove(chunks_szad, node);
|
||||
node->addr = prev->addr;
|
||||
node->size += prev->size;
|
||||
extent_tree_szad_insert(&chunks_szad, node);
|
||||
node->zeroed = (node->zeroed && prev->zeroed);
|
||||
extent_tree_szad_insert(chunks_szad, node);
|
||||
|
||||
base_node_dealloc(prev);
|
||||
}
|
||||
malloc_mutex_unlock(&chunks_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
chunk_unmap(void *chunk, size_t size)
|
||||
{
|
||||
assert(chunk != NULL);
|
||||
assert(CHUNK_ADDR2BASE(chunk) == chunk);
|
||||
assert(size != 0);
|
||||
assert((size & chunksize_mask) == 0);
|
||||
|
||||
if (config_dss && chunk_in_dss(chunk))
|
||||
chunk_record(&chunks_szad_dss, &chunks_ad_dss, chunk, size);
|
||||
else if (chunk_dealloc_mmap(chunk, size))
|
||||
chunk_record(&chunks_szad_mmap, &chunks_ad_mmap, chunk, size);
|
||||
}
|
||||
|
||||
void
|
||||
chunk_dealloc(void *chunk, size_t size, bool unmap)
|
||||
{
|
||||
@ -273,15 +310,13 @@ chunk_dealloc(void *chunk, size_t size, bool unmap)
|
||||
rtree_set(chunks_rtree, (uintptr_t)chunk, NULL);
|
||||
if (config_stats || config_prof) {
|
||||
malloc_mutex_lock(&chunks_mtx);
|
||||
assert(stats_chunks.curchunks >= (size / chunksize));
|
||||
stats_chunks.curchunks -= (size / chunksize);
|
||||
malloc_mutex_unlock(&chunks_mtx);
|
||||
}
|
||||
|
||||
if (unmap) {
|
||||
if ((config_dss && chunk_in_dss(chunk)) ||
|
||||
chunk_dealloc_mmap(chunk, size))
|
||||
chunk_record(chunk, size);
|
||||
}
|
||||
if (unmap)
|
||||
chunk_unmap(chunk, size);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -301,8 +336,10 @@ chunk_boot(void)
|
||||
}
|
||||
if (config_dss && chunk_dss_boot())
|
||||
return (true);
|
||||
extent_tree_szad_new(&chunks_szad);
|
||||
extent_tree_ad_new(&chunks_ad);
|
||||
extent_tree_szad_new(&chunks_szad_mmap);
|
||||
extent_tree_ad_new(&chunks_ad_mmap);
|
||||
extent_tree_szad_new(&chunks_szad_dss);
|
||||
extent_tree_ad_new(&chunks_ad_dss);
|
||||
if (config_ivsalloc) {
|
||||
chunks_rtree = rtree_new((ZU(1) << (LG_SIZEOF_PTR+3)) -
|
||||
opt_lg_chunk);
|
||||
@ -312,3 +349,33 @@ chunk_boot(void)
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
void
|
||||
chunk_prefork(void)
|
||||
{
|
||||
|
||||
malloc_mutex_lock(&chunks_mtx);
|
||||
if (config_ivsalloc)
|
||||
rtree_prefork(chunks_rtree);
|
||||
chunk_dss_prefork();
|
||||
}
|
||||
|
||||
void
|
||||
chunk_postfork_parent(void)
|
||||
{
|
||||
|
||||
chunk_dss_postfork_parent();
|
||||
if (config_ivsalloc)
|
||||
rtree_postfork_parent(chunks_rtree);
|
||||
malloc_mutex_postfork_parent(&chunks_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
chunk_postfork_child(void)
|
||||
{
|
||||
|
||||
chunk_dss_postfork_child();
|
||||
if (config_ivsalloc)
|
||||
rtree_postfork_child(chunks_rtree);
|
||||
malloc_mutex_postfork_child(&chunks_mtx);
|
||||
}
|
||||
|
@ -3,6 +3,16 @@
|
||||
/******************************************************************************/
|
||||
/* Data. */
|
||||
|
||||
const char *dss_prec_names[] = {
|
||||
"disabled",
|
||||
"primary",
|
||||
"secondary",
|
||||
"N/A"
|
||||
};
|
||||
|
||||
/* Current dss precedence default, used when creating new arenas. */
|
||||
static dss_prec_t dss_prec_default = DSS_PREC_DEFAULT;
|
||||
|
||||
/*
|
||||
* Protects sbrk() calls. This avoids malloc races among threads, though it
|
||||
* does not protect against races with threads that call sbrk() directly.
|
||||
@ -29,6 +39,31 @@ sbrk(intptr_t increment)
|
||||
}
|
||||
#endif
|
||||
|
||||
dss_prec_t
|
||||
chunk_dss_prec_get(void)
|
||||
{
|
||||
dss_prec_t ret;
|
||||
|
||||
if (config_dss == false)
|
||||
return (dss_prec_disabled);
|
||||
malloc_mutex_lock(&dss_mtx);
|
||||
ret = dss_prec_default;
|
||||
malloc_mutex_unlock(&dss_mtx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
bool
|
||||
chunk_dss_prec_set(dss_prec_t dss_prec)
|
||||
{
|
||||
|
||||
if (config_dss == false)
|
||||
return (true);
|
||||
malloc_mutex_lock(&dss_mtx);
|
||||
dss_prec_default = dss_prec;
|
||||
malloc_mutex_unlock(&dss_mtx);
|
||||
return (false);
|
||||
}
|
||||
|
||||
void *
|
||||
chunk_alloc_dss(size_t size, size_t alignment, bool *zero)
|
||||
{
|
||||
@ -88,7 +123,7 @@ chunk_alloc_dss(size_t size, size_t alignment, bool *zero)
|
||||
dss_max = dss_next;
|
||||
malloc_mutex_unlock(&dss_mtx);
|
||||
if (cpad_size != 0)
|
||||
chunk_dealloc(cpad, cpad_size, true);
|
||||
chunk_unmap(cpad, cpad_size);
|
||||
if (*zero) {
|
||||
VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
|
||||
memset(ret, 0, size);
|
||||
|
@ -113,22 +113,30 @@ pages_trim(void *addr, size_t alloc_size, size_t leadsize, size_t size)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
pages_purge(void *addr, size_t length)
|
||||
{
|
||||
bool unzeroed;
|
||||
|
||||
#ifdef _WIN32
|
||||
VirtualAlloc(addr, length, MEM_RESET, PAGE_READWRITE);
|
||||
unzeroed = true;
|
||||
#else
|
||||
# ifdef JEMALLOC_PURGE_MADVISE_DONTNEED
|
||||
# define JEMALLOC_MADV_PURGE MADV_DONTNEED
|
||||
# define JEMALLOC_MADV_ZEROS true
|
||||
# elif defined(JEMALLOC_PURGE_MADVISE_FREE)
|
||||
# define JEMALLOC_MADV_PURGE MADV_FREE
|
||||
# define JEMALLOC_MADV_ZEROS false
|
||||
# else
|
||||
# error "No method defined for purging unused dirty pages."
|
||||
# endif
|
||||
madvise(addr, length, JEMALLOC_MADV_PURGE);
|
||||
int err = madvise(addr, length, JEMALLOC_MADV_PURGE);
|
||||
unzeroed = (JEMALLOC_MADV_ZEROS == false || err != 0);
|
||||
# undef JEMALLOC_MADV_PURGE
|
||||
# undef JEMALLOC_MADV_ZEROS
|
||||
#endif
|
||||
return (unzeroed);
|
||||
}
|
||||
|
||||
static void *
|
||||
|
@ -48,8 +48,8 @@ static int n##_ctl(const size_t *mib, size_t miblen, void *oldp, \
|
||||
size_t *oldlenp, void *newp, size_t newlen);
|
||||
|
||||
#define INDEX_PROTO(n) \
|
||||
const ctl_named_node_t *n##_index(const size_t *mib, size_t miblen, \
|
||||
size_t i);
|
||||
static const ctl_named_node_t *n##_index(const size_t *mib, \
|
||||
size_t miblen, size_t i);
|
||||
|
||||
static bool ctl_arena_init(ctl_arena_stats_t *astats);
|
||||
static void ctl_arena_clear(ctl_arena_stats_t *astats);
|
||||
@ -58,6 +58,7 @@ static void ctl_arena_stats_amerge(ctl_arena_stats_t *cstats,
|
||||
static void ctl_arena_stats_smerge(ctl_arena_stats_t *sstats,
|
||||
ctl_arena_stats_t *astats);
|
||||
static void ctl_arena_refresh(arena_t *arena, unsigned i);
|
||||
static bool ctl_grow(void);
|
||||
static void ctl_refresh(void);
|
||||
static bool ctl_init(void);
|
||||
static int ctl_lookup(const char *name, ctl_node_t const **nodesp,
|
||||
@ -88,6 +89,7 @@ CTL_PROTO(config_utrace)
|
||||
CTL_PROTO(config_valgrind)
|
||||
CTL_PROTO(config_xmalloc)
|
||||
CTL_PROTO(opt_abort)
|
||||
CTL_PROTO(opt_dss)
|
||||
CTL_PROTO(opt_lg_chunk)
|
||||
CTL_PROTO(opt_narenas)
|
||||
CTL_PROTO(opt_lg_dirty_mult)
|
||||
@ -110,6 +112,10 @@ CTL_PROTO(opt_prof_gdump)
|
||||
CTL_PROTO(opt_prof_final)
|
||||
CTL_PROTO(opt_prof_leak)
|
||||
CTL_PROTO(opt_prof_accum)
|
||||
CTL_PROTO(arena_i_purge)
|
||||
static void arena_purge(unsigned arena_ind);
|
||||
CTL_PROTO(arena_i_dss)
|
||||
INDEX_PROTO(arena_i)
|
||||
CTL_PROTO(arenas_bin_i_size)
|
||||
CTL_PROTO(arenas_bin_i_nregs)
|
||||
CTL_PROTO(arenas_bin_i_run_size)
|
||||
@ -125,6 +131,7 @@ CTL_PROTO(arenas_nbins)
|
||||
CTL_PROTO(arenas_nhbins)
|
||||
CTL_PROTO(arenas_nlruns)
|
||||
CTL_PROTO(arenas_purge)
|
||||
CTL_PROTO(arenas_extend)
|
||||
CTL_PROTO(prof_active)
|
||||
CTL_PROTO(prof_dump)
|
||||
CTL_PROTO(prof_interval)
|
||||
@ -158,6 +165,7 @@ CTL_PROTO(stats_arenas_i_lruns_j_nrequests)
|
||||
CTL_PROTO(stats_arenas_i_lruns_j_curruns)
|
||||
INDEX_PROTO(stats_arenas_i_lruns_j)
|
||||
CTL_PROTO(stats_arenas_i_nthreads)
|
||||
CTL_PROTO(stats_arenas_i_dss)
|
||||
CTL_PROTO(stats_arenas_i_pactive)
|
||||
CTL_PROTO(stats_arenas_i_pdirty)
|
||||
CTL_PROTO(stats_arenas_i_mapped)
|
||||
@ -223,6 +231,7 @@ static const ctl_named_node_t config_node[] = {
|
||||
|
||||
static const ctl_named_node_t opt_node[] = {
|
||||
{NAME("abort"), CTL(opt_abort)},
|
||||
{NAME("dss"), CTL(opt_dss)},
|
||||
{NAME("lg_chunk"), CTL(opt_lg_chunk)},
|
||||
{NAME("narenas"), CTL(opt_narenas)},
|
||||
{NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)},
|
||||
@ -247,6 +256,18 @@ static const ctl_named_node_t opt_node[] = {
|
||||
{NAME("prof_accum"), CTL(opt_prof_accum)}
|
||||
};
|
||||
|
||||
static const ctl_named_node_t arena_i_node[] = {
|
||||
{NAME("purge"), CTL(arena_i_purge)},
|
||||
{NAME("dss"), CTL(arena_i_dss)}
|
||||
};
|
||||
static const ctl_named_node_t super_arena_i_node[] = {
|
||||
{NAME(""), CHILD(named, arena_i)}
|
||||
};
|
||||
|
||||
static const ctl_indexed_node_t arena_node[] = {
|
||||
{INDEX(arena_i)}
|
||||
};
|
||||
|
||||
static const ctl_named_node_t arenas_bin_i_node[] = {
|
||||
{NAME("size"), CTL(arenas_bin_i_size)},
|
||||
{NAME("nregs"), CTL(arenas_bin_i_nregs)},
|
||||
@ -282,7 +303,8 @@ static const ctl_named_node_t arenas_node[] = {
|
||||
{NAME("bin"), CHILD(indexed, arenas_bin)},
|
||||
{NAME("nlruns"), CTL(arenas_nlruns)},
|
||||
{NAME("lrun"), CHILD(indexed, arenas_lrun)},
|
||||
{NAME("purge"), CTL(arenas_purge)}
|
||||
{NAME("purge"), CTL(arenas_purge)},
|
||||
{NAME("extend"), CTL(arenas_extend)}
|
||||
};
|
||||
|
||||
static const ctl_named_node_t prof_node[] = {
|
||||
@ -352,6 +374,7 @@ static const ctl_indexed_node_t stats_arenas_i_lruns_node[] = {
|
||||
|
||||
static const ctl_named_node_t stats_arenas_i_node[] = {
|
||||
{NAME("nthreads"), CTL(stats_arenas_i_nthreads)},
|
||||
{NAME("dss"), CTL(stats_arenas_i_dss)},
|
||||
{NAME("pactive"), CTL(stats_arenas_i_pactive)},
|
||||
{NAME("pdirty"), CTL(stats_arenas_i_pdirty)},
|
||||
{NAME("mapped"), CTL(stats_arenas_i_mapped)},
|
||||
@ -387,6 +410,7 @@ static const ctl_named_node_t root_node[] = {
|
||||
{NAME("thread"), CHILD(named, thread)},
|
||||
{NAME("config"), CHILD(named, config)},
|
||||
{NAME("opt"), CHILD(named, opt)},
|
||||
{NAME("arena"), CHILD(indexed, arena)},
|
||||
{NAME("arenas"), CHILD(named, arenas)},
|
||||
{NAME("prof"), CHILD(named, prof)},
|
||||
{NAME("stats"), CHILD(named, stats)}
|
||||
@ -420,6 +444,7 @@ static void
|
||||
ctl_arena_clear(ctl_arena_stats_t *astats)
|
||||
{
|
||||
|
||||
astats->dss = dss_prec_names[dss_prec_limit];
|
||||
astats->pactive = 0;
|
||||
astats->pdirty = 0;
|
||||
if (config_stats) {
|
||||
@ -439,8 +464,8 @@ ctl_arena_stats_amerge(ctl_arena_stats_t *cstats, arena_t *arena)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
arena_stats_merge(arena, &cstats->pactive, &cstats->pdirty,
|
||||
&cstats->astats, cstats->bstats, cstats->lstats);
|
||||
arena_stats_merge(arena, &cstats->dss, &cstats->pactive,
|
||||
&cstats->pdirty, &cstats->astats, cstats->bstats, cstats->lstats);
|
||||
|
||||
for (i = 0; i < NBINS; i++) {
|
||||
cstats->allocated_small += cstats->bstats[i].allocated;
|
||||
@ -500,7 +525,7 @@ static void
|
||||
ctl_arena_refresh(arena_t *arena, unsigned i)
|
||||
{
|
||||
ctl_arena_stats_t *astats = &ctl_stats.arenas[i];
|
||||
ctl_arena_stats_t *sstats = &ctl_stats.arenas[narenas];
|
||||
ctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas];
|
||||
|
||||
ctl_arena_clear(astats);
|
||||
|
||||
@ -518,11 +543,72 @@ ctl_arena_refresh(arena_t *arena, unsigned i)
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
ctl_grow(void)
|
||||
{
|
||||
size_t astats_size;
|
||||
ctl_arena_stats_t *astats;
|
||||
arena_t **tarenas;
|
||||
|
||||
/* Extend arena stats and arenas arrays. */
|
||||
astats_size = (ctl_stats.narenas + 2) * sizeof(ctl_arena_stats_t);
|
||||
if (ctl_stats.narenas == narenas_auto) {
|
||||
/* ctl_stats.arenas and arenas came from base_alloc(). */
|
||||
astats = (ctl_arena_stats_t *)imalloc(astats_size);
|
||||
if (astats == NULL)
|
||||
return (true);
|
||||
memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) *
|
||||
sizeof(ctl_arena_stats_t));
|
||||
|
||||
tarenas = (arena_t **)imalloc((ctl_stats.narenas + 1) *
|
||||
sizeof(arena_t *));
|
||||
if (tarenas == NULL) {
|
||||
idalloc(astats);
|
||||
return (true);
|
||||
}
|
||||
memcpy(tarenas, arenas, ctl_stats.narenas * sizeof(arena_t *));
|
||||
} else {
|
||||
astats = (ctl_arena_stats_t *)iralloc(ctl_stats.arenas,
|
||||
astats_size, 0, 0, false, false);
|
||||
if (astats == NULL)
|
||||
return (true);
|
||||
|
||||
tarenas = (arena_t **)iralloc(arenas, (ctl_stats.narenas + 1) *
|
||||
sizeof(arena_t *), 0, 0, false, false);
|
||||
if (tarenas == NULL)
|
||||
return (true);
|
||||
}
|
||||
/* Initialize the new astats and arenas elements. */
|
||||
memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t));
|
||||
if (ctl_arena_init(&astats[ctl_stats.narenas + 1]))
|
||||
return (true);
|
||||
tarenas[ctl_stats.narenas] = NULL;
|
||||
/* Swap merged stats to their new location. */
|
||||
{
|
||||
ctl_arena_stats_t tstats;
|
||||
memcpy(&tstats, &astats[ctl_stats.narenas],
|
||||
sizeof(ctl_arena_stats_t));
|
||||
memcpy(&astats[ctl_stats.narenas],
|
||||
&astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t));
|
||||
memcpy(&astats[ctl_stats.narenas + 1], &tstats,
|
||||
sizeof(ctl_arena_stats_t));
|
||||
}
|
||||
ctl_stats.arenas = astats;
|
||||
ctl_stats.narenas++;
|
||||
malloc_mutex_lock(&arenas_lock);
|
||||
arenas = tarenas;
|
||||
narenas_total++;
|
||||
arenas_extend(narenas_total - 1);
|
||||
malloc_mutex_unlock(&arenas_lock);
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
static void
|
||||
ctl_refresh(void)
|
||||
{
|
||||
unsigned i;
|
||||
VARIABLE_ARRAY(arena_t *, tarenas, narenas);
|
||||
VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas);
|
||||
|
||||
if (config_stats) {
|
||||
malloc_mutex_lock(&chunks_mtx);
|
||||
@ -542,19 +628,19 @@ ctl_refresh(void)
|
||||
* Clear sum stats, since they will be merged into by
|
||||
* ctl_arena_refresh().
|
||||
*/
|
||||
ctl_stats.arenas[narenas].nthreads = 0;
|
||||
ctl_arena_clear(&ctl_stats.arenas[narenas]);
|
||||
ctl_stats.arenas[ctl_stats.narenas].nthreads = 0;
|
||||
ctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]);
|
||||
|
||||
malloc_mutex_lock(&arenas_lock);
|
||||
memcpy(tarenas, arenas, sizeof(arena_t *) * narenas);
|
||||
for (i = 0; i < narenas; i++) {
|
||||
memcpy(tarenas, arenas, sizeof(arena_t *) * ctl_stats.narenas);
|
||||
for (i = 0; i < ctl_stats.narenas; i++) {
|
||||
if (arenas[i] != NULL)
|
||||
ctl_stats.arenas[i].nthreads = arenas[i]->nthreads;
|
||||
else
|
||||
ctl_stats.arenas[i].nthreads = 0;
|
||||
}
|
||||
malloc_mutex_unlock(&arenas_lock);
|
||||
for (i = 0; i < narenas; i++) {
|
||||
for (i = 0; i < ctl_stats.narenas; i++) {
|
||||
bool initialized = (tarenas[i] != NULL);
|
||||
|
||||
ctl_stats.arenas[i].initialized = initialized;
|
||||
@ -563,11 +649,13 @@ ctl_refresh(void)
|
||||
}
|
||||
|
||||
if (config_stats) {
|
||||
ctl_stats.allocated = ctl_stats.arenas[narenas].allocated_small
|
||||
+ ctl_stats.arenas[narenas].astats.allocated_large
|
||||
ctl_stats.allocated =
|
||||
ctl_stats.arenas[ctl_stats.narenas].allocated_small
|
||||
+ ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large
|
||||
+ ctl_stats.huge.allocated;
|
||||
ctl_stats.active =
|
||||
(ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE)
|
||||
+ ctl_stats.huge.allocated;
|
||||
ctl_stats.active = (ctl_stats.arenas[narenas].pactive <<
|
||||
LG_PAGE) + ctl_stats.huge.allocated;
|
||||
ctl_stats.mapped = (ctl_stats.chunks.current << opt_lg_chunk);
|
||||
}
|
||||
|
||||
@ -585,13 +673,15 @@ ctl_init(void)
|
||||
* Allocate space for one extra arena stats element, which
|
||||
* contains summed stats across all arenas.
|
||||
*/
|
||||
assert(narenas_auto == narenas_total_get());
|
||||
ctl_stats.narenas = narenas_auto;
|
||||
ctl_stats.arenas = (ctl_arena_stats_t *)base_alloc(
|
||||
(narenas + 1) * sizeof(ctl_arena_stats_t));
|
||||
(ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t));
|
||||
if (ctl_stats.arenas == NULL) {
|
||||
ret = true;
|
||||
goto label_return;
|
||||
}
|
||||
memset(ctl_stats.arenas, 0, (narenas + 1) *
|
||||
memset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) *
|
||||
sizeof(ctl_arena_stats_t));
|
||||
|
||||
/*
|
||||
@ -601,14 +691,14 @@ ctl_init(void)
|
||||
*/
|
||||
if (config_stats) {
|
||||
unsigned i;
|
||||
for (i = 0; i <= narenas; i++) {
|
||||
for (i = 0; i <= ctl_stats.narenas; i++) {
|
||||
if (ctl_arena_init(&ctl_stats.arenas[i])) {
|
||||
ret = true;
|
||||
goto label_return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ctl_stats.arenas[narenas].initialized = true;
|
||||
ctl_stats.arenas[ctl_stats.narenas].initialized = true;
|
||||
|
||||
ctl_epoch = 0;
|
||||
ctl_refresh();
|
||||
@ -827,6 +917,27 @@ ctl_boot(void)
|
||||
return (false);
|
||||
}
|
||||
|
||||
void
|
||||
ctl_prefork(void)
|
||||
{
|
||||
|
||||
malloc_mutex_lock(&ctl_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
ctl_postfork_parent(void)
|
||||
{
|
||||
|
||||
malloc_mutex_postfork_parent(&ctl_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
ctl_postfork_child(void)
|
||||
{
|
||||
|
||||
malloc_mutex_postfork_child(&ctl_mtx);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* *_ctl() functions. */
|
||||
|
||||
@ -1032,8 +1143,8 @@ thread_tcache_enabled_ctl(const size_t *mib, size_t miblen, void *oldp,
|
||||
}
|
||||
READ(oldval, bool);
|
||||
|
||||
label_return:
|
||||
ret = 0;
|
||||
label_return:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1063,13 +1174,14 @@ thread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
||||
int ret;
|
||||
unsigned newind, oldind;
|
||||
|
||||
malloc_mutex_lock(&ctl_mtx);
|
||||
newind = oldind = choose_arena(NULL)->ind;
|
||||
WRITE(newind, unsigned);
|
||||
READ(oldind, unsigned);
|
||||
if (newind != oldind) {
|
||||
arena_t *arena;
|
||||
|
||||
if (newind >= narenas) {
|
||||
if (newind >= ctl_stats.narenas) {
|
||||
/* New arena index is out of range. */
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
@ -1102,6 +1214,7 @@ thread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
malloc_mutex_unlock(&ctl_mtx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1135,6 +1248,7 @@ CTL_RO_BOOL_CONFIG_GEN(config_xmalloc)
|
||||
/******************************************************************************/
|
||||
|
||||
CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
|
||||
CTL_RO_NL_GEN(opt_dss, opt_dss, const char *)
|
||||
CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t)
|
||||
CTL_RO_NL_GEN(opt_narenas, opt_narenas, size_t)
|
||||
CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t)
|
||||
@ -1158,12 +1272,123 @@ CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool)
|
||||
CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool)
|
||||
CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool)
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* ctl_mutex must be held during execution of this function. */
|
||||
static void
|
||||
arena_purge(unsigned arena_ind)
|
||||
{
|
||||
VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas);
|
||||
|
||||
malloc_mutex_lock(&arenas_lock);
|
||||
memcpy(tarenas, arenas, sizeof(arena_t *) * ctl_stats.narenas);
|
||||
malloc_mutex_unlock(&arenas_lock);
|
||||
|
||||
if (arena_ind == ctl_stats.narenas) {
|
||||
unsigned i;
|
||||
for (i = 0; i < ctl_stats.narenas; i++) {
|
||||
if (tarenas[i] != NULL)
|
||||
arena_purge_all(tarenas[i]);
|
||||
}
|
||||
} else {
|
||||
assert(arena_ind < ctl_stats.narenas);
|
||||
if (tarenas[arena_ind] != NULL)
|
||||
arena_purge_all(tarenas[arena_ind]);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
arena_i_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
||||
void *newp, size_t newlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
READONLY();
|
||||
WRITEONLY();
|
||||
malloc_mutex_lock(&ctl_mtx);
|
||||
arena_purge(mib[1]);
|
||||
malloc_mutex_unlock(&ctl_mtx);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
arena_i_dss_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
||||
void *newp, size_t newlen)
|
||||
{
|
||||
int ret, i;
|
||||
bool match, err;
|
||||
const char *dss;
|
||||
unsigned arena_ind = mib[1];
|
||||
dss_prec_t dss_prec_old = dss_prec_limit;
|
||||
dss_prec_t dss_prec = dss_prec_limit;
|
||||
|
||||
malloc_mutex_lock(&ctl_mtx);
|
||||
WRITE(dss, const char *);
|
||||
match = false;
|
||||
for (i = 0; i < dss_prec_limit; i++) {
|
||||
if (strcmp(dss_prec_names[i], dss) == 0) {
|
||||
dss_prec = i;
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match == false) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
if (arena_ind < ctl_stats.narenas) {
|
||||
arena_t *arena = arenas[arena_ind];
|
||||
if (arena != NULL) {
|
||||
dss_prec_old = arena_dss_prec_get(arena);
|
||||
arena_dss_prec_set(arena, dss_prec);
|
||||
err = false;
|
||||
} else
|
||||
err = true;
|
||||
} else {
|
||||
dss_prec_old = chunk_dss_prec_get();
|
||||
err = chunk_dss_prec_set(dss_prec);
|
||||
}
|
||||
dss = dss_prec_names[dss_prec_old];
|
||||
READ(dss, const char *);
|
||||
if (err) {
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
malloc_mutex_unlock(&ctl_mtx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static const ctl_named_node_t *
|
||||
arena_i_index(const size_t *mib, size_t miblen, size_t i)
|
||||
{
|
||||
const ctl_named_node_t * ret;
|
||||
|
||||
malloc_mutex_lock(&ctl_mtx);
|
||||
if (i > ctl_stats.narenas) {
|
||||
ret = NULL;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
ret = super_arena_i_node;
|
||||
label_return:
|
||||
malloc_mutex_unlock(&ctl_mtx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t)
|
||||
CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t)
|
||||
CTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t)
|
||||
const ctl_named_node_t *
|
||||
static const ctl_named_node_t *
|
||||
arenas_bin_i_index(const size_t *mib, size_t miblen, size_t i)
|
||||
{
|
||||
|
||||
@ -1173,7 +1398,7 @@ arenas_bin_i_index(const size_t *mib, size_t miblen, size_t i)
|
||||
}
|
||||
|
||||
CTL_RO_NL_GEN(arenas_lrun_i_size, ((mib[2]+1) << LG_PAGE), size_t)
|
||||
const ctl_named_node_t *
|
||||
static const ctl_named_node_t *
|
||||
arenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i)
|
||||
{
|
||||
|
||||
@ -1182,7 +1407,27 @@ arenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i)
|
||||
return (super_arenas_lrun_i_node);
|
||||
}
|
||||
|
||||
CTL_RO_NL_GEN(arenas_narenas, narenas, unsigned)
|
||||
static int
|
||||
arenas_narenas_ctl(const size_t *mib, size_t miblen, void *oldp,
|
||||
size_t *oldlenp, void *newp, size_t newlen)
|
||||
{
|
||||
int ret;
|
||||
unsigned narenas;
|
||||
|
||||
malloc_mutex_lock(&ctl_mtx);
|
||||
READONLY();
|
||||
if (*oldlenp != sizeof(unsigned)) {
|
||||
ret = EINVAL;
|
||||
goto label_return;
|
||||
}
|
||||
narenas = ctl_stats.narenas;
|
||||
READ(narenas, unsigned);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
malloc_mutex_unlock(&ctl_mtx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp,
|
||||
@ -1193,13 +1438,13 @@ arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp,
|
||||
|
||||
malloc_mutex_lock(&ctl_mtx);
|
||||
READONLY();
|
||||
if (*oldlenp != narenas * sizeof(bool)) {
|
||||
if (*oldlenp != ctl_stats.narenas * sizeof(bool)) {
|
||||
ret = EINVAL;
|
||||
nread = (*oldlenp < narenas * sizeof(bool))
|
||||
? (*oldlenp / sizeof(bool)) : narenas;
|
||||
nread = (*oldlenp < ctl_stats.narenas * sizeof(bool))
|
||||
? (*oldlenp / sizeof(bool)) : ctl_stats.narenas;
|
||||
} else {
|
||||
ret = 0;
|
||||
nread = narenas;
|
||||
nread = ctl_stats.narenas;
|
||||
}
|
||||
|
||||
for (i = 0; i < nread; i++)
|
||||
@ -1222,36 +1467,43 @@ arenas_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
||||
void *newp, size_t newlen)
|
||||
{
|
||||
int ret;
|
||||
unsigned arena;
|
||||
unsigned arena_ind;
|
||||
|
||||
malloc_mutex_lock(&ctl_mtx);
|
||||
WRITEONLY();
|
||||
arena = UINT_MAX;
|
||||
WRITE(arena, unsigned);
|
||||
if (newp != NULL && arena >= narenas) {
|
||||
arena_ind = UINT_MAX;
|
||||
WRITE(arena_ind, unsigned);
|
||||
if (newp != NULL && arena_ind >= ctl_stats.narenas)
|
||||
ret = EFAULT;
|
||||
goto label_return;
|
||||
} else {
|
||||
VARIABLE_ARRAY(arena_t *, tarenas, narenas);
|
||||
|
||||
malloc_mutex_lock(&arenas_lock);
|
||||
memcpy(tarenas, arenas, sizeof(arena_t *) * narenas);
|
||||
malloc_mutex_unlock(&arenas_lock);
|
||||
|
||||
if (arena == UINT_MAX) {
|
||||
unsigned i;
|
||||
for (i = 0; i < narenas; i++) {
|
||||
if (tarenas[i] != NULL)
|
||||
arena_purge_all(tarenas[i]);
|
||||
}
|
||||
} else {
|
||||
assert(arena < narenas);
|
||||
if (tarenas[arena] != NULL)
|
||||
arena_purge_all(tarenas[arena]);
|
||||
}
|
||||
else {
|
||||
if (arena_ind == UINT_MAX)
|
||||
arena_ind = ctl_stats.narenas;
|
||||
arena_purge(arena_ind);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
label_return:
|
||||
malloc_mutex_unlock(&ctl_mtx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
arenas_extend_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
||||
void *newp, size_t newlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
malloc_mutex_lock(&ctl_mtx);
|
||||
READONLY();
|
||||
if (ctl_grow()) {
|
||||
ret = EAGAIN;
|
||||
goto label_return;
|
||||
}
|
||||
READ(ctl_stats.narenas - 1, unsigned);
|
||||
|
||||
ret = 0;
|
||||
label_return:
|
||||
malloc_mutex_unlock(&ctl_mtx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1356,7 +1608,7 @@ CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns,
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns,
|
||||
ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t)
|
||||
|
||||
const ctl_named_node_t *
|
||||
static const ctl_named_node_t *
|
||||
stats_arenas_i_bins_j_index(const size_t *mib, size_t miblen, size_t j)
|
||||
{
|
||||
|
||||
@ -1374,7 +1626,7 @@ CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests,
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns,
|
||||
ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t)
|
||||
|
||||
const ctl_named_node_t *
|
||||
static const ctl_named_node_t *
|
||||
stats_arenas_i_lruns_j_index(const size_t *mib, size_t miblen, size_t j)
|
||||
{
|
||||
|
||||
@ -1384,6 +1636,7 @@ stats_arenas_i_lruns_j_index(const size_t *mib, size_t miblen, size_t j)
|
||||
}
|
||||
|
||||
CTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned)
|
||||
CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *)
|
||||
CTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t)
|
||||
CTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t)
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_mapped,
|
||||
@ -1395,13 +1648,13 @@ CTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise,
|
||||
CTL_RO_CGEN(config_stats, stats_arenas_i_purged,
|
||||
ctl_stats.arenas[mib[2]].astats.purged, uint64_t)
|
||||
|
||||
const ctl_named_node_t *
|
||||
static const ctl_named_node_t *
|
||||
stats_arenas_i_index(const size_t *mib, size_t miblen, size_t i)
|
||||
{
|
||||
const ctl_named_node_t * ret;
|
||||
|
||||
malloc_mutex_lock(&ctl_mtx);
|
||||
if (ctl_stats.arenas[i].initialized == false) {
|
||||
if (i > ctl_stats.narenas || ctl_stats.arenas[i].initialized == false) {
|
||||
ret = NULL;
|
||||
goto label_return;
|
||||
}
|
||||
|
@ -48,7 +48,8 @@ huge_palloc(size_t size, size_t alignment, bool zero)
|
||||
* it is possible to make correct junk/zero fill decisions below.
|
||||
*/
|
||||
is_zeroed = zero;
|
||||
ret = chunk_alloc(csize, alignment, false, &is_zeroed);
|
||||
ret = chunk_alloc(csize, alignment, false, &is_zeroed,
|
||||
chunk_dss_prec_get());
|
||||
if (ret == NULL) {
|
||||
base_node_dealloc(node);
|
||||
return (NULL);
|
||||
@ -101,7 +102,7 @@ huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size, size_t extra)
|
||||
|
||||
void *
|
||||
huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
|
||||
size_t alignment, bool zero)
|
||||
size_t alignment, bool zero, bool try_tcache_dalloc)
|
||||
{
|
||||
void *ret;
|
||||
size_t copysize;
|
||||
@ -180,7 +181,7 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
|
||||
#endif
|
||||
{
|
||||
memcpy(ret, ptr, copysize);
|
||||
iqalloc(ptr);
|
||||
iqallocx(ptr, try_tcache_dalloc);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
@ -37,7 +37,8 @@ unsigned ncpus;
|
||||
|
||||
malloc_mutex_t arenas_lock;
|
||||
arena_t **arenas;
|
||||
unsigned narenas;
|
||||
unsigned narenas_total;
|
||||
unsigned narenas_auto;
|
||||
|
||||
/* Set to true once the allocator has been initialized. */
|
||||
static bool malloc_initialized = false;
|
||||
@ -148,14 +149,14 @@ choose_arena_hard(void)
|
||||
{
|
||||
arena_t *ret;
|
||||
|
||||
if (narenas > 1) {
|
||||
if (narenas_auto > 1) {
|
||||
unsigned i, choose, first_null;
|
||||
|
||||
choose = 0;
|
||||
first_null = narenas;
|
||||
first_null = narenas_auto;
|
||||
malloc_mutex_lock(&arenas_lock);
|
||||
assert(arenas[0] != NULL);
|
||||
for (i = 1; i < narenas; i++) {
|
||||
for (i = 1; i < narenas_auto; i++) {
|
||||
if (arenas[i] != NULL) {
|
||||
/*
|
||||
* Choose the first arena that has the lowest
|
||||
@ -164,7 +165,7 @@ choose_arena_hard(void)
|
||||
if (arenas[i]->nthreads <
|
||||
arenas[choose]->nthreads)
|
||||
choose = i;
|
||||
} else if (first_null == narenas) {
|
||||
} else if (first_null == narenas_auto) {
|
||||
/*
|
||||
* Record the index of the first uninitialized
|
||||
* arena, in case all extant arenas are in use.
|
||||
@ -178,7 +179,8 @@ choose_arena_hard(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (arenas[choose]->nthreads == 0 || first_null == narenas) {
|
||||
if (arenas[choose]->nthreads == 0
|
||||
|| first_null == narenas_auto) {
|
||||
/*
|
||||
* Use an unloaded arena, or the least loaded arena if
|
||||
* all arenas are already initialized.
|
||||
@ -207,7 +209,7 @@ stats_print_atexit(void)
|
||||
{
|
||||
|
||||
if (config_tcache && config_stats) {
|
||||
unsigned i;
|
||||
unsigned narenas, i;
|
||||
|
||||
/*
|
||||
* Merge stats from extant threads. This is racy, since
|
||||
@ -216,7 +218,7 @@ stats_print_atexit(void)
|
||||
* out of date by the time they are reported, if other threads
|
||||
* continue to allocate.
|
||||
*/
|
||||
for (i = 0; i < narenas; i++) {
|
||||
for (i = 0, narenas = narenas_total_get(); i < narenas; i++) {
|
||||
arena_t *arena = arenas[i];
|
||||
if (arena != NULL) {
|
||||
tcache_t *tcache;
|
||||
@ -258,12 +260,13 @@ malloc_ncpus(void)
|
||||
result = si.dwNumberOfProcessors;
|
||||
#else
|
||||
result = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
#endif
|
||||
if (result == -1) {
|
||||
/* Error. */
|
||||
ret = 1;
|
||||
}
|
||||
#endif
|
||||
ret = (unsigned)result;
|
||||
} else {
|
||||
ret = (unsigned)result;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@ -381,6 +384,22 @@ malloc_conf_init(void)
|
||||
const char *opts, *k, *v;
|
||||
size_t klen, vlen;
|
||||
|
||||
/*
|
||||
* Automatically configure valgrind before processing options. The
|
||||
* valgrind option remains in jemalloc 3.x for compatibility reasons.
|
||||
*/
|
||||
if (config_valgrind) {
|
||||
opt_valgrind = (RUNNING_ON_VALGRIND != 0) ? true : false;
|
||||
if (config_fill && opt_valgrind) {
|
||||
opt_junk = false;
|
||||
assert(opt_zero == false);
|
||||
opt_quarantine = JEMALLOC_VALGRIND_QUARANTINE_DEFAULT;
|
||||
opt_redzone = true;
|
||||
}
|
||||
if (config_tcache && opt_valgrind)
|
||||
opt_tcache = false;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
/* Get runtime configuration. */
|
||||
switch (i) {
|
||||
@ -542,6 +561,30 @@ malloc_conf_init(void)
|
||||
*/
|
||||
CONF_HANDLE_SIZE_T(opt_lg_chunk, "lg_chunk", LG_PAGE +
|
||||
(config_fill ? 2 : 1), (sizeof(size_t) << 3) - 1)
|
||||
if (strncmp("dss", k, klen) == 0) {
|
||||
int i;
|
||||
bool match = false;
|
||||
for (i = 0; i < dss_prec_limit; i++) {
|
||||
if (strncmp(dss_prec_names[i], v, vlen)
|
||||
== 0) {
|
||||
if (chunk_dss_prec_set(i)) {
|
||||
malloc_conf_error(
|
||||
"Error setting dss",
|
||||
k, klen, v, vlen);
|
||||
} else {
|
||||
opt_dss =
|
||||
dss_prec_names[i];
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match == false) {
|
||||
malloc_conf_error("Invalid conf value",
|
||||
k, klen, v, vlen);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
CONF_HANDLE_SIZE_T(opt_narenas, "narenas", 1,
|
||||
SIZE_T_MAX)
|
||||
CONF_HANDLE_SSIZE_T(opt_lg_dirty_mult, "lg_dirty_mult",
|
||||
@ -558,20 +601,7 @@ malloc_conf_init(void)
|
||||
CONF_HANDLE_BOOL(opt_utrace, "utrace")
|
||||
}
|
||||
if (config_valgrind) {
|
||||
bool hit;
|
||||
CONF_HANDLE_BOOL_HIT(opt_valgrind,
|
||||
"valgrind", hit)
|
||||
if (config_fill && opt_valgrind && hit) {
|
||||
opt_junk = false;
|
||||
opt_zero = false;
|
||||
if (opt_quarantine == 0) {
|
||||
opt_quarantine =
|
||||
JEMALLOC_VALGRIND_QUARANTINE_DEFAULT;
|
||||
}
|
||||
opt_redzone = true;
|
||||
}
|
||||
if (hit)
|
||||
continue;
|
||||
CONF_HANDLE_BOOL(opt_valgrind, "valgrind")
|
||||
}
|
||||
if (config_xmalloc) {
|
||||
CONF_HANDLE_BOOL(opt_xmalloc, "xmalloc")
|
||||
@ -700,9 +730,9 @@ malloc_init_hard(void)
|
||||
* Create enough scaffolding to allow recursive allocation in
|
||||
* malloc_ncpus().
|
||||
*/
|
||||
narenas = 1;
|
||||
narenas_total = narenas_auto = 1;
|
||||
arenas = init_arenas;
|
||||
memset(arenas, 0, sizeof(arena_t *) * narenas);
|
||||
memset(arenas, 0, sizeof(arena_t *) * narenas_auto);
|
||||
|
||||
/*
|
||||
* Initialize one arena here. The rest are lazily created in
|
||||
@ -760,20 +790,21 @@ malloc_init_hard(void)
|
||||
else
|
||||
opt_narenas = 1;
|
||||
}
|
||||
narenas = opt_narenas;
|
||||
narenas_auto = opt_narenas;
|
||||
/*
|
||||
* Make sure that the arenas array can be allocated. In practice, this
|
||||
* limit is enough to allow the allocator to function, but the ctl
|
||||
* machinery will fail to allocate memory at far lower limits.
|
||||
*/
|
||||
if (narenas > chunksize / sizeof(arena_t *)) {
|
||||
narenas = chunksize / sizeof(arena_t *);
|
||||
if (narenas_auto > chunksize / sizeof(arena_t *)) {
|
||||
narenas_auto = chunksize / sizeof(arena_t *);
|
||||
malloc_printf("<jemalloc>: Reducing narenas to limit (%d)\n",
|
||||
narenas);
|
||||
narenas_auto);
|
||||
}
|
||||
narenas_total = narenas_auto;
|
||||
|
||||
/* Allocate and initialize arenas. */
|
||||
arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas);
|
||||
arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas_total);
|
||||
if (arenas == NULL) {
|
||||
malloc_mutex_unlock(&init_lock);
|
||||
return (true);
|
||||
@ -782,7 +813,7 @@ malloc_init_hard(void)
|
||||
* Zero the array. In practice, this should always be pre-zeroed,
|
||||
* since it was just mmap()ed, but let's be sure.
|
||||
*/
|
||||
memset(arenas, 0, sizeof(arena_t *) * narenas);
|
||||
memset(arenas, 0, sizeof(arena_t *) * narenas_total);
|
||||
/* Copy the pointer to the one arena that was already initialized. */
|
||||
arenas[0] = init_arenas[0];
|
||||
|
||||
@ -1267,11 +1298,10 @@ je_valloc(size_t size)
|
||||
* passed an extra argument for the caller return address, which will be
|
||||
* ignored.
|
||||
*/
|
||||
JEMALLOC_EXPORT void (* const __free_hook)(void *ptr) = je_free;
|
||||
JEMALLOC_EXPORT void *(* const __malloc_hook)(size_t size) = je_malloc;
|
||||
JEMALLOC_EXPORT void *(* const __realloc_hook)(void *ptr, size_t size) =
|
||||
je_realloc;
|
||||
JEMALLOC_EXPORT void *(* const __memalign_hook)(size_t alignment, size_t size) =
|
||||
JEMALLOC_EXPORT void (* __free_hook)(void *ptr) = je_free;
|
||||
JEMALLOC_EXPORT void *(* __malloc_hook)(size_t size) = je_malloc;
|
||||
JEMALLOC_EXPORT void *(* __realloc_hook)(void *ptr, size_t size) = je_realloc;
|
||||
JEMALLOC_EXPORT void *(* __memalign_hook)(size_t alignment, size_t size) =
|
||||
je_memalign;
|
||||
#endif
|
||||
|
||||
@ -1284,7 +1314,7 @@ JEMALLOC_EXPORT void *(* const __memalign_hook)(size_t alignment, size_t size) =
|
||||
*/
|
||||
|
||||
size_t
|
||||
je_malloc_usable_size(const void *ptr)
|
||||
je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)
|
||||
{
|
||||
size_t ret;
|
||||
|
||||
@ -1348,18 +1378,19 @@ je_mallctlbymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
||||
#ifdef JEMALLOC_EXPERIMENTAL
|
||||
|
||||
JEMALLOC_INLINE void *
|
||||
iallocm(size_t usize, size_t alignment, bool zero)
|
||||
iallocm(size_t usize, size_t alignment, bool zero, bool try_tcache,
|
||||
arena_t *arena)
|
||||
{
|
||||
|
||||
assert(usize == ((alignment == 0) ? s2u(usize) : sa2u(usize,
|
||||
alignment)));
|
||||
|
||||
if (alignment != 0)
|
||||
return (ipalloc(usize, alignment, zero));
|
||||
return (ipallocx(usize, alignment, zero, try_tcache, arena));
|
||||
else if (zero)
|
||||
return (icalloc(usize));
|
||||
return (icallocx(usize, try_tcache, arena));
|
||||
else
|
||||
return (imalloc(usize));
|
||||
return (imallocx(usize, try_tcache, arena));
|
||||
}
|
||||
|
||||
int
|
||||
@ -1370,6 +1401,9 @@ je_allocm(void **ptr, size_t *rsize, size_t size, int flags)
|
||||
size_t alignment = (ZU(1) << (flags & ALLOCM_LG_ALIGN_MASK)
|
||||
& (SIZE_T_MAX-1));
|
||||
bool zero = flags & ALLOCM_ZERO;
|
||||
unsigned arena_ind = ((unsigned)(flags >> 8)) - 1;
|
||||
arena_t *arena;
|
||||
bool try_tcache;
|
||||
|
||||
assert(ptr != NULL);
|
||||
assert(size != 0);
|
||||
@ -1377,6 +1411,14 @@ je_allocm(void **ptr, size_t *rsize, size_t size, int flags)
|
||||
if (malloc_init())
|
||||
goto label_oom;
|
||||
|
||||
if (arena_ind != UINT_MAX) {
|
||||
arena = arenas[arena_ind];
|
||||
try_tcache = false;
|
||||
} else {
|
||||
arena = NULL;
|
||||
try_tcache = true;
|
||||
}
|
||||
|
||||
usize = (alignment == 0) ? s2u(size) : sa2u(size, alignment);
|
||||
if (usize == 0)
|
||||
goto label_oom;
|
||||
@ -1393,18 +1435,19 @@ je_allocm(void **ptr, size_t *rsize, size_t size, int flags)
|
||||
s2u(SMALL_MAXCLASS+1) : sa2u(SMALL_MAXCLASS+1,
|
||||
alignment);
|
||||
assert(usize_promoted != 0);
|
||||
p = iallocm(usize_promoted, alignment, zero);
|
||||
p = iallocm(usize_promoted, alignment, zero,
|
||||
try_tcache, arena);
|
||||
if (p == NULL)
|
||||
goto label_oom;
|
||||
arena_prof_promoted(p, usize);
|
||||
} else {
|
||||
p = iallocm(usize, alignment, zero);
|
||||
p = iallocm(usize, alignment, zero, try_tcache, arena);
|
||||
if (p == NULL)
|
||||
goto label_oom;
|
||||
}
|
||||
prof_malloc(p, usize, cnt);
|
||||
} else {
|
||||
p = iallocm(usize, alignment, zero);
|
||||
p = iallocm(usize, alignment, zero, try_tcache, arena);
|
||||
if (p == NULL)
|
||||
goto label_oom;
|
||||
}
|
||||
@ -1441,6 +1484,9 @@ je_rallocm(void **ptr, size_t *rsize, size_t size, size_t extra, int flags)
|
||||
& (SIZE_T_MAX-1));
|
||||
bool zero = flags & ALLOCM_ZERO;
|
||||
bool no_move = flags & ALLOCM_NO_MOVE;
|
||||
unsigned arena_ind = ((unsigned)(flags >> 8)) - 1;
|
||||
bool try_tcache_alloc, try_tcache_dalloc;
|
||||
arena_t *arena;
|
||||
|
||||
assert(ptr != NULL);
|
||||
assert(*ptr != NULL);
|
||||
@ -1448,6 +1494,19 @@ je_rallocm(void **ptr, size_t *rsize, size_t size, size_t extra, int flags)
|
||||
assert(SIZE_T_MAX - size >= extra);
|
||||
assert(malloc_initialized || IS_INITIALIZER);
|
||||
|
||||
if (arena_ind != UINT_MAX) {
|
||||
arena_chunk_t *chunk;
|
||||
try_tcache_alloc = true;
|
||||
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(*ptr);
|
||||
try_tcache_dalloc = (chunk == *ptr || chunk->arena !=
|
||||
arenas[arena_ind]);
|
||||
arena = arenas[arena_ind];
|
||||
} else {
|
||||
try_tcache_alloc = true;
|
||||
try_tcache_dalloc = true;
|
||||
arena = NULL;
|
||||
}
|
||||
|
||||
p = *ptr;
|
||||
if (config_prof && opt_prof) {
|
||||
prof_thr_cnt_t *cnt;
|
||||
@ -1474,9 +1533,10 @@ je_rallocm(void **ptr, size_t *rsize, size_t size, size_t extra, int flags)
|
||||
if (prof_promote && (uintptr_t)cnt != (uintptr_t)1U
|
||||
&& ((alignment == 0) ? s2u(size) : sa2u(size, alignment))
|
||||
<= SMALL_MAXCLASS) {
|
||||
q = iralloc(p, SMALL_MAXCLASS+1, (SMALL_MAXCLASS+1 >=
|
||||
q = irallocx(p, SMALL_MAXCLASS+1, (SMALL_MAXCLASS+1 >=
|
||||
size+extra) ? 0 : size+extra - (SMALL_MAXCLASS+1),
|
||||
alignment, zero, no_move);
|
||||
alignment, zero, no_move, try_tcache_alloc,
|
||||
try_tcache_dalloc, arena);
|
||||
if (q == NULL)
|
||||
goto label_err;
|
||||
if (max_usize < PAGE) {
|
||||
@ -1485,7 +1545,8 @@ je_rallocm(void **ptr, size_t *rsize, size_t size, size_t extra, int flags)
|
||||
} else
|
||||
usize = isalloc(q, config_prof);
|
||||
} else {
|
||||
q = iralloc(p, size, extra, alignment, zero, no_move);
|
||||
q = irallocx(p, size, extra, alignment, zero, no_move,
|
||||
try_tcache_alloc, try_tcache_dalloc, arena);
|
||||
if (q == NULL)
|
||||
goto label_err;
|
||||
usize = isalloc(q, config_prof);
|
||||
@ -1502,7 +1563,8 @@ je_rallocm(void **ptr, size_t *rsize, size_t size, size_t extra, int flags)
|
||||
old_size = isalloc(p, false);
|
||||
old_rzsize = u2rz(old_size);
|
||||
}
|
||||
q = iralloc(p, size, extra, alignment, zero, no_move);
|
||||
q = irallocx(p, size, extra, alignment, zero, no_move,
|
||||
try_tcache_alloc, try_tcache_dalloc, arena);
|
||||
if (q == NULL)
|
||||
goto label_err;
|
||||
if (config_stats)
|
||||
@ -1563,10 +1625,19 @@ je_dallocm(void *ptr, int flags)
|
||||
{
|
||||
size_t usize;
|
||||
size_t rzsize JEMALLOC_CC_SILENCE_INIT(0);
|
||||
unsigned arena_ind = ((unsigned)(flags >> 8)) - 1;
|
||||
bool try_tcache;
|
||||
|
||||
assert(ptr != NULL);
|
||||
assert(malloc_initialized || IS_INITIALIZER);
|
||||
|
||||
if (arena_ind != UINT_MAX) {
|
||||
arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
||||
try_tcache = (chunk == ptr || chunk->arena !=
|
||||
arenas[arena_ind]);
|
||||
} else
|
||||
try_tcache = true;
|
||||
|
||||
UTRACE(ptr, 0, 0);
|
||||
if (config_stats || config_valgrind)
|
||||
usize = isalloc(ptr, config_prof);
|
||||
@ -1579,7 +1650,7 @@ je_dallocm(void *ptr, int flags)
|
||||
thread_allocated_tsd_get()->deallocated += usize;
|
||||
if (config_valgrind && opt_valgrind)
|
||||
rzsize = p2rz(ptr);
|
||||
iqalloc(ptr);
|
||||
iqallocx(ptr, try_tcache);
|
||||
JEMALLOC_VALGRIND_FREE(ptr, rzsize);
|
||||
|
||||
return (ALLOCM_SUCCESS);
|
||||
@ -1616,6 +1687,27 @@ je_nallocm(size_t *rsize, size_t size, int flags)
|
||||
* malloc during fork().
|
||||
*/
|
||||
|
||||
/*
|
||||
* If an application creates a thread before doing any allocation in the main
|
||||
* thread, then calls fork(2) in the main thread followed by memory allocation
|
||||
* in the child process, a race can occur that results in deadlock within the
|
||||
* child: the main thread may have forked while the created thread had
|
||||
* partially initialized the allocator. Ordinarily jemalloc prevents
|
||||
* fork/malloc races via the following functions it registers during
|
||||
* initialization using pthread_atfork(), but of course that does no good if
|
||||
* the allocator isn't fully initialized at fork time. The following library
|
||||
* constructor is a partial solution to this problem. It may still possible to
|
||||
* trigger the deadlock described above, but doing so would involve forking via
|
||||
* a library constructor that runs before jemalloc's runs.
|
||||
*/
|
||||
JEMALLOC_ATTR(constructor)
|
||||
static void
|
||||
jemalloc_constructor(void)
|
||||
{
|
||||
|
||||
malloc_init();
|
||||
}
|
||||
|
||||
#ifndef JEMALLOC_MUTEX_INIT_CB
|
||||
void
|
||||
jemalloc_prefork(void)
|
||||
@ -1633,14 +1725,16 @@ _malloc_prefork(void)
|
||||
assert(malloc_initialized);
|
||||
|
||||
/* Acquire all mutexes in a safe order. */
|
||||
ctl_prefork();
|
||||
malloc_mutex_prefork(&arenas_lock);
|
||||
for (i = 0; i < narenas; i++) {
|
||||
for (i = 0; i < narenas_total; i++) {
|
||||
if (arenas[i] != NULL)
|
||||
arena_prefork(arenas[i]);
|
||||
}
|
||||
prof_prefork();
|
||||
chunk_prefork();
|
||||
base_prefork();
|
||||
huge_prefork();
|
||||
chunk_dss_prefork();
|
||||
}
|
||||
|
||||
#ifndef JEMALLOC_MUTEX_INIT_CB
|
||||
@ -1660,14 +1754,16 @@ _malloc_postfork(void)
|
||||
assert(malloc_initialized);
|
||||
|
||||
/* Release all mutexes, now that fork() has completed. */
|
||||
chunk_dss_postfork_parent();
|
||||
huge_postfork_parent();
|
||||
base_postfork_parent();
|
||||
for (i = 0; i < narenas; i++) {
|
||||
chunk_postfork_parent();
|
||||
prof_postfork_parent();
|
||||
for (i = 0; i < narenas_total; i++) {
|
||||
if (arenas[i] != NULL)
|
||||
arena_postfork_parent(arenas[i]);
|
||||
}
|
||||
malloc_mutex_postfork_parent(&arenas_lock);
|
||||
ctl_postfork_parent();
|
||||
}
|
||||
|
||||
void
|
||||
@ -1678,14 +1774,16 @@ jemalloc_postfork_child(void)
|
||||
assert(malloc_initialized);
|
||||
|
||||
/* Release all mutexes, now that fork() has completed. */
|
||||
chunk_dss_postfork_child();
|
||||
huge_postfork_child();
|
||||
base_postfork_child();
|
||||
for (i = 0; i < narenas; i++) {
|
||||
chunk_postfork_child();
|
||||
prof_postfork_child();
|
||||
for (i = 0; i < narenas_total; i++) {
|
||||
if (arenas[i] != NULL)
|
||||
arena_postfork_child(arenas[i]);
|
||||
}
|
||||
malloc_mutex_postfork_child(&arenas_lock);
|
||||
ctl_postfork_child();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -64,7 +64,7 @@ pthread_create(pthread_t *__restrict thread,
|
||||
/******************************************************************************/
|
||||
|
||||
#ifdef JEMALLOC_MUTEX_INIT_CB
|
||||
int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
|
||||
JEMALLOC_EXPORT int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
|
||||
void *(calloc_cb)(size_t, size_t));
|
||||
|
||||
__weak_reference(_pthread_mutex_init_calloc_cb_stub,
|
||||
|
@ -1270,4 +1270,46 @@ prof_boot2(void)
|
||||
return (false);
|
||||
}
|
||||
|
||||
void
|
||||
prof_prefork(void)
|
||||
{
|
||||
|
||||
if (opt_prof) {
|
||||
unsigned i;
|
||||
|
||||
malloc_mutex_lock(&bt2ctx_mtx);
|
||||
malloc_mutex_lock(&prof_dump_seq_mtx);
|
||||
for (i = 0; i < PROF_NCTX_LOCKS; i++)
|
||||
malloc_mutex_lock(&ctx_locks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prof_postfork_parent(void)
|
||||
{
|
||||
|
||||
if (opt_prof) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < PROF_NCTX_LOCKS; i++)
|
||||
malloc_mutex_postfork_parent(&ctx_locks[i]);
|
||||
malloc_mutex_postfork_parent(&prof_dump_seq_mtx);
|
||||
malloc_mutex_postfork_parent(&bt2ctx_mtx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prof_postfork_child(void)
|
||||
{
|
||||
|
||||
if (opt_prof) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < PROF_NCTX_LOCKS; i++)
|
||||
malloc_mutex_postfork_child(&ctx_locks[i]);
|
||||
malloc_mutex_postfork_child(&prof_dump_seq_mtx);
|
||||
malloc_mutex_postfork_child(&bt2ctx_mtx);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -44,3 +44,24 @@ rtree_new(unsigned bits)
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
rtree_prefork(rtree_t *rtree)
|
||||
{
|
||||
|
||||
malloc_mutex_prefork(&rtree->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
rtree_postfork_parent(rtree_t *rtree)
|
||||
{
|
||||
|
||||
malloc_mutex_postfork_parent(&rtree->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
rtree_postfork_child(rtree_t *rtree)
|
||||
{
|
||||
|
||||
malloc_mutex_postfork_child(&rtree->mutex);
|
||||
}
|
||||
|
@ -206,6 +206,7 @@ stats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||
unsigned i, bool bins, bool large)
|
||||
{
|
||||
unsigned nthreads;
|
||||
const char *dss;
|
||||
size_t page, pactive, pdirty, mapped;
|
||||
uint64_t npurge, nmadvise, purged;
|
||||
size_t small_allocated;
|
||||
@ -218,6 +219,9 @@ stats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||
CTL_I_GET("stats.arenas.0.nthreads", &nthreads, unsigned);
|
||||
malloc_cprintf(write_cb, cbopaque,
|
||||
"assigned threads: %u\n", nthreads);
|
||||
CTL_I_GET("stats.arenas.0.dss", &dss, const char *);
|
||||
malloc_cprintf(write_cb, cbopaque, "dss allocation precedence: %s\n",
|
||||
dss);
|
||||
CTL_I_GET("stats.arenas.0.pactive", &pactive, size_t);
|
||||
CTL_I_GET("stats.arenas.0.pdirty", &pdirty, size_t);
|
||||
CTL_I_GET("stats.arenas.0.npurge", &npurge, uint64_t);
|
||||
@ -370,6 +374,7 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||
"Run-time option settings:\n");
|
||||
OPT_WRITE_BOOL(abort)
|
||||
OPT_WRITE_SIZE_T(lg_chunk)
|
||||
OPT_WRITE_CHAR_P(dss)
|
||||
OPT_WRITE_SIZE_T(narenas)
|
||||
OPT_WRITE_SSIZE_T(lg_dirty_mult)
|
||||
OPT_WRITE_BOOL(stats_print)
|
||||
@ -400,7 +405,7 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||
malloc_cprintf(write_cb, cbopaque, "CPUs: %u\n", ncpus);
|
||||
|
||||
CTL_GET("arenas.narenas", &uv, unsigned);
|
||||
malloc_cprintf(write_cb, cbopaque, "Max arenas: %u\n", uv);
|
||||
malloc_cprintf(write_cb, cbopaque, "Arenas: %u\n", uv);
|
||||
|
||||
malloc_cprintf(write_cb, cbopaque, "Pointer size: %zu\n",
|
||||
sizeof(void *));
|
||||
@ -472,7 +477,8 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||
CTL_GET("stats.chunks.current", &chunks_current, size_t);
|
||||
malloc_cprintf(write_cb, cbopaque, "chunks: nchunks "
|
||||
"highchunks curchunks\n");
|
||||
malloc_cprintf(write_cb, cbopaque, " %13"PRIu64"%13zu%13zu\n",
|
||||
malloc_cprintf(write_cb, cbopaque,
|
||||
" %13"PRIu64" %12zu %12zu\n",
|
||||
chunks_total, chunks_high, chunks_current);
|
||||
|
||||
/* Print huge stats. */
|
||||
|
@ -288,7 +288,7 @@ tcache_create(arena_t *arena)
|
||||
else if (size <= tcache_maxclass)
|
||||
tcache = (tcache_t *)arena_malloc_large(arena, size, true);
|
||||
else
|
||||
tcache = (tcache_t *)icalloc(size);
|
||||
tcache = (tcache_t *)icallocx(size, false, arena);
|
||||
|
||||
if (tcache == NULL)
|
||||
return (NULL);
|
||||
@ -364,7 +364,7 @@ tcache_destroy(tcache_t *tcache)
|
||||
|
||||
arena_dalloc_large(arena, chunk, tcache);
|
||||
} else
|
||||
idalloc(tcache);
|
||||
idallocx(tcache, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -393,7 +393,6 @@ malloc_vsnprintf(char *str, size_t size, const char *format, va_list ap)
|
||||
case '\0': goto label_out;
|
||||
case '%': {
|
||||
bool alt_form = false;
|
||||
bool zero_pad = false;
|
||||
bool left_justify = false;
|
||||
bool plus_space = false;
|
||||
bool plus_plus = false;
|
||||
@ -414,10 +413,6 @@ malloc_vsnprintf(char *str, size_t size, const char *format, va_list ap)
|
||||
assert(alt_form == false);
|
||||
alt_form = true;
|
||||
break;
|
||||
case '0':
|
||||
assert(zero_pad == false);
|
||||
zero_pad = true;
|
||||
break;
|
||||
case '-':
|
||||
assert(left_justify == false);
|
||||
left_justify = true;
|
||||
|
@ -416,12 +416,12 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU,
|
||||
assert((!In64BitMode || HasX86_64) &&
|
||||
"64-bit code requested on a subtarget that doesn't support it!");
|
||||
|
||||
// Stack alignment is 16 bytes on Darwin, FreeBSD, Linux and Solaris (both
|
||||
// 32 and 64 bit) and for all 64-bit targets.
|
||||
// Stack alignment is 16 bytes on Darwin, Linux and Solaris (both 32 and 64
|
||||
// bit) and for all 64-bit targets.
|
||||
if (StackAlignOverride)
|
||||
stackAlignment = StackAlignOverride;
|
||||
else if (isTargetDarwin() || isTargetFreeBSD() || isTargetLinux() ||
|
||||
isTargetSolaris() || In64BitMode)
|
||||
else if (isTargetDarwin() || isTargetLinux() || isTargetSolaris() ||
|
||||
In64BitMode)
|
||||
stackAlignment = 16;
|
||||
}
|
||||
|
||||
|
@ -80,11 +80,11 @@ n or # - change number of processes to display\n", stdout);
|
||||
#ifdef ORDER
|
||||
if (displaymode == DISP_CPU)
|
||||
fputs("\
|
||||
o - specify sort order (pri, size, res, cpu, time, threads, jid)\n",
|
||||
o - specify sort order (pri, size, res, cpu, time, threads, jid, pid)\n",
|
||||
stdout);
|
||||
else
|
||||
fputs("\
|
||||
o - specify sort order (vcsw, ivcsw, read, write, fault, total, jid)\n",
|
||||
o - specify sort order (vcsw, ivcsw, read, write, fault, total, jid, pid)\n",
|
||||
stdout);
|
||||
#endif
|
||||
fputs("\
|
||||
|
@ -1204,7 +1204,7 @@ Rule Zion 2012 only - Sep 23 2:00 0 S
|
||||
# past, approved sending the proposed June 2011 changes to the Time
|
||||
# Decree Law back to the Knesset for second and third (final) votes
|
||||
# before the upcoming elections on Jan. 22, 2013. Hence, although the
|
||||
# changes are not yet law, they are expected to be so before Februray 2013.
|
||||
# changes are not yet law, they are expected to be so before February 2013.
|
||||
#
|
||||
# As of 2013, DST starts at 02:00 on the Friday before the last Sunday in March.
|
||||
# DST ends at 02:00 on the first Sunday after October 1, unless it occurs on the
|
||||
|
@ -2797,6 +2797,13 @@ Zone America/Costa_Rica -5:36:20 - LMT 1890 # San Jose
|
||||
# http://www.timeanddate.com/news/time/cuba-starts-dst-2012.html
|
||||
# </a>
|
||||
|
||||
# From Steffen Thorsen (2012-11-03):
|
||||
# Radio Reloj and many other sources report that Cuba is changing back
|
||||
# to standard time on 2012-11-04:
|
||||
# http://www.radioreloj.cu/index.php/noticias-radio-reloj/36-nacionales/9961-regira-horario-normal-en-cuba-desde-el-domingo-cuatro-de-noviembre
|
||||
# From Paul Eggert (2012-11-03):
|
||||
# For now, assume the future rule is first Sunday in November.
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Cuba 1928 only - Jun 10 0:00 1:00 D
|
||||
Rule Cuba 1928 only - Oct 10 0:00 0 S
|
||||
@ -2834,7 +2841,7 @@ Rule Cuba 2009 2010 - Mar Sun>=8 0:00s 1:00 D
|
||||
Rule Cuba 2011 only - Mar Sun>=15 0:00s 1:00 D
|
||||
Rule Cuba 2011 only - Nov 13 0:00s 0 S
|
||||
Rule Cuba 2012 only - Apr 1 0:00s 1:00 D
|
||||
Rule Cuba 2012 max - Oct lastSun 0:00s 0 S
|
||||
Rule Cuba 2012 max - Nov Sun>=1 0:00s 0 S
|
||||
Rule Cuba 2013 max - Mar Sun>=8 0:00s 1:00 D
|
||||
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
|
@ -123,4 +123,5 @@ else
|
||||
fi
|
||||
|
||||
load_rc_config pccard_ether
|
||||
load_rc_config network
|
||||
run_rc_command $args
|
||||
|
@ -212,6 +212,11 @@ _libproc= libproc
|
||||
_librtld_db= librtld_db
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "powerpc"
|
||||
_libproc= libproc
|
||||
_librtld_db= librtld_db
|
||||
.endif
|
||||
|
||||
.if ${MK_OPENSSL} != "no"
|
||||
_libmp= libmp
|
||||
.endif
|
||||
|
@ -33,8 +33,14 @@
|
||||
/*
|
||||
* XXX These routines belong in libm, but they must remain in libc for
|
||||
* binary compat until we can bump libm's major version number.
|
||||
*
|
||||
* Note this only applies to the dynamic versions of libm and libc, so
|
||||
* for the static and profiled versions we stub out the definitions.
|
||||
* Otherwise you cannot link statically to libm and libc at the same
|
||||
* time, when calling both functions.
|
||||
*/
|
||||
|
||||
#ifdef PIC
|
||||
__weak_reference(__isnan, isnan);
|
||||
__weak_reference(__isnanf, isnanf);
|
||||
|
||||
@ -55,3 +61,4 @@ __isnanf(float f)
|
||||
u.f = f;
|
||||
return (u.bits.exp == 255 && u.bits.man != 0);
|
||||
}
|
||||
#endif /* PIC */
|
||||
|
@ -267,7 +267,7 @@ number produced by a signed conversion.
|
||||
A
|
||||
.Cm +
|
||||
overrides a space if both are used.
|
||||
.It Sq Cm '
|
||||
.It So "'" Sc (apostrophe)
|
||||
Decimal conversions
|
||||
.Cm ( d , u ,
|
||||
or
|
||||
|
10
lib/libcrypt/tests/Makefile
Normal file
10
lib/libcrypt/tests/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# $FreeBSD$
|
||||
|
||||
# exercise libcrypt
|
||||
|
||||
TESTS_C= crypt_tests
|
||||
|
||||
CFLAGS+= -I${.CURDIR:H}
|
||||
LDADD+= -L${.OBJDIR:H} -lcrypt
|
||||
|
||||
.include <atf.test.mk>
|
54
lib/libcrypt/tests/crypt_tests.c
Normal file
54
lib/libcrypt/tests/crypt_tests.c
Normal file
@ -0,0 +1,54 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <crypt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
#define LEET "0.s0.l33t"
|
||||
|
||||
ATF_TC(md5);
|
||||
ATF_TC_HEAD(md5, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Tests the MD5 based password hash");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(md5, tc)
|
||||
{
|
||||
const char want[] = "$1$deadbeef$0Huu6KHrKLVWfqa4WljDE0";
|
||||
char *pw;
|
||||
|
||||
pw = crypt(LEET, want);
|
||||
ATF_CHECK_STREQ(pw, want);
|
||||
}
|
||||
|
||||
ATF_TC(invalid);
|
||||
ATF_TC_HEAD(invalid, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Tests that invalid password fails");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(invalid, tc)
|
||||
{
|
||||
const char want[] = "$1$cafebabe$0Huu6KHrKLVWfqa4WljDE0";
|
||||
char *pw;
|
||||
|
||||
pw = crypt(LEET, want);
|
||||
ATF_CHECK(strcmp(pw, want) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function must not do anything except enumerate
|
||||
* the test cases, else atf-run is likely to be upset.
|
||||
*/
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
ATF_TP_ADD_TC(tp, md5);
|
||||
ATF_TP_ADD_TC(tp, invalid);
|
||||
return atf_no_error();
|
||||
}
|
@ -47,6 +47,9 @@ __FBSDID("$FreeBSD$");
|
||||
#elif defined(__mips__)
|
||||
#define BREAKPOINT_INSTR 0xd /* break */
|
||||
#define BREAKPOINT_INSTR_SZ 4
|
||||
#elif defined(__powerpc__)
|
||||
#define BREAKPOINT_INSTR 0x7fe00008 /* trap */
|
||||
#define BREAKPOINT_INSTR_SZ 4
|
||||
#else
|
||||
#error "Add support for your architecture"
|
||||
#endif
|
||||
|
@ -60,6 +60,8 @@ proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue)
|
||||
*regvalue = regs.r_eip;
|
||||
#elif defined(__mips__)
|
||||
*regvalue = regs.r_regs[PC];
|
||||
#elif defined(__powerpc__)
|
||||
*regvalue = regs.pc;
|
||||
#endif
|
||||
break;
|
||||
case REG_SP:
|
||||
@ -69,6 +71,8 @@ proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue)
|
||||
*regvalue = regs.r_esp;
|
||||
#elif defined(__mips__)
|
||||
*regvalue = regs.r_regs[SP];
|
||||
#elif defined(__powerpc__)
|
||||
*regvalue = regs.fixreg[1];
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
@ -99,6 +103,8 @@ proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue)
|
||||
regs.r_eip = regvalue;
|
||||
#elif defined(__mips__)
|
||||
regs.r_regs[PC] = regvalue;
|
||||
#elif defined(__powerpc__)
|
||||
regs.pc = regvalue;
|
||||
#endif
|
||||
break;
|
||||
case REG_SP:
|
||||
@ -108,6 +114,8 @@ proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue)
|
||||
regs.r_esp = regvalue;
|
||||
#elif defined(__mips__)
|
||||
regs.r_regs[PC] = regvalue;
|
||||
#elif defined(__powerpc__)
|
||||
regs.fixreg[1] = regvalue;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
|
||||
* z = (z-x[i])*2**24
|
||||
*
|
||||
*
|
||||
* y[] ouput result in an array of double precision numbers.
|
||||
* y[] output result in an array of double precision numbers.
|
||||
* The dimension of y[] is:
|
||||
* 24-bit precision 1
|
||||
* 53-bit precision 2
|
||||
|
@ -30,8 +30,9 @@
|
||||
|
||||
#include "fpmath.h"
|
||||
|
||||
/* Provided by libc */
|
||||
#if 0
|
||||
/* Provided by libc.so */
|
||||
#ifndef PIC
|
||||
#undef isnan
|
||||
int
|
||||
isnan(double d)
|
||||
{
|
||||
@ -40,7 +41,7 @@ isnan(double d)
|
||||
u.d = d;
|
||||
return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0));
|
||||
}
|
||||
#endif
|
||||
#endif /* !PIC */
|
||||
|
||||
int
|
||||
__isnanf(float f)
|
||||
|
@ -83,7 +83,7 @@ kernel.txz:
|
||||
src.txz:
|
||||
mkdir -p ${DISTDIR}/usr
|
||||
ln -fs ${WORLDDIR} ${DISTDIR}/usr/src
|
||||
cd ${DISTDIR} && tar cLvJf ${.OBJDIR}/src.txz --exclude .svn \
|
||||
cd ${DISTDIR} && tar cLvJf ${.OBJDIR}/src.txz --exclude .svn --exclude .zfs \
|
||||
--exclude CVS --exclude @ --exclude usr/src/release/dist usr/src
|
||||
|
||||
ports.txz:
|
||||
|
@ -6,23 +6,23 @@
|
||||
|
||||
<!-- Version of the OS we're describing. This needs to be updated
|
||||
with each new release. -->
|
||||
<!ENTITY release.current "9.0-CURRENT">
|
||||
<!ENTITY release.current "10.0-CURRENT">
|
||||
|
||||
<!-- The previous version used for comparison in the "What's New"
|
||||
section. For -CURRENT, we might point back to the last
|
||||
branchpoint. -->
|
||||
<!ENTITY release.prev "8.0-RELEASE">
|
||||
<!ENTITY release.prev "9.0-RELEASE">
|
||||
|
||||
<!-- The previous stable release, useful for pointing user's at the
|
||||
release they SHOULD be running if they don't want the bleeding
|
||||
edge. -->
|
||||
<!ENTITY release.prev.stable "8.0-RELEASE">
|
||||
<!ENTITY release.prev.stable "8.3-RELEASE">
|
||||
|
||||
<!-- The next version to be released, usually used for snapshots. -->
|
||||
<!ENTITY release.next "9.0-RELEASE">
|
||||
<!ENTITY release.next "9.1-RELEASE">
|
||||
|
||||
<!-- The name of this branch. -->
|
||||
<!ENTITY release.branch "9-CURRENT">
|
||||
<!ENTITY release.branch "10-CURRENT">
|
||||
|
||||
<!-- The URL for obtaining this version of FreeBSD. -->
|
||||
<!ENTITY release.url "http://www.FreeBSD.org/snapshots/">
|
||||
@ -39,7 +39,7 @@
|
||||
<!ENTITY release.manpath.xorg "7.5.1">
|
||||
<!ENTITY release.manpath.netbsd "5.1">
|
||||
<!ENTITY release.manpath.freebsd-ports "Ports">
|
||||
<!ENTITY release.manpath.freebsd "9-current">
|
||||
<!ENTITY release.manpath.freebsd "10-current">
|
||||
|
||||
<!-- Text constants which probably don't need to be changed.-->
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd July 9, 2012
|
||||
.Dd November 7, 2012
|
||||
.Dt IFCONFIG 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -142,7 +142,7 @@ The link-level
|
||||
address
|
||||
is specified as a series of colon-separated hex digits.
|
||||
This can be used to
|
||||
e.g.\& set a new MAC address on an ethernet interface, though the
|
||||
e.g.,\& set a new MAC address on an ethernet interface, though the
|
||||
mechanism used is not ethernet-specific.
|
||||
If the interface is already
|
||||
up when this option is used, it will be briefly brought down and
|
||||
@ -301,7 +301,7 @@ Specify interface FIB.
|
||||
A FIB
|
||||
.Ar fib_number
|
||||
is assigned to all frames or packets received on that interface.
|
||||
The FIB is not inherited, e.g. vlans or other sub-interfaces will use
|
||||
The FIB is not inherited, e.g., vlans or other sub-interfaces will use
|
||||
the default FIB (0) irrespective of the parent interface's FIB.
|
||||
The kernel needs to be tuned to support more than the default FIB
|
||||
using the
|
||||
@ -1003,7 +1003,7 @@ For example, if a device is capable of operating on channel 6
|
||||
with 802.11n and 802.11g then one can specify that g-only use
|
||||
should be used by specifying ``6:g''.
|
||||
Similarly the channel width can be specified by appending it
|
||||
with ``/''; e.g. ``6/40'' specifies a 40MHz wide channel,
|
||||
with ``/''; e.g., ``6/40'' specifies a 40MHz wide channel,
|
||||
These attributes can be combined as in: ``6:ht/40''.
|
||||
The full set of flags specified following a ``:'' are:
|
||||
.Cm a
|
||||
@ -1036,7 +1036,7 @@ and
|
||||
In addition,
|
||||
a 40MHz HT channel specification may include the location
|
||||
of the extension channel by appending ``+'' or ``-'' for above and below,
|
||||
respectively; e.g. ``2437:ht/40+'' specifies 40MHz wide HT operation
|
||||
respectively; e.g., ``2437:ht/40+'' specifies 40MHz wide HT operation
|
||||
with the center channel at frequency 2437 and the extension channel above.
|
||||
.It Cm country Ar name
|
||||
Set the country code to use in calculating the regulatory constraints
|
||||
@ -1046,7 +1046,7 @@ will operation on the channels, and the maximum transmit power that
|
||||
can be used on a channel are defined by this setting.
|
||||
Country/Region codes are specified as a 2-character abbreviation
|
||||
defined by ISO 3166 or using a longer, but possibly ambiguous, spelling;
|
||||
e.g. "ES" and "Spain".
|
||||
e.g., "ES" and "Spain".
|
||||
The set of country codes are taken from /etc/regdomain.xml and can also
|
||||
be viewed with the ``list countries'' request.
|
||||
Note that not all devices support changing the country code from a default
|
||||
@ -1063,7 +1063,7 @@ DFS embodies several facilities including detection of overlapping
|
||||
radar signals, dynamic transmit power control, and channel selection
|
||||
according to a least-congested criteria.
|
||||
DFS support is mandatory for some 5GHz frequencies in certain
|
||||
locales (e.g. ETSI).
|
||||
locales (e.g., ETSI).
|
||||
By default DFS is enabled according to the regulatory definitions
|
||||
specified in /etc/regdomain.xml and the current country code, regdomain,
|
||||
and channel.
|
||||
@ -1115,7 +1115,7 @@ specifies the number of beacon intervals between DTIM
|
||||
and must be in the range 1 to 15.
|
||||
By default DTIM is 1 (i.e., DTIM occurs at each beacon).
|
||||
.It Cm quiet
|
||||
Enable the use of quiet IE. Hostap will use this to silent other
|
||||
Enable the use of quiet IE. Hostap will use this to silence other
|
||||
stations to reduce interference for radar detection when
|
||||
operating on 5GHz frequency and doth support is enabled.
|
||||
Use
|
||||
@ -1168,7 +1168,7 @@ Enable Dynamic WDS (DWDS) support.
|
||||
DWDS is a facility by which 4-address traffic can be carried between
|
||||
stations operating in infrastructure mode.
|
||||
A station first associates to an access point and authenticates using
|
||||
normal procedures (e.g. WPA).
|
||||
normal procedures (e.g., WPA).
|
||||
Then 4-address frames are passed to carry traffic for stations
|
||||
operating on either side of the wireless link.
|
||||
DWDS extends the normal WDS mechanism by leveraging existing security
|
||||
@ -1186,7 +1186,7 @@ When DWDS is enabled on a station, traffic with a destination address
|
||||
different from the peer station are encapsulated in a 4-address frame
|
||||
and transmitted to the peer.
|
||||
All 4-address traffic uses the security information of the stations
|
||||
(e.g. cryptographic keys).
|
||||
(e.g., cryptographic keys).
|
||||
A station is associated using 802.11n facilities may transport
|
||||
4-address traffic using these same mechanisms; this depends on available
|
||||
resources and capabilities of the device.
|
||||
@ -1236,7 +1236,7 @@ Stations negotiate use of these facilities, termed HT20 and HT40,
|
||||
when they associate.
|
||||
To disable all use of 802.11n use
|
||||
.Fl ht .
|
||||
To disable use of HT20 (e.g. to force only HT40 use) use
|
||||
To disable use of HT20 (e.g., to force only HT40 use) use
|
||||
.Fl ht20 .
|
||||
To disable use of HT40 use
|
||||
.Fl ht40 .
|
||||
@ -1250,7 +1250,7 @@ Auto Channel Selection is used to locate a channel to operate on,
|
||||
HT configuration controls whether legacy, HT20, or HT40 operation is setup
|
||||
on the selected channel.
|
||||
If a fixed channel is specified for a station then HT configuration can
|
||||
be given as part of the channel specification; e.g. 6:ht/20 to setup
|
||||
be given as part of the channel specification; e.g., 6:ht/20 to setup
|
||||
HT20 operation on channel 6.
|
||||
.It Cm htcompat
|
||||
Enable use of compatibility support for pre-802.11n devices (default).
|
||||
@ -1506,13 +1506,13 @@ The default setting is 6 but drivers may override this with a value
|
||||
they choose.
|
||||
.It Cm mcastrate Ar rate
|
||||
Set the rate for transmitting multicast/broadcast frames.
|
||||
Rates are specified as megabits/second in decimal; e.g.\& 5.5 for 5.5 Mb/s.
|
||||
Rates are specified as megabits/second in decimal; e.g.,\& 5.5 for 5.5 Mb/s.
|
||||
This rate should be valid for the current operating conditions;
|
||||
if an invalid rate is specified drivers are free to chose an
|
||||
appropriate rate.
|
||||
.It Cm mgtrate Ar rate
|
||||
Set the rate for transmitting management and/or control frames.
|
||||
Rates are specified as megabits/second in decimal; e.g.\& 5.5 for 5.5 Mb/s.
|
||||
Rates are specified as megabits/second in decimal; e.g.,\& 5.5 for 5.5 Mb/s.
|
||||
.It Cm outdoor
|
||||
Set the location to use in calculating regulatory constraints.
|
||||
The location is also advertised in beacon and probe response frames
|
||||
@ -1672,7 +1672,7 @@ request can be used to show recent scan results without
|
||||
initiating a new scan.
|
||||
.It Cm scanvalid Ar threshold
|
||||
Set the maximum time the scan cache contents are considered valid;
|
||||
i.e. will be used without first triggering a scan operation to
|
||||
i.e., will be used without first triggering a scan operation to
|
||||
refresh the data.
|
||||
The
|
||||
.Ar threshold
|
||||
@ -1734,7 +1734,7 @@ When operating with TDMA, setup a BSS with
|
||||
slots.
|
||||
The slot count may be at most 8.
|
||||
The current implementation is only tested with two stations
|
||||
(i.e. point to point applications).
|
||||
(i.e., point to point applications).
|
||||
This setting is only meaningful when a station is configured as slot 0;
|
||||
other stations adopt this setting from the BSS they join.
|
||||
By default
|
||||
@ -1758,7 +1758,7 @@ is set to 10 milliseconds.
|
||||
When operating with TDMA, setup a BSS such that beacons are transmitted every
|
||||
.Ar intval
|
||||
superframes to synchronize the TDMA slot timing.
|
||||
A superframe is defined as the number of slots times the slot length; e.g.
|
||||
A superframe is defined as the number of slots times the slot length; e.g.,
|
||||
a BSS with two slots of 10 milliseconds has a 20 millisecond superframe.
|
||||
The beacon interval may not be zero.
|
||||
A lower setting of
|
||||
@ -1784,7 +1784,7 @@ the driver will use the setting closest to the specified value.
|
||||
Not all adapters support changing the transmit power.
|
||||
.It Cm ucastrate Ar rate
|
||||
Set a fixed rate for transmitting unicast frames.
|
||||
Rates are specified as megabits/second in decimal; e.g.\& 5.5 for 5.5 Mb/s.
|
||||
Rates are specified as megabits/second in decimal; e.g.,\& 5.5 for 5.5 Mb/s.
|
||||
This rate should be valid for the current operating conditions;
|
||||
if an invalid rate is specified drivers are free to chose an
|
||||
appropriate rate.
|
||||
@ -2519,7 +2519,7 @@ protocol on an interface:
|
||||
Set the virtual host ID.
|
||||
This is a required setting to initiate
|
||||
.Xr carp 4 .
|
||||
If the virtual host ID doesn't exist yet, it is created and attached to the
|
||||
If the virtual host ID does not exist yet, it is created and attached to the
|
||||
interface, otherwise configuration of an existing vhid is adjusted.
|
||||
If the
|
||||
.Cm vhid
|
||||
@ -2628,9 +2628,6 @@ The
|
||||
flag disables this behavior.
|
||||
.Pp
|
||||
Only the super-user may modify the configuration of a network interface.
|
||||
.Sh NOTES
|
||||
The media selection system is relatively new and only some drivers support
|
||||
it (or have need for it).
|
||||
.Sh EXAMPLES
|
||||
Assign the IPv4 address
|
||||
.Li 192.0.2.10 ,
|
||||
@ -2714,7 +2711,9 @@ tried to alter an interface's configuration.
|
||||
.Xr pfsync 4 ,
|
||||
.Xr polling 4 ,
|
||||
.Xr vlan 4 ,
|
||||
.Xr devd.conf 5 ,
|
||||
.\" .Xr eon 5 ,
|
||||
.Xr devd 8 ,
|
||||
.Xr rc 8 ,
|
||||
.Xr routed 8 ,
|
||||
.Xr jail 8 ,
|
||||
|
@ -141,7 +141,7 @@ or in CFB mode.
|
||||
.It Fl o Ar N
|
||||
Use
|
||||
.Ar N Ns \-bit
|
||||
ouput feedback (OFB) mode.
|
||||
output feedback (OFB) mode.
|
||||
Currently
|
||||
.Ar N
|
||||
must be a multiple of 8 between 8 and 64 inclusive (this does not conform
|
||||
|
@ -30,7 +30,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 20, 2004
|
||||
.Dd November 7, 2012
|
||||
.Dt ICMP6 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -234,7 +234,7 @@ calls may be used to obtain and install the filter on ICMPv6 sockets at
|
||||
option level
|
||||
.Dv IPPROTO_ICMPV6
|
||||
and name
|
||||
.Dv ICMPV6_FILTER
|
||||
.Dv ICMP6_FILTER
|
||||
with a pointer to the
|
||||
.Vt icmp6_filter
|
||||
structure as the option value.
|
||||
|
@ -33,7 +33,7 @@
|
||||
.Dt IPSEC 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm IPsec
|
||||
.Nm ipsec
|
||||
.Nd Internet Protocol Security protocol
|
||||
.Sh SYNOPSIS
|
||||
.Cd "options IPSEC"
|
||||
|
@ -1,20 +1,50 @@
|
||||
# $FreeBSD$
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/8/93
|
||||
|
||||
FILES= bsd.README
|
||||
FILES+= bsd.arch.inc.mk
|
||||
FILES+= bsd.compat.mk bsd.compiler.mk bsd.cpu.mk
|
||||
FILES+= bsd.dep.mk bsd.doc.mk bsd.dtrace.mk
|
||||
FILES+= bsd.endian.mk
|
||||
FILES+= bsd.files.mk bsd.crunchgen.mk bsd.incs.mk bsd.info.mk bsd.init.mk
|
||||
FILES+= bsd.kmod.mk
|
||||
FILES+= bsd.lib.mk bsd.libnames.mk bsd.links.mk bsd.man.mk bsd.nls.mk
|
||||
FILES+= bsd.obj.mk bsd.own.mk
|
||||
FILES+= bsd.port.mk bsd.port.options.mk bsd.port.post.mk
|
||||
FILES+= bsd.port.pre.mk bsd.port.subdir.mk bsd.prog.mk
|
||||
FILES+= bsd.snmpmod.mk bsd.subdir.mk bsd.sys.mk bsd.symver.mk
|
||||
FILES+= sys.mk version_gen.awk
|
||||
.include <bsd.own.mk>
|
||||
|
||||
FILES= \
|
||||
bsd.README \
|
||||
bsd.arch.inc.mk \
|
||||
bsd.compat.mk \
|
||||
bsd.compiler.mk \
|
||||
bsd.cpu.mk \
|
||||
bsd.crunchgen.mk \
|
||||
bsd.dep.mk \
|
||||
bsd.doc.mk \
|
||||
bsd.dtrace.mk \
|
||||
bsd.endian.mk \
|
||||
bsd.files.mk \
|
||||
bsd.incs.mk \
|
||||
bsd.info.mk \
|
||||
bsd.init.mk \
|
||||
bsd.kmod.mk \
|
||||
bsd.lib.mk \
|
||||
bsd.libnames.mk \
|
||||
bsd.links.mk \
|
||||
bsd.man.mk \
|
||||
bsd.nls.mk \
|
||||
bsd.obj.mk \
|
||||
bsd.own.mk \
|
||||
bsd.port.mk \
|
||||
bsd.port.options.mk \
|
||||
bsd.port.post.mk \
|
||||
bsd.port.pre.mk \
|
||||
bsd.port.subdir.mk \
|
||||
bsd.prog.mk \
|
||||
bsd.snmpmod.mk \
|
||||
bsd.subdir.mk \
|
||||
bsd.symver.mk \
|
||||
bsd.sys.mk \
|
||||
bsd.test.mk \
|
||||
sys.mk \
|
||||
version_gen.awk
|
||||
|
||||
NO_OBJ=
|
||||
FILESDIR= ${BINDIR}/mk
|
||||
|
||||
.if ${MK_ATF} != "no"
|
||||
FILES+= atf.test.mk
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
148
share/mk/atf.test.mk
Normal file
148
share/mk/atf.test.mk
Normal file
@ -0,0 +1,148 @@
|
||||
# $NetBSD$
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
.include <bsd.init.mk>
|
||||
|
||||
ATF_TESTS:=
|
||||
|
||||
.if make(*test)
|
||||
TESTSDIR?= .
|
||||
.endif
|
||||
|
||||
.if defined(ATF_TESTS_SUBDIRS)
|
||||
# Only visit subdirs when building, etc because ATF does this it on its own.
|
||||
.if !make(atf-test)
|
||||
SUBDIR+= ${ATF_TESTS_SUBDIRS}
|
||||
.endif
|
||||
ATF_TESTS+= ${ATF_TESTS_SUBDIRS}
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
.endif
|
||||
|
||||
.if defined(TESTS_C)
|
||||
ATF_TESTS+= ${TESTS_C}
|
||||
.for _T in ${TESTS_C}
|
||||
SRCS.${_T}?= ${_T}.c
|
||||
DPADD.${_T}+= ${LIBATF_C}
|
||||
LDADD.${_T}+= -latf-c
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.if defined(TESTS_CXX)
|
||||
ATF_TESTS+= ${TESTS_CXX}
|
||||
.for _T in ${TESTS_CXX}
|
||||
SRCS.${_T}?= ${_T}${CXX_SUFFIX:U.cc}
|
||||
DPADD.${_T}+= ${LIBATF_CXX} ${LIBATF_C}
|
||||
LDADD.${_T}+= -latf-c++ -latf-c
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.if defined(TESTS_SH)
|
||||
ATF_TESTS+= ${TESTS_SH}
|
||||
.for _T in ${TESTS_SH}
|
||||
CLEANFILES+= ${_T} ${_T}.tmp
|
||||
TESTS_SH_SRC_${_T}?= ${_T}.sh
|
||||
${_T}: ${TESTS_SH_SRC_${_T}}
|
||||
echo '#! /usr/bin/atf-sh' > ${.TARGET}.tmp
|
||||
cat ${.ALLSRC} >> ${.TARGET}.tmp
|
||||
chmod +x ${.TARGET}.tmp
|
||||
mv ${.TARGET}.tmp ${.TARGET}
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
ATFFILE?= auto
|
||||
|
||||
.if ${ATFFILE:tl} != "no"
|
||||
FILES+= Atffile
|
||||
FILESDIR_Atffile= ${TESTSDIR}
|
||||
|
||||
.if ${ATFFILE:tl} == "auto"
|
||||
CLEANFILES+= Atffile Atffile.tmp
|
||||
|
||||
Atffile: Makefile
|
||||
@{ echo 'Content-Type: application/X-atf-atffile; version="1"'; \
|
||||
echo; \
|
||||
echo '# Automatically generated by atf-test.mk.'; \
|
||||
echo; \
|
||||
echo 'prop: test-suite = "'`uname -o`'"'; \
|
||||
echo; \
|
||||
for tp in ${ATF_TESTS}; do \
|
||||
echo "tp: $${tp}"; \
|
||||
done; } >Atffile.tmp
|
||||
@mv Atffile.tmp Atffile
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# Generate support variables for atf-test.
|
||||
#
|
||||
# atf-test can only work for native builds, i.e. a build host of a particular
|
||||
# OS building a release for the same OS version and architecture. The target
|
||||
# runs ATF, which is on the build host, and the tests execute code built for
|
||||
# the target host.
|
||||
#
|
||||
# Due to the dependencies of the binaries built by the source tree and how they
|
||||
# are used by tests, it is highly possible for a execution of "make test" to
|
||||
# report bogus results unless the new binaries are put in place.
|
||||
|
||||
# XXX (gcooper): Executing ATF from outside the source tree is improper; it
|
||||
# should be built as part of the OS toolchain build for the host OS and
|
||||
# executed from there.
|
||||
ATF_PATH+= ${DESTDIR}/bin ${DESTDIR}/sbin ${DESTDIR}/usr/bin ${DESTDIR}/usr/sbin
|
||||
TESTS_ENV+= PATH=${ATF_PATH:ts:}:${PATH}
|
||||
|
||||
ATF_BUILD_CC?= ${DESTDIR}/usr/bin/cc
|
||||
ATF_BUILD_CPP?= ${DESTDIR}/usr/bin/cpp
|
||||
ATF_BUILD_CXX?= ${DESTDIR}/usr/bin/c++
|
||||
ATF_CONFDIR?= ${DESTDIR}/etc
|
||||
ATF_INCLUDEDIR?= ${DESTDIR}/usr/include
|
||||
ATF_LIBDIR?= ${DESTDIR}/usr/lib
|
||||
ATF_LIBEXECDIR?= ${DESTDIR}/usr/libexec
|
||||
ATF_PKGDATADIR?= ${DESTDIR}/usr/share/atf
|
||||
ATF_SHELL?= ${DESTDIR}/bin/sh
|
||||
LD_LIBRARY_PATH?= ${TESTS_LD_LIBRARY_PATH:tW:S/ /:/g}
|
||||
|
||||
ATF_ENV_VARS= \
|
||||
ATF_BUILD_CC \
|
||||
ATF_BUILD_CPP \
|
||||
ATF_BUILD_CXX \
|
||||
ATF_CONFDIR \
|
||||
ATF_INCLUDEDIR \
|
||||
ATF_LIBDIR \
|
||||
ATF_LIBEXECDIR \
|
||||
ATF_PKGDATADIR \
|
||||
ATF_SHELL \
|
||||
|
||||
.for v in ${ATF_ENV_VARS}
|
||||
.if !empty($v)
|
||||
TESTS_ENV+= $v=${$v}
|
||||
.endif
|
||||
.endfor
|
||||
|
||||
_TESTS_FIFO= ${.OBJDIR}/atf-run.fifo
|
||||
_TESTS_LOG= ${.OBJDIR}/atf-run.log
|
||||
CLEANFILES+= ${_TESTS_FIFO} ${_TESTS_LOG}
|
||||
|
||||
ATF_BIN?= ${DESTDIR}/usr/bin
|
||||
ATF_REPORT?= ${ATF_BIN}/atf-report
|
||||
ATF_RUN?= ${ATF_BIN}/atf-run
|
||||
|
||||
.PHONY: realtest
|
||||
realtest:
|
||||
.if defined(TESTSDIR)
|
||||
@set -e; \
|
||||
cd ${DESTDIR}${TESTSDIR}; \
|
||||
rm -f ${_TESTS_FIFO}; \
|
||||
mkfifo ${_TESTS_FIFO}; \
|
||||
tee ${_TESTS_LOG} < ${_TESTS_FIFO} | ${TESTS_ENV} ${ATF_REPORT} & \
|
||||
set +e; \
|
||||
${TESTS_ENV} ${ATF_RUN} >> ${_TESTS_FIFO}; \
|
||||
result=$${?}; \
|
||||
wait; \
|
||||
rm -f ${_TESTS_FIFO}; \
|
||||
echo; \
|
||||
echo "*** The verbatim output of atf-run has been saved to ${_TESTS_LOG}"; \
|
||||
exit $${result}
|
||||
.endif
|
||||
|
||||
.include <bsd.test.mk>
|
@ -1,350 +1,88 @@
|
||||
# from: @(#)bsd.prog.mk 5.26 (Berkeley) 6/25/91
|
||||
# $FreeBSD$
|
||||
# $Id: progs.mk,v 1.11 2012/11/06 17:18:54 sjg Exp $
|
||||
#
|
||||
# @(#) Copyright (c) 2006, Simon J. Gerraty
|
||||
#
|
||||
# This file is provided in the hope that it will
|
||||
# be of use. There is absolutely NO WARRANTY.
|
||||
# Permission to copy, redistribute or otherwise
|
||||
# use this file is hereby granted provided that
|
||||
# the above copyright notice and this notice are
|
||||
# left intact.
|
||||
#
|
||||
# Please send copies of changes and bug-fixes to:
|
||||
# sjg@crufty.net
|
||||
#
|
||||
|
||||
.include <bsd.init.mk>
|
||||
.MAIN: all
|
||||
|
||||
.SUFFIXES: .out .o .c .cc .cpp .cxx .C .m .y .l .ln .s .S .asm
|
||||
.if defined(PROGS)
|
||||
|
||||
.if ${MK_MAN} == "no"
|
||||
NO_MAN=
|
||||
# In meta mode, we can capture dependenices for _one_ of the progs.
|
||||
# if makefile doesn't nominate one, we use the first.
|
||||
.ifndef UPDATE_DEPENDFILE_PROG
|
||||
UPDATE_DEPENDFILE_PROG = ${PROGS:[1]}
|
||||
.export UPDATE_DEPENDFILE_PROG
|
||||
.endif
|
||||
|
||||
# Legacy knobs
|
||||
.if defined(PROG) || defined(PROG_CXX)
|
||||
. if defined(PROG)
|
||||
PROGS= ${PROG}
|
||||
. endif
|
||||
. if defined(PROG_CXX)
|
||||
PROGS= ${PROG_CXX}
|
||||
PROGS_CXX= ${PROG_CXX}
|
||||
. endif
|
||||
# Loop once to keep pattern and avoid namespace pollution
|
||||
. for _P in ${PROGS}
|
||||
. if defined(INTERNALPROG)
|
||||
INTERNALPROG.${_P}=
|
||||
. endif
|
||||
. if !defined(NO_MAN)
|
||||
. if defined(MAN)
|
||||
MAN.${_P}= ${MAN}
|
||||
. else
|
||||
. for sect in 1 1aout 2 3 4 5 6 7 8 9
|
||||
. if defined(MAN${sect})
|
||||
MAN.${_P}= ${MAN${sect}}
|
||||
. endif
|
||||
. endfor
|
||||
. endif
|
||||
. endif # defined(NO_MAN)
|
||||
. if defined(NLSNAME) && !empty(NLSNAME)
|
||||
NLSNAME.${P}:= ${NLSNAME}
|
||||
. endif
|
||||
. if defined(OBJS)
|
||||
OBJS.${_P}:= ${OBJS}
|
||||
. endif
|
||||
. if defined(PRECIOUSPROG)
|
||||
PRECIOUSPROG.${_P}=
|
||||
. endif
|
||||
. if defined(PROGNAME)
|
||||
PROGNAME.${_P}= ${PROGNAME}
|
||||
. endif
|
||||
. if defined(SRCS)
|
||||
SRCS.${_P}:= ${SRCS}
|
||||
. endif
|
||||
. endfor
|
||||
.else # !defined(PROG) && !defined(PROG_CXX)
|
||||
. if defined(PROGS_CXX) && !empty(PROGS_CXX)
|
||||
PROGS+= ${PROGS_CXX}
|
||||
. endif
|
||||
.endif # defined(PROG) || defined(PROG_CXX)
|
||||
|
||||
.if defined(PROGS_CXX) && !empty(PROGS_CXX)
|
||||
. for _P in ${PROGS_CXX}
|
||||
PROG_CXX.${_P}=
|
||||
. endfor
|
||||
.ifndef PROG
|
||||
# They may have asked us to build just one
|
||||
.for t in ${PROGS}
|
||||
.if make($t)
|
||||
PROG ?= $t
|
||||
.endif
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
# Avoid recursive variables
|
||||
.undef NLSNAME
|
||||
|
||||
.if defined(COPTS)
|
||||
CFLAGS+=${COPTS}
|
||||
.endif
|
||||
|
||||
.if defined(DEBUG_FLAGS)
|
||||
. if ${MK_CTF} != "no" && ${DEBUG_FLAGS:M-g} != ""
|
||||
CTFFLAGS+= -g
|
||||
. endif
|
||||
CFLAGS+=${DEBUG_FLAGS}
|
||||
CXXFLAGS+=${DEBUG_FLAGS}
|
||||
.endif
|
||||
|
||||
STRIP?= -s
|
||||
|
||||
.if ${MK_ASSERT_DEBUG} == "no"
|
||||
CFLAGS+= -DNDEBUG
|
||||
NO_WERROR=
|
||||
.endif
|
||||
|
||||
.for _P in ${PROGS}
|
||||
|
||||
BINDIR.${_P}?= ${BINDIR}
|
||||
BINGRP.${_P}?= ${BINGRP}
|
||||
BINMODE.${_P}?= ${BINMODE}
|
||||
BINOWN.${_P}?= ${BINOWN}
|
||||
|
||||
CFLAGS.${_P}+= ${CFLAGS}
|
||||
CXXFLAGS.${_P}+= ${CXXFLAGS}
|
||||
DPADD.${_P}+= ${DPADD}
|
||||
LDADD.${_P}+= ${LDADD}
|
||||
LDFLAGS.${_P}+= ${LDFLAGS}
|
||||
|
||||
INSTALLFLAGS.${_P}?= ${INSTALLFLAGS}
|
||||
|
||||
. if defined(PRECIOUSPROG.${_P})
|
||||
. if !defined(NO_FSCHG) && !defined(NO_FSCHG.${_P})
|
||||
INSTALLFLAGS.${_P}+= -fschg
|
||||
. endif
|
||||
INSTALLFLAGS.${_P}+= -S
|
||||
. endif
|
||||
|
||||
NO_SHARED.${_P}?= ${NO_SHARED}
|
||||
|
||||
. if !defined(NLSDIR.${_P})
|
||||
NLSDIR.${_P}:= ${NLSDIR}
|
||||
. endif
|
||||
. undef NLSDIR
|
||||
|
||||
. if !empty(NO_SHARED.${_P}) && ${NO_SHARED.${_P}:tl} != "no"
|
||||
LDFLAGS.${_P}+= -static
|
||||
. endif
|
||||
|
||||
. if defined(SRCS.${_P})
|
||||
|
||||
_SRCS:= ${SRCS.${_P}}
|
||||
OBJS.${_P}+= ${_SRCS:N*.h:R:S/$/.o/g}
|
||||
|
||||
. if target(beforelinking)
|
||||
${_P}: ${OBJS.${_P}} beforelinking
|
||||
. else
|
||||
${_P}: ${OBJS.${_P}}
|
||||
. endif
|
||||
. if defined(PROG_CXX.${_P})
|
||||
${CXX} ${CXXFLAGS.${_P}} ${LDFLAGS.${_P}} -o ${.TARGET} ${OBJS.${_P}} \
|
||||
${LDADD.${_P}}
|
||||
. else
|
||||
${CC} ${CFLAGS.${_P}} ${LDFLAGS.${_P}} -o ${.TARGET} ${OBJS.${_P}} \
|
||||
${LDADD.${_P}}
|
||||
. endif
|
||||
. if ${MK_CTF} != "no"
|
||||
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS.${_P}}
|
||||
. endif
|
||||
|
||||
. else # !defined(SRCS.${_P})
|
||||
|
||||
. if !target(${_P})
|
||||
. if defined(PROG_CXX.${_P})
|
||||
SRCS.${_P}?= ${_P}.cc
|
||||
. else
|
||||
SRCS.${_P}?= ${_P}.c
|
||||
. endif
|
||||
|
||||
# Always make an intermediate object file because:
|
||||
# - it saves time rebuilding when only the library has changed
|
||||
# - the name of the object gets put into the executable symbol table instead of
|
||||
# the name of a variable temporary object.
|
||||
# - it's useful to keep objects around for crunching.
|
||||
OBJS.${_P}:= ${_P}.o
|
||||
|
||||
. if target(beforelinking)
|
||||
${_P}: ${OBJS.${_P}} beforelinking
|
||||
. else
|
||||
${_P}: ${OBJS.${_P}}
|
||||
. endif # target(beforelinking)
|
||||
. if defined(PROG_CXX.${_P})
|
||||
${CXX} ${CXXFLAGS.${_P}} ${LDFLAGS.${_P}} -o ${.TARGET} ${OBJS.${_P}} \
|
||||
${LDADD.${_P}}
|
||||
. else
|
||||
${CC} ${CFLAGS.${_P}} ${LDFLAGS.${_P}} -o ${.TARGET} ${OBJS.${_P}} \
|
||||
${LDADD.${_P}}
|
||||
. endif
|
||||
. if ${MK_CTF} != "no"
|
||||
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS.${_P}}
|
||||
. endif
|
||||
|
||||
. endif # !target(${_P})
|
||||
|
||||
. endif # defined(SRCS.${_P})
|
||||
|
||||
CLEANFILES+= ${OBJS.${_P}}
|
||||
|
||||
.endfor # for _P in ${PROGS}
|
||||
|
||||
all: objwarn ${PROGS} ${SCRIPTS}
|
||||
|
||||
.if !defined(NO_MAN)
|
||||
. for _P in ${PROGS}
|
||||
MAN.${_P}?= ${_P}.1
|
||||
MAN:= ${MAN.${_P}}
|
||||
. include <bsd.man.mk>
|
||||
. endfor
|
||||
. if target(_manpages) # bsd.man.mk was included
|
||||
all: _manpages
|
||||
. endif
|
||||
.endif
|
||||
|
||||
CLEANFILES+= ${PROGS}
|
||||
|
||||
.include <bsd.libnames.mk>
|
||||
|
||||
_EXTRADEPEND:
|
||||
.for _P in ${PROGS}
|
||||
. if !empty(LDFLAGS.${P}:M-nostdlib)
|
||||
. if !empty(DPADD.${_P})
|
||||
echo ${_P}: ${DPADD.${_P}} >> ${DEPENDFILE}
|
||||
. endif
|
||||
. else
|
||||
echo ${_P}: ${LIBC} ${DPADD.${_P}} >> ${DEPENDFILE}
|
||||
. if defined(PROG_CXX.${_P})
|
||||
. if !empty(CXXFLAGS.${P}:M-stdlib=libc++)
|
||||
echo ${_P}: ${LIBCPLUSPLUS} >> ${DEPENDFILE}
|
||||
. else
|
||||
echo ${_P}: ${LIBSTDCPLUSPLUS} >> ${DEPENDFILE}
|
||||
. endif
|
||||
. endif
|
||||
. endif
|
||||
.if defined(PROG)
|
||||
# just one of many
|
||||
PROG_VARS += CFLAGS CPPFLAGS CXXFLAGS DPADD DPLIBS LDADD MAN SRCS
|
||||
.for v in ${PROG_VARS:O:u}
|
||||
$v += ${${v}_${PROG}:U${${v}.${PROG}}}
|
||||
.endfor
|
||||
|
||||
.if !target(install)
|
||||
# for meta mode, there can be only one!
|
||||
.if ${PROG} == ${UPDATE_DEPENDFILE_PROG:Uno}
|
||||
UPDATE_DEPENDFILE ?= yes
|
||||
.endif
|
||||
UPDATE_DEPENDFILE ?= NO
|
||||
|
||||
. if !target(realinstall)
|
||||
# ensure that we don't clobber each other's dependencies
|
||||
DEPENDFILE?= .depend.${PROG}
|
||||
# prog.mk will do the rest
|
||||
.else
|
||||
all: ${PROGS}
|
||||
|
||||
. for _P in ${PROGS}
|
||||
|
||||
. if !defined(INTERNALPROG.${_P})
|
||||
|
||||
.ORDER: beforeinstall _proginstall.${_P}
|
||||
_proginstall.${_P}:
|
||||
. if defined(PROGNAME.${_P})
|
||||
${INSTALL} ${STRIP} -o ${BINOWN.${_P}} -g ${BINGRP.${_P}} \
|
||||
-m ${BINMODE.${_P}} ${INSTALLFLAGS.${_P}} ${_P} \
|
||||
${DESTDIR}${BINDIR.${_P}}/${PROGNAME.${_P}}
|
||||
. else
|
||||
${INSTALL} ${STRIP} -o ${BINOWN.${_P}} -g ${BINGRP.${_P}} \
|
||||
-m ${BINMODE.${_P}} ${INSTALLFLAGS.${_P}} ${_P} \
|
||||
${DESTDIR}${BINDIR.${_P}}
|
||||
. endif
|
||||
|
||||
realinstall: _proginstall.${_P}
|
||||
|
||||
. endif # !defined(INTERNALPROG.${_P})
|
||||
|
||||
. endfor # for _P in ${PROGS}
|
||||
|
||||
. endif # !target(realinstall)
|
||||
|
||||
. if defined(SCRIPTS) && !empty(SCRIPTS)
|
||||
SCRIPTSDIR?= ${BINDIR}
|
||||
SCRIPTSOWN?= ${BINOWN}
|
||||
SCRIPTSGRP?= ${BINGRP}
|
||||
SCRIPTSMODE?= ${BINMODE}
|
||||
|
||||
. for S in ${SCRIPTS}
|
||||
|
||||
realinstall: scriptsinstall
|
||||
.ORDER: beforeinstall scriptsinstall
|
||||
|
||||
. if defined(SCRIPTSNAME)
|
||||
SCRIPTSNAME_${S}?= ${SCRIPTSNAME}
|
||||
. else
|
||||
SCRIPTSNAME_${S}?= ${S:T:R}
|
||||
. endif
|
||||
|
||||
SCRIPTSDIR_${S}?= ${SCRIPTSDIR}
|
||||
SCRIPTSOWN_${S}?= ${SCRIPTSOWN}
|
||||
SCRIPTSGRP_${S}?= ${SCRIPTSGRP}
|
||||
SCRIPTSMODE_${S}?= ${SCRIPTSMODE}
|
||||
|
||||
scriptsinstall: ${DESTDIR}${SCRIPTSDIR_${S}}/${SCRIPTSNAME_${S}}
|
||||
|
||||
${DESTDIR}${SCRIPTSDIR_${S}}/${SCRIPTSNAME_${S}}: ${S}
|
||||
${INSTALL} -o ${SCRIPTSOWN_${S}} \
|
||||
-g ${SCRIPTSGRP_${S}} \
|
||||
-m ${SCRIPTSMODE_${S}} \
|
||||
${.ALLSRC} \
|
||||
${.TARGET}
|
||||
|
||||
. endfor # for S in ${SCRIPTS}
|
||||
|
||||
. endif # defined(SCRIPTS) && !empty(SCRIPTS)
|
||||
|
||||
.endif # !target(install)
|
||||
|
||||
.if !defined(NO_MAN)
|
||||
. if target(_manpages) # bsd.man.mk was included
|
||||
realinstall: _maninstall
|
||||
. endif
|
||||
# We cannot capture dependencies for meta mode here
|
||||
UPDATE_DEPENDFILE = NO
|
||||
# nor can we safely run in parallel.
|
||||
.NOTPARALLEL:
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# Wrap bsd.nls.mk because I can't force that Makefile snippet to work only with
|
||||
# ${PROGS}.
|
||||
.for _P in ${PROGS}
|
||||
NLSNAME.${_P}?= ${_P}
|
||||
NLS:= ${NLS.${_P}}
|
||||
NLSDIR:= ${NLSDIR.${_P}}
|
||||
NLSNAME:= ${NLSNAME.${_P}}
|
||||
.include <bsd.nls.mk>
|
||||
# handle being called [bsd.]progs.mk
|
||||
.include <${.PARSEFILE:S,progs,prog,}>
|
||||
|
||||
.ifndef PROG
|
||||
PROGS_TARGETS += clean
|
||||
|
||||
.for p in ${PROGS}
|
||||
.if defined(PROGS_CXX) && !empty(PROGS_CXX:M$p)
|
||||
# bsd.prog.mk may need to know this
|
||||
x.$p= PROG_CXX=$p
|
||||
.endif
|
||||
|
||||
$p ${p}_p: .PHONY .MAKE
|
||||
(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} PROG=$p ${x.$p})
|
||||
|
||||
.for t in ${PROGS_TARGETS:O:u}
|
||||
$p.$t: .PHONY .MAKE
|
||||
(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} PROG=$p ${x.$p} ${@:E})
|
||||
.endfor
|
||||
.endfor
|
||||
|
||||
.include <bsd.files.mk>
|
||||
.include <bsd.incs.mk>
|
||||
.include <bsd.links.mk>
|
||||
|
||||
.if !target(lint)
|
||||
. for _P in ${PROGS}
|
||||
. if !target(lint.${_P})
|
||||
. if defined(PROG_CXX.${_P})
|
||||
lint.${_P}:
|
||||
. else
|
||||
_CFLAGS:= ${CFLAGS.${_P}}
|
||||
_SRCS:= ${SRCS.${_P}}
|
||||
lint.${_P}: ${_SRCS:M*.c}
|
||||
${LINT} ${LINTFLAGS} ${_CFLAGS:M-[DIU]*} ${.ALLSRC}
|
||||
. endif
|
||||
. endif
|
||||
lint: lint.${_P}
|
||||
|
||||
. endfor
|
||||
.endif # !target(lint)
|
||||
|
||||
.for _P in ${PROGS}
|
||||
CFLAGS:= ${CFLAGS.${_P}}
|
||||
CXXFLAGS:= ${CXXFLAGS.${_P}}
|
||||
# XXX: Pollutes DPADD.${_P} and LDADD.${_P} above
|
||||
#DPADD:= ${DPADD.${_P}}
|
||||
#LDADD:= ${LDADD.${_P}}
|
||||
SRCS:= ${SRCS.${_P}}
|
||||
. include <bsd.dep.mk>
|
||||
# bsd.dep.mk mangles SRCS
|
||||
SRCS.${_P}:= ${SRCS}
|
||||
. undef DPADD LDADD
|
||||
.for t in ${PROGS_TARGETS:O:u}
|
||||
$t: ${PROGS:%=%.$t}
|
||||
.endfor
|
||||
|
||||
# XXX: emulate the old bsd.prog.mk by allowing Makefiles that didn't set
|
||||
# ${PROG*} to function with this Makefile snippet.
|
||||
.if empty(PROGS)
|
||||
. include <bsd.dep.mk>
|
||||
.endif
|
||||
|
||||
.if !exists(${.OBJDIR}/${DEPENDFILE})
|
||||
. for _P in ${PROGS}
|
||||
_SRCS:= ${SRCS.${_P}}
|
||||
${OBJS.${_P}}: ${_SRCS:M*.h}
|
||||
. endfor
|
||||
.endif
|
||||
|
||||
.include <bsd.obj.mk>
|
||||
|
||||
.include <bsd.sys.mk>
|
||||
|
||||
.if defined(PORTNAME)
|
||||
.include <bsd.pkg.mk>
|
||||
.endif
|
||||
|
@ -29,6 +29,9 @@
|
||||
# maninstall, manlint, obj, objlink, realinstall, regress, tags
|
||||
#
|
||||
|
||||
.if !target(__<bsd.subdir.mk>__)
|
||||
__<bsd.subdir.mk>__:
|
||||
|
||||
.include <bsd.init.mk>
|
||||
|
||||
DISTRIBUTION?= base
|
||||
@ -92,3 +95,5 @@ afterinstall:
|
||||
install: beforeinstall realinstall afterinstall
|
||||
.ORDER: beforeinstall realinstall afterinstall
|
||||
.endif
|
||||
|
||||
.endif
|
||||
|
79
share/mk/bsd.test.mk
Normal file
79
share/mk/bsd.test.mk
Normal file
@ -0,0 +1,79 @@
|
||||
# $NetBSD: bsd.test.mk,v 1.21 2012/08/25 22:21:16 jmmv Exp $
|
||||
# $FreeBSD$
|
||||
|
||||
.include <bsd.init.mk>
|
||||
|
||||
.if defined(TESTS_C)
|
||||
PROGS+= ${TESTS_C}
|
||||
.for _T in ${TESTS_C}
|
||||
BINDIR.${_T}= ${TESTSDIR}
|
||||
MAN.${_T}?= # empty
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.if defined(TESTS_CXX)
|
||||
PROGS_CXX+= ${TESTS_CXX}
|
||||
PROGS+= ${TESTS_CXX}
|
||||
.for _T in ${TESTS_CXX}
|
||||
BINDIR.${_T}= ${TESTSDIR}
|
||||
MAN.${_T}?= # empty
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
.if defined(TESTS_SH)
|
||||
SCRIPTS+= ${TESTS_SH}
|
||||
.for _T in ${TESTS_SH}
|
||||
SCRIPTSDIR_${_T}= ${TESTSDIR}
|
||||
.endfor
|
||||
.endif
|
||||
|
||||
TESTSBASE?= ${DESTDIR}/usr/tests
|
||||
|
||||
# it is rare for test cases to have man pages
|
||||
.if !defined(MAN)
|
||||
WITHOUT_MAN=yes
|
||||
.export WITHOUT_MAN
|
||||
.endif
|
||||
|
||||
# tell progs.mk we might want to install things
|
||||
PROG_VARS+= BINDIR
|
||||
PROGS_TARGETS+= install
|
||||
|
||||
.if !empty(PROGS) || !empty(PROGS_CXX) || !empty(SCRIPTS)
|
||||
.include <bsd.progs.mk>
|
||||
.endif
|
||||
|
||||
beforetest: .PHONY
|
||||
.if defined(TESTSDIR)
|
||||
.if ${TESTSDIR} == ${TESTSBASE}
|
||||
# Forbid running from ${TESTSBASE}. It can cause false positives/negatives and
|
||||
# it does not cover all the tests (e.g. it misses testing software in external).
|
||||
@echo "*** Sorry, you cannot use make test from src/tests. Install the"
|
||||
@echo "*** tests into their final location and run them from ${TESTSBASE}"
|
||||
@false
|
||||
.else
|
||||
@echo "*** Using this test does not preclude you from running the tests"
|
||||
@echo "*** installed in ${TESTSBASE}. This test run may raise false"
|
||||
@echo "*** positives and/or false negatives."
|
||||
.endif
|
||||
.else
|
||||
@echo "*** No TESTSDIR defined; nothing to do."
|
||||
@false
|
||||
.endif
|
||||
@echo
|
||||
|
||||
.if !target(realtest)
|
||||
realtest: .PHONY
|
||||
@echo "$@ not defined; skipping"
|
||||
.endif
|
||||
|
||||
test: .PHONY
|
||||
.ORDER: beforetest realtest
|
||||
test: beforetest realtest
|
||||
|
||||
.if target(aftertest)
|
||||
.ORDER: realtest aftertest
|
||||
test: aftertest
|
||||
.endif
|
||||
|
||||
.include <bsd.obj.mk>
|
@ -481,7 +481,7 @@ SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, SI_ORDER_ANY, hook_tsc_freq, NULL);
|
||||
void
|
||||
identify_cpu(void)
|
||||
{
|
||||
u_int regs[4];
|
||||
u_int regs[4], cpu_stdext_disable;
|
||||
|
||||
do_cpuid(0, regs);
|
||||
cpu_high = regs[0];
|
||||
@ -516,6 +516,20 @@ identify_cpu(void)
|
||||
if (cpu_high >= 7) {
|
||||
cpuid_count(7, 0, regs);
|
||||
cpu_stdext_feature = regs[1];
|
||||
|
||||
/*
|
||||
* Some hypervisors fail to filter out unsupported
|
||||
* extended features. For now, disable the
|
||||
* extensions, activation of which requires setting a
|
||||
* bit in CR4, and which VM monitors do not support.
|
||||
*/
|
||||
if (cpu_feature2 & CPUID2_HV) {
|
||||
cpu_stdext_disable = CPUID_STDEXT_FSGSBASE |
|
||||
CPUID_STDEXT_SMEP;
|
||||
} else
|
||||
cpu_stdext_disable = 0;
|
||||
TUNABLE_INT_FETCH("hw.cpu_stdext_disable", &cpu_stdext_disable);
|
||||
cpu_stdext_feature &= ~cpu_stdext_disable;
|
||||
}
|
||||
|
||||
if (cpu_vendor_id == CPU_VENDOR_INTEL ||
|
||||
|
@ -1206,6 +1206,9 @@ initarm(struct arm_boot_params *abp)
|
||||
|
||||
pcpu0_init();
|
||||
|
||||
/* Do basic tuning, hz etc */
|
||||
init_param1();
|
||||
|
||||
/* Calculate number of L2 tables needed for mapping vm_page_array */
|
||||
l2size = (memsize / PAGE_SIZE) * sizeof(struct vm_page);
|
||||
l2size = (l2size >> L1_S_SHIFT) + 1;
|
||||
@ -1219,17 +1222,16 @@ initarm(struct arm_boot_params *abp)
|
||||
/* Make it divisible by 4 */
|
||||
l2size = (l2size + 3) & ~3;
|
||||
|
||||
#define KERNEL_TEXT_BASE (KERNBASE)
|
||||
freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK;
|
||||
|
||||
/* Define a macro to simplify memory allocation */
|
||||
#define valloc_pages(var, np) \
|
||||
alloc_pages((var).pv_va, (np)); \
|
||||
#define valloc_pages(var, np) \
|
||||
alloc_pages((var).pv_va, (np)); \
|
||||
(var).pv_pa = (var).pv_va + (KERNPHYSADDR - KERNVIRTADDR);
|
||||
|
||||
#define alloc_pages(var, np) \
|
||||
(var) = freemempos; \
|
||||
freemempos += (np * PAGE_SIZE); \
|
||||
#define alloc_pages(var, np) \
|
||||
(var) = freemempos; \
|
||||
freemempos += (np * PAGE_SIZE); \
|
||||
memset((char *)(var), 0, ((np) * PAGE_SIZE));
|
||||
|
||||
while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
|
||||
@ -1262,13 +1264,10 @@ initarm(struct arm_boot_params *abp)
|
||||
dpcpu_init((void *)dpcpu.pv_va, 0);
|
||||
|
||||
/* Allocate stacks for all modes */
|
||||
valloc_pages(irqstack, (IRQ_STACK_SIZE * MAXCPU));
|
||||
valloc_pages(abtstack, (ABT_STACK_SIZE * MAXCPU));
|
||||
valloc_pages(undstack, (UND_STACK_SIZE * MAXCPU));
|
||||
valloc_pages(kernelstack, (KSTACK_PAGES * MAXCPU));
|
||||
|
||||
init_param1();
|
||||
|
||||
valloc_pages(irqstack, IRQ_STACK_SIZE * MAXCPU);
|
||||
valloc_pages(abtstack, ABT_STACK_SIZE * MAXCPU);
|
||||
valloc_pages(undstack, UND_STACK_SIZE * MAXCPU);
|
||||
valloc_pages(kernelstack, KSTACK_PAGES * MAXCPU);
|
||||
valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
|
||||
|
||||
/*
|
||||
@ -1323,8 +1322,7 @@ initarm(struct arm_boot_params *abp)
|
||||
err_devmap = platform_devmap_init();
|
||||
pmap_devmap_bootstrap(l1pagetable, pmap_devmap_bootstrap_table);
|
||||
|
||||
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) |
|
||||
DOMAIN_CLIENT);
|
||||
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT);
|
||||
pmap_pa = kernel_l1pt.pv_pa;
|
||||
setttb(kernel_l1pt.pv_pa);
|
||||
cpu_tlb_flushID();
|
||||
@ -1403,7 +1401,6 @@ initarm(struct arm_boot_params *abp)
|
||||
*/
|
||||
physmap_init(availmem_regions, availmem_regions_sz);
|
||||
|
||||
/* Do basic tuning, hz etc */
|
||||
init_param2(physmem);
|
||||
kdb_init();
|
||||
|
||||
@ -1411,4 +1408,3 @@ initarm(struct arm_boot_params *abp)
|
||||
sizeof(struct pcb)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -96,6 +96,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <arm/at91/at91sam9g20reg.h>
|
||||
#include <arm/at91/at91sam9g45reg.h>
|
||||
|
||||
#ifndef MAXCPU
|
||||
#define MAXCPU 1
|
||||
#endif
|
||||
|
||||
/* Page table for mapping proc0 zero page */
|
||||
#define KERNEL_PT_SYS 0
|
||||
#define KERNEL_PT_KERN 1
|
||||
@ -454,7 +458,7 @@ initarm(struct arm_boot_params *abp)
|
||||
{
|
||||
struct pv_addr kernel_l1pt;
|
||||
struct pv_addr dpcpu;
|
||||
int loop, i;
|
||||
int i;
|
||||
u_int l1pagetable;
|
||||
vm_offset_t freemempos;
|
||||
vm_offset_t afterkern;
|
||||
@ -482,23 +486,23 @@ initarm(struct arm_boot_params *abp)
|
||||
while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
|
||||
freemempos += PAGE_SIZE;
|
||||
valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
|
||||
for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
|
||||
if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
|
||||
valloc_pages(kernel_pt_table[loop],
|
||||
for (i = 0; i < NUM_KERNEL_PTS; ++i) {
|
||||
if (!(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
|
||||
valloc_pages(kernel_pt_table[i],
|
||||
L2_TABLE_SIZE / PAGE_SIZE);
|
||||
} else {
|
||||
kernel_pt_table[loop].pv_va = freemempos -
|
||||
(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
|
||||
kernel_pt_table[i].pv_va = freemempos -
|
||||
(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
|
||||
L2_TABLE_SIZE_REAL;
|
||||
kernel_pt_table[loop].pv_pa =
|
||||
kernel_pt_table[loop].pv_va - KERNVIRTADDR +
|
||||
kernel_pt_table[i].pv_pa =
|
||||
kernel_pt_table[i].pv_va - KERNVIRTADDR +
|
||||
KERNPHYSADDR;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Allocate a page for the system page mapped to V0x00000000
|
||||
* This page will just contain the system vectors and can be
|
||||
* shared by all processes.
|
||||
* Allocate a page for the system page mapped to 0x00000000
|
||||
* or 0xffff0000. This page will just contain the system vectors
|
||||
* and can be shared by all processes.
|
||||
*/
|
||||
valloc_pages(systempage, 1);
|
||||
|
||||
@ -507,10 +511,10 @@ initarm(struct arm_boot_params *abp)
|
||||
dpcpu_init((void *)dpcpu.pv_va, 0);
|
||||
|
||||
/* Allocate stacks for all modes */
|
||||
valloc_pages(irqstack, IRQ_STACK_SIZE);
|
||||
valloc_pages(abtstack, ABT_STACK_SIZE);
|
||||
valloc_pages(undstack, UND_STACK_SIZE);
|
||||
valloc_pages(kernelstack, KSTACK_PAGES);
|
||||
valloc_pages(irqstack, IRQ_STACK_SIZE * MAXCPU);
|
||||
valloc_pages(abtstack, ABT_STACK_SIZE * MAXCPU);
|
||||
valloc_pages(undstack, UND_STACK_SIZE * MAXCPU);
|
||||
valloc_pages(kernelstack, KSTACK_PAGES * MAXCPU);
|
||||
valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
|
||||
|
||||
/*
|
||||
@ -558,17 +562,17 @@ initarm(struct arm_boot_params *abp)
|
||||
pmap_map_chunk(l1pagetable, msgbufpv.pv_va, msgbufpv.pv_pa,
|
||||
msgbufsize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
|
||||
|
||||
for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
|
||||
pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va,
|
||||
kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE,
|
||||
for (i = 0; i < NUM_KERNEL_PTS; ++i) {
|
||||
pmap_map_chunk(l1pagetable, kernel_pt_table[i].pv_va,
|
||||
kernel_pt_table[i].pv_pa, L2_TABLE_SIZE,
|
||||
VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
|
||||
}
|
||||
|
||||
pmap_devmap_bootstrap(l1pagetable, at91_devmap);
|
||||
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
|
||||
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT);
|
||||
setttb(kernel_l1pt.pv_pa);
|
||||
cpu_tlb_flushID();
|
||||
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
|
||||
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
|
||||
|
||||
at91_soc_id();
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
* - Port3 with:
|
||||
* - 26 input pins (GPI_00..GPI_09 + GPI_15..GPI_23 + GPI_25 + GPI_27..GPI_28)
|
||||
* - 24 output pins (GPO_00..GPO_23)
|
||||
* - 6 input/ouput pins (GPIO_00..GPIO_05)
|
||||
* - 6 input/output pins (GPIO_00..GPIO_05)
|
||||
*
|
||||
* Pins are mapped to logical pin number as follows:
|
||||
* [0..9] -> GPI_00..GPI_09 (port 3)
|
||||
|
@ -64,6 +64,7 @@ MAN+= ../forth/delay.4th.8
|
||||
MAN+= ../forth/loader.conf.5
|
||||
MAN+= ../forth/loader.4th.8
|
||||
MAN+= ../forth/menu.4th.8
|
||||
MAN+= ../forth/menusets.4th.8
|
||||
MAN+= ../forth/version.4th.8
|
||||
.endif
|
||||
|
||||
|
@ -342,6 +342,7 @@ create init_text8 255 allot
|
||||
\ sure that things move along smoothly, allocate
|
||||
\ a temporary NULL string
|
||||
|
||||
drop ( getenv cruft )
|
||||
s" "
|
||||
then
|
||||
then
|
||||
|
@ -40,13 +40,11 @@ sio_init: pushl %eax
|
||||
movb $0x3,%al # Set RTS,
|
||||
outb %al,(%dx) # DTR
|
||||
incl %edx # Line status reg
|
||||
call sio_flush
|
||||
ret
|
||||
# Fallthrough
|
||||
|
||||
/* int sio_flush(void) */
|
||||
|
||||
sio_flush: xorl %eax,%eax # Return value
|
||||
xorl %ecx,%ecx # Timeout
|
||||
sio_flush: xorl %ecx,%ecx # Timeout
|
||||
movb $0x80,%ch # counter
|
||||
sio_flush.1: call sio_ischar # Check for character
|
||||
jz sio_flush.2 # Till none
|
||||
|
@ -103,7 +103,7 @@ FILESMODE_${LOADER}= ${BINMODE} -b
|
||||
FILES+= loader.help loader.4th support.4th loader.conf
|
||||
FILES+= screen.4th frames.4th beastie.4th
|
||||
FILES+= brand.4th check-password.4th color.4th delay.4th
|
||||
FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
|
||||
FILES+= menu.4th menu-commands.4th menusets.4th shortcuts.4th version.4th
|
||||
FILESDIR_loader.conf= /boot/defaults
|
||||
|
||||
.if !exists(${DESTDIR}/boot/loader.rc)
|
||||
|
@ -35,7 +35,7 @@ loader.help: help.common
|
||||
FILES+= loader.4th support.4th loader.conf
|
||||
FILES+= screen.4th frames.4th
|
||||
FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th
|
||||
FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
|
||||
FILES+= menu.4th menu-commands.4th menusets.4th shortcuts.4th version.4th
|
||||
.if !exists(${DESTDIR}/boot/loader.rc)
|
||||
FILES+= loader.rc
|
||||
.endif
|
||||
|
@ -5,9 +5,9 @@
|
||||
BINDIR?= /boot
|
||||
|
||||
LOADER_ADDRESS?=0x200000
|
||||
CFLAGS+= -ffreestanding -mpreferred-stack-boundary=2 \
|
||||
-mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float \
|
||||
-Os -DPC98
|
||||
CFLAGS+= -march=i386 -ffreestanding -mpreferred-stack-boundary=2 \
|
||||
-mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
|
||||
CFLAGS+= -Os -DPC98
|
||||
LDFLAGS+= -nostdlib
|
||||
|
||||
# BTX components
|
||||
|
@ -3,7 +3,7 @@
|
||||
.include <bsd.own.mk>
|
||||
|
||||
# XXX: clang can compile the boot code just fine, but boot2 gets too big
|
||||
CC:=${CC:C/^(.*\/)?clang$/gcc/1}
|
||||
CC:= gcc
|
||||
|
||||
FILES= boot boot1 boot2
|
||||
|
||||
|
@ -554,8 +554,10 @@ parse()
|
||||
}
|
||||
ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) :
|
||||
OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD;
|
||||
if (ioctrl & IO_SERIAL)
|
||||
sio_init(115200 / comspeed);
|
||||
if (ioctrl & IO_SERIAL) {
|
||||
if (sio_init(115200 / comspeed) != 0)
|
||||
ioctrl &= ~IO_SERIAL;
|
||||
}
|
||||
} else {
|
||||
for (q = arg--; *q && *q != '('; q++);
|
||||
if (*q) {
|
||||
|
@ -840,7 +840,7 @@ putstr: lodsb # Load char
|
||||
.set SIO_DIV,(115200/SIOSPD) # 115200 / SPD
|
||||
|
||||
/*
|
||||
* void sio_init(void)
|
||||
* int sio_init(void)
|
||||
*/
|
||||
sio_init: movw $SIO_PRT+0x3,%dx # Data format reg
|
||||
movb $SIO_FMT|0x80,%al # Set format
|
||||
@ -856,14 +856,19 @@ sio_init: movw $SIO_PRT+0x3,%dx # Data format reg
|
||||
movb $0x3,%al # Set RTS,
|
||||
outb %al,(%dx) # DTR
|
||||
incl %edx # Line status reg
|
||||
call sio_getc.1 # Get character
|
||||
|
||||
/*
|
||||
* void sio_flush(void)
|
||||
* int sio_flush(void)
|
||||
*/
|
||||
sio_flush.0: call sio_getc.1 # Get character
|
||||
sio_flush: call sio_ischar # Check for character
|
||||
jnz sio_flush.0 # Till none
|
||||
ret # To caller
|
||||
sio_flush: xorl %eax,%eax # Return value
|
||||
xorl %ecx,%ecx # Timeout
|
||||
movb $0x80,%ch # counter
|
||||
sio_flush.1: call sio_ischar # Check for character
|
||||
jz sio_flush.2 # Till none
|
||||
loop sio_flush.1 # or counter is zero
|
||||
movb $1, %al # Exhausted all tries
|
||||
sio_flush.2: ret # To caller
|
||||
|
||||
/*
|
||||
* void sio_putc(int c)
|
||||
|
@ -13,3 +13,7 @@ ORG= 0x0000
|
||||
LDFLAGS=-e start -Ttext ${ORG} -Wl,-N,-S,--oformat,binary
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
# XXX: clang integrated-as doesn't grok .codeNN directives yet
|
||||
CFLAGS.cdboot.S= ${CLANG_NO_IAS}
|
||||
CFLAGS+= ${CFLAGS.${.IMPSRC:T}}
|
||||
|
@ -63,7 +63,6 @@ static void comc_setup(int speed, int port);
|
||||
static int comc_speed_set(struct env_var *ev, int flags,
|
||||
const void *value);
|
||||
|
||||
static int comc_started;
|
||||
static int comc_curspeed;
|
||||
static int comc_port = COMPORT;
|
||||
static uint32_t comc_locator;
|
||||
@ -87,9 +86,6 @@ comc_probe(struct console *cp)
|
||||
int speed, port;
|
||||
uint32_t locator;
|
||||
|
||||
/* XXX check the BIOS equipment list? */
|
||||
cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
|
||||
|
||||
if (comc_curspeed == 0) {
|
||||
comc_curspeed = COMSPEED;
|
||||
/*
|
||||
@ -137,18 +133,19 @@ comc_probe(struct console *cp)
|
||||
env_setenv("comconsole_pcidev", EV_VOLATILE, env, comc_pcidev_set,
|
||||
env_nounset);
|
||||
}
|
||||
comc_setup(comc_curspeed, comc_port);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_init(int arg)
|
||||
{
|
||||
if (comc_started && arg == 0)
|
||||
return 0;
|
||||
comc_started = 1;
|
||||
|
||||
comc_setup(comc_curspeed, comc_port);
|
||||
|
||||
return(0);
|
||||
if ((comconsole.c_flags & (C_PRESENTIN | C_PRESENTOUT)) ==
|
||||
(C_PRESENTIN | C_PRESENTOUT))
|
||||
return (CMD_OK);
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -166,13 +163,13 @@ comc_putchar(int c)
|
||||
static int
|
||||
comc_getchar(void)
|
||||
{
|
||||
return(comc_ischar() ? inb(comc_port + com_data) : -1);
|
||||
return (comc_ischar() ? inb(comc_port + com_data) : -1);
|
||||
}
|
||||
|
||||
static int
|
||||
comc_ischar(void)
|
||||
{
|
||||
return(inb(comc_port + com_lsr) & LSR_RXRDY);
|
||||
return (inb(comc_port + com_lsr) & LSR_RXRDY);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -185,7 +182,8 @@ comc_speed_set(struct env_var *ev, int flags, const void *value)
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
|
||||
if (comc_started && comc_curspeed != speed)
|
||||
if ((comconsole.c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) != 0 &&
|
||||
comc_curspeed != speed)
|
||||
comc_setup(speed, comc_port);
|
||||
|
||||
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
|
||||
@ -203,7 +201,8 @@ comc_port_set(struct env_var *ev, int flags, const void *value)
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
|
||||
if (comc_started && comc_port != port) {
|
||||
if ((comconsole.c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) != 0 &&
|
||||
comc_port != port) {
|
||||
comc_setup(comc_curspeed, port);
|
||||
set_hw_console_hint();
|
||||
}
|
||||
@ -305,7 +304,8 @@ comc_pcidev_set(struct env_var *ev, int flags, const void *value)
|
||||
printf("Invalid pcidev\n");
|
||||
return (CMD_ERROR);
|
||||
}
|
||||
if (comc_started && comc_locator != locator) {
|
||||
if ((comconsole.c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) != 0 &&
|
||||
comc_locator != locator) {
|
||||
error = comc_pcidev_handle(locator);
|
||||
if (error != CMD_OK)
|
||||
return (error);
|
||||
@ -317,6 +317,8 @@ comc_pcidev_set(struct env_var *ev, int flags, const void *value)
|
||||
static void
|
||||
comc_setup(int speed, int port)
|
||||
{
|
||||
static int TRY_COUNT = 1000000;
|
||||
int tries;
|
||||
|
||||
comc_curspeed = speed;
|
||||
comc_port = port;
|
||||
@ -327,9 +329,15 @@ comc_setup(int speed, int port)
|
||||
outb(comc_port + com_cfcr, COMC_FMT);
|
||||
outb(comc_port + com_mcr, MCR_RTS | MCR_DTR);
|
||||
|
||||
tries = 0;
|
||||
do
|
||||
inb(comc_port + com_data);
|
||||
while (inb(comc_port + com_lsr) & LSR_RXRDY);
|
||||
while (inb(comc_port + com_lsr) & LSR_RXRDY && ++tries < TRY_COUNT);
|
||||
|
||||
if (tries < TRY_COUNT)
|
||||
comconsole.c_flags |= (C_PRESENTIN | C_PRESENTOUT);
|
||||
else
|
||||
comconsole.c_flags &= ~(C_PRESENTIN | C_PRESENTOUT);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -88,7 +88,7 @@ FILESMODE_${LOADER}= ${BINMODE} -b
|
||||
FILES+= loader.help loader.4th support.4th loader.conf
|
||||
FILES+= screen.4th frames.4th beastie.4th
|
||||
FILES+= brand.4th check-password.4th color.4th delay.4th
|
||||
FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
|
||||
FILES+= menu.4th menu-commands.4th menusets.4th shortcuts.4th version.4th
|
||||
FILESDIR_loader.conf= /boot/defaults
|
||||
|
||||
.if !exists(${DESTDIR}/boot/loader.rc)
|
||||
|
@ -105,7 +105,7 @@ loader.help: help.common help.ofw
|
||||
FILES= loader.help loader.4th support.4th loader.conf
|
||||
FILES+= screen.4th frames.4th
|
||||
FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th
|
||||
FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
|
||||
FILES+= menu.4th menu-commands.4th menusets.4th shortcuts.4th version.4th
|
||||
FILESDIR_loader.conf= /boot/defaults
|
||||
|
||||
.if !exists(${DESTDIR}/boot/loader.rc)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user