various bug fixes
This commit is contained in:
parent
a796abef16
commit
1a8f27c350
14 changed files with 1236 additions and 9 deletions
148
man/man1/graph.1
Normal file
148
man/man1/graph.1
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
.TH GRAPH 1
|
||||||
|
.CT 1 numbers graphics
|
||||||
|
.SH NAME
|
||||||
|
graph \- draw a graph
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B graph
|
||||||
|
[
|
||||||
|
.I option ...
|
||||||
|
]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.I Graph
|
||||||
|
with no options takes pairs of numbers from the
|
||||||
|
standard input as abscissas
|
||||||
|
.RI ( x -values)
|
||||||
|
and ordinates
|
||||||
|
.RI ( y -values)
|
||||||
|
of a graph.
|
||||||
|
Successive points are connected by straight lines.
|
||||||
|
The graph is encoded on the standard output
|
||||||
|
for display by
|
||||||
|
.IR plot (1)
|
||||||
|
filters.
|
||||||
|
.PP
|
||||||
|
If an ordinate is followed by
|
||||||
|
a nonnumeric string, that string is printed as a
|
||||||
|
label beginning on the point.
|
||||||
|
Labels may be surrounded with quotes
|
||||||
|
.L
|
||||||
|
" "
|
||||||
|
in which case they may be empty or contain blanks
|
||||||
|
and numbers;
|
||||||
|
labels never contain newlines.
|
||||||
|
.PP
|
||||||
|
The following options are recognized,
|
||||||
|
each as a separate argument.
|
||||||
|
.TP
|
||||||
|
.B -a
|
||||||
|
Supply abscissas automatically; no
|
||||||
|
.IR x -values
|
||||||
|
appear in the input.
|
||||||
|
Spacing is given by the next
|
||||||
|
argument (default 1).
|
||||||
|
A second optional argument is the starting point for
|
||||||
|
automatic abscissas (default 0, or 1
|
||||||
|
with a log scale in
|
||||||
|
.IR x ,
|
||||||
|
or the lower limit given by
|
||||||
|
.BR -x ).
|
||||||
|
.TP
|
||||||
|
.B -b
|
||||||
|
Break (disconnect) the graph after each label in the input.
|
||||||
|
.TP
|
||||||
|
.B -c
|
||||||
|
Character string given by next argument
|
||||||
|
is default label for each point.
|
||||||
|
.TP
|
||||||
|
.B -g
|
||||||
|
Next argument is grid style,
|
||||||
|
0 no grid, 1 frame with ticks, 2 full grid (default).
|
||||||
|
.TP
|
||||||
|
.B -l
|
||||||
|
Next argument is a legend to title the graph.
|
||||||
|
Grid ranges
|
||||||
|
are automatically printed as part
|
||||||
|
of the title unless a
|
||||||
|
.B -s
|
||||||
|
option is present.
|
||||||
|
.TP
|
||||||
|
.B -m
|
||||||
|
Next argument is mode (style)
|
||||||
|
of connecting lines:
|
||||||
|
0 disconnected, 1 connected.
|
||||||
|
Some devices give distinguishable line styles
|
||||||
|
for other small integers.
|
||||||
|
Mode \-1 (default) begins with style 1 and
|
||||||
|
rotates styles for successive curves under option
|
||||||
|
.BR -o .
|
||||||
|
.TP
|
||||||
|
.B -o
|
||||||
|
(Overlay.)
|
||||||
|
The ordinates for
|
||||||
|
.I n
|
||||||
|
superposed curves appear in the input
|
||||||
|
with each abscissa value.
|
||||||
|
The next argument is
|
||||||
|
.IR n .
|
||||||
|
.TP
|
||||||
|
.B -s
|
||||||
|
Save screen; no new page for this graph.
|
||||||
|
.TP
|
||||||
|
.B -x l
|
||||||
|
If
|
||||||
|
.B l
|
||||||
|
is present,
|
||||||
|
.IR x -axis
|
||||||
|
is logarithmic.
|
||||||
|
Next 1 (or 2) arguments are lower (and upper)
|
||||||
|
.I x
|
||||||
|
limits.
|
||||||
|
Third argument, if present, is grid spacing on
|
||||||
|
.I x
|
||||||
|
axis.
|
||||||
|
Normally these quantities are determined automatically.
|
||||||
|
.TP
|
||||||
|
.B -y l
|
||||||
|
Similarly for
|
||||||
|
.IR y .
|
||||||
|
.TP
|
||||||
|
.B -e
|
||||||
|
Make automatically determined
|
||||||
|
.I x
|
||||||
|
and
|
||||||
|
.I y
|
||||||
|
scales equal.
|
||||||
|
.TP
|
||||||
|
.B -h
|
||||||
|
Next argument is fraction of space for height.
|
||||||
|
.TP
|
||||||
|
.B -w
|
||||||
|
Similarly for width.
|
||||||
|
.TP
|
||||||
|
.B -r
|
||||||
|
Next argument is fraction of space to move right before plotting.
|
||||||
|
.TP
|
||||||
|
.B -u
|
||||||
|
Similarly to move up before plotting.
|
||||||
|
.TP
|
||||||
|
.B -t
|
||||||
|
Transpose horizontal and vertical axes.
|
||||||
|
(Option
|
||||||
|
.B -a
|
||||||
|
now applies to the vertical axis.)
|
||||||
|
.PP
|
||||||
|
If a specified lower limit exceeds the upper limit,
|
||||||
|
the axis
|
||||||
|
is reversed.
|
||||||
|
.SH SOURCE
|
||||||
|
.B /sys/src/cmd/graph
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.IR plot (1),
|
||||||
|
.IR grap (1)
|
||||||
|
.SH BUGS
|
||||||
|
Segments that run out of bounds are dropped, not windowed.
|
||||||
|
Logarithmic axes may not be reversed.
|
||||||
|
Option
|
||||||
|
.B -e
|
||||||
|
actually makes automatic limits, rather than automatic scaling,
|
||||||
|
equal.
|
||||||
61
man/man1/plot.1
Normal file
61
man/man1/plot.1
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
.TH PLOT 1
|
||||||
|
.SH NAME
|
||||||
|
plot \- graphics filter
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B plot
|
||||||
|
[
|
||||||
|
.I file ...
|
||||||
|
]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.I Plot
|
||||||
|
interprets plotting instructions (see
|
||||||
|
.IR plot (6))
|
||||||
|
from the
|
||||||
|
.I files
|
||||||
|
or standard input,
|
||||||
|
drawing the results in a newly created
|
||||||
|
.IR rio (1)
|
||||||
|
window.
|
||||||
|
Plot persists until a newline is typed in the window.
|
||||||
|
Various options may be interspersed with the
|
||||||
|
.I file
|
||||||
|
arguments; they take effect at the given point in processing.
|
||||||
|
Options are:
|
||||||
|
.TP "\w'\fL-g \fIgrade\fLXX'u"
|
||||||
|
.B -d
|
||||||
|
Double buffer: accumulate the plot off-screen and write to the screen all at once
|
||||||
|
when an erase command is encountered or at end of file.
|
||||||
|
.TP
|
||||||
|
.B -e
|
||||||
|
Erase the screen.
|
||||||
|
.TP
|
||||||
|
.BI -c " col"
|
||||||
|
Set the foreground color (see
|
||||||
|
.IR plot (6)
|
||||||
|
for color names).
|
||||||
|
.TP
|
||||||
|
.BI -f " fill"
|
||||||
|
Set the background color.
|
||||||
|
.TP
|
||||||
|
.BI -g " grade"
|
||||||
|
Set the quality factor for arcs.
|
||||||
|
Higher grades give better quality.
|
||||||
|
.TP
|
||||||
|
.BI -p " col"
|
||||||
|
Set the pen color.
|
||||||
|
.TP
|
||||||
|
.BI -w
|
||||||
|
Pause until a newline is typed on standard input.
|
||||||
|
.TP
|
||||||
|
.B -C
|
||||||
|
Close the current plot.
|
||||||
|
.TP
|
||||||
|
.B -W " x0,y0,x1,y1"
|
||||||
|
Specify the bounding rectangle of plot's window.
|
||||||
|
By default it uses a 512×512 window in the
|
||||||
|
middle of the screen.
|
||||||
|
.SH SOURCE
|
||||||
|
.B /sys/src/cmd/plot
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.IR rio (1),
|
||||||
|
.IR plot (6)
|
||||||
87
man/man5/venti.conf.5
Normal file
87
man/man5/venti.conf.5
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
.TH VENTI.CONF 6
|
||||||
|
.SH NAME
|
||||||
|
venti.conf \- a venti configuration file
|
||||||
|
.SH DESCRIPTION
|
||||||
|
A venti configuration file enumerates the various index sections and
|
||||||
|
arenas that constitute a venti system.
|
||||||
|
The components are indicated by the name of the file, typically
|
||||||
|
a disk partition, in which they reside. The configuration
|
||||||
|
file is the only location that file names are used. Internally,
|
||||||
|
venti uses the names assigned when the components were formatted
|
||||||
|
with
|
||||||
|
.I fmtarenas
|
||||||
|
or
|
||||||
|
.I fmtisect
|
||||||
|
(see
|
||||||
|
.IR ventiaux (8)).
|
||||||
|
In particular, by changing the configuration a
|
||||||
|
component can be copied to a different file.
|
||||||
|
.PP
|
||||||
|
The configuration file consists of lines in the form described below.
|
||||||
|
Lines starting with
|
||||||
|
.B #
|
||||||
|
are comments.
|
||||||
|
.TP
|
||||||
|
.BI index " name
|
||||||
|
Names the index for the system.
|
||||||
|
.TP
|
||||||
|
.BI arenas " file
|
||||||
|
.I File
|
||||||
|
contains a collection of arenas, formatted using
|
||||||
|
.IR fmtarenas .
|
||||||
|
.TP
|
||||||
|
.BI isect " file
|
||||||
|
.I File
|
||||||
|
contains an index section, formatted using
|
||||||
|
.IR fmtisect .
|
||||||
|
.PP
|
||||||
|
After formatting a venti system using
|
||||||
|
.IR fmtindex ,
|
||||||
|
the order of arenas and index sections should not be changed.
|
||||||
|
Additional arenas can be appended to the configuration.
|
||||||
|
.PP
|
||||||
|
The configuration file optionally holds configuration parameters
|
||||||
|
for the venti server itself.
|
||||||
|
These are:
|
||||||
|
.TP
|
||||||
|
.BI mem " cachesize
|
||||||
|
.TP
|
||||||
|
.BI bcmem " blockcachesize
|
||||||
|
.TP
|
||||||
|
.BI icmem " indexcachesize
|
||||||
|
.TP
|
||||||
|
.BI addr " ventiaddress
|
||||||
|
.TP
|
||||||
|
.BI httpaddr " httpaddress
|
||||||
|
.TP
|
||||||
|
.B queuewrites
|
||||||
|
.PD
|
||||||
|
See
|
||||||
|
.IR venti (8)
|
||||||
|
for descriptions of these variables.
|
||||||
|
.SH EXAMPLE
|
||||||
|
.EX
|
||||||
|
# a sample venti configuration file
|
||||||
|
#
|
||||||
|
# formatted with
|
||||||
|
# venti/fmtarenas arena. /tmp/disks/arenas
|
||||||
|
# venti/fmtisect isect0 /tmp/disks/isect0
|
||||||
|
# venti/fmtisect isect1 /tmp/disks/isect1
|
||||||
|
# venti/fmtindex venti.conf
|
||||||
|
#
|
||||||
|
# server is started with
|
||||||
|
# venti/venti
|
||||||
|
|
||||||
|
# the name of the index
|
||||||
|
index main
|
||||||
|
|
||||||
|
# the index sections
|
||||||
|
isect /tmp/disks/isect0
|
||||||
|
isect /tmp/disks/isect1
|
||||||
|
|
||||||
|
# the arenas
|
||||||
|
arenas /tmp/disks/arenas
|
||||||
|
.EE
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.IR venti (8),
|
||||||
|
.IR ventiaux (8)
|
||||||
232
man/man8/venti.8
Normal file
232
man/man8/venti.8
Normal file
|
|
@ -0,0 +1,232 @@
|
||||||
|
.TH VENTI 8
|
||||||
|
.SH NAME
|
||||||
|
venti \- an archival block storage server
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B venti/venti
|
||||||
|
[
|
||||||
|
.B -dsw
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -a
|
||||||
|
.I ventiaddress
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -B
|
||||||
|
.I blockcachesize
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -c
|
||||||
|
.I config
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -C
|
||||||
|
.I cachesize
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -h
|
||||||
|
.I httpaddress
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -I
|
||||||
|
.I icachesize
|
||||||
|
]
|
||||||
|
.PP
|
||||||
|
.B venti/sync
|
||||||
|
[
|
||||||
|
.B -h
|
||||||
|
.I host
|
||||||
|
]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.I Venti
|
||||||
|
is a block storage server intended for archival data.
|
||||||
|
In a Venti server,
|
||||||
|
the SHA1 hash of a block's contents acts as the block
|
||||||
|
identifier for read and write operations.
|
||||||
|
This approach enforces a write-once policy, preventing accidental or
|
||||||
|
malicious destruction of data. In addition, duplicate copies of a
|
||||||
|
block are coalesced, reducing the consumption of storage and
|
||||||
|
simplifying the implementation of clients.
|
||||||
|
.PP
|
||||||
|
Storage for
|
||||||
|
.I venti
|
||||||
|
consists of a data log and an index, both of which
|
||||||
|
can be spread across multiple files.
|
||||||
|
The files containing the data log are themselves divided into self-contained sections called arenas.
|
||||||
|
Each arena contains a large number of data blocks and is sized to
|
||||||
|
facilitate operations such as copying to removable media.
|
||||||
|
The index provides a mapping between the a Sha1 fingerprint and
|
||||||
|
the location of the corresponding block in the data log.
|
||||||
|
.PP
|
||||||
|
The index and data log are typically stored on raw disk partitions.
|
||||||
|
To improve the robustness, the data log should be stored on
|
||||||
|
a device that provides RAID functionality. The index does
|
||||||
|
not require such protection, since if necessary, it can
|
||||||
|
can be regenerated from the data log.
|
||||||
|
The performance of
|
||||||
|
.I venti
|
||||||
|
is typically limited to the random access performance
|
||||||
|
of the index. This performance can be improved by spreading the
|
||||||
|
index accross multiple disks.
|
||||||
|
.PP
|
||||||
|
The storage for
|
||||||
|
.I venti
|
||||||
|
is initialized using
|
||||||
|
.IR fmtarenas ,
|
||||||
|
.IR fmtisect ,
|
||||||
|
and
|
||||||
|
.I fmtindex
|
||||||
|
(see
|
||||||
|
.IR ventiaux (8)).
|
||||||
|
A configuration file,
|
||||||
|
.IR venti.conf (6),
|
||||||
|
ties the index sections and data arenas together.
|
||||||
|
.PP
|
||||||
|
A Venti
|
||||||
|
server is accessed via an undocumented network protocol.
|
||||||
|
Two client applications are included in this distribution:
|
||||||
|
.IR vac (1)
|
||||||
|
and
|
||||||
|
.IR vacfs (4).
|
||||||
|
.I Vac
|
||||||
|
copies files from a Plan 9 file system to Venti, creating an
|
||||||
|
archive and returning the fingerprint of the root.
|
||||||
|
This archive can be mounted in Plan 9 using
|
||||||
|
.IR vacfs .
|
||||||
|
These two commands enable a rudimentary backup system.
|
||||||
|
A future release will include a Plan 9 file system that uses
|
||||||
|
Venti as a replacement for the WORM device of
|
||||||
|
.IR fs (4).
|
||||||
|
.PP
|
||||||
|
The
|
||||||
|
.I venti
|
||||||
|
server provides rudimentary status information via
|
||||||
|
a built-in http server. The URL files it serves are:
|
||||||
|
.TP
|
||||||
|
.B stats
|
||||||
|
Various internal statistics.
|
||||||
|
.TP
|
||||||
|
.B index
|
||||||
|
An enumeration of the index sections and all non empty arenas, including various statistics.
|
||||||
|
.TP
|
||||||
|
.B storage
|
||||||
|
A summary of the state of the data log.
|
||||||
|
.TP
|
||||||
|
.B xindex
|
||||||
|
An enumeration of the index sections and all non empty arenas, in XML format.
|
||||||
|
.PP
|
||||||
|
Several auxiliary utilities (see
|
||||||
|
.IR ventiaux (8))
|
||||||
|
aid in maintaining the storage for Venti.
|
||||||
|
With the exception of
|
||||||
|
.I rdarena ,
|
||||||
|
these utilities should generally be run after killing the
|
||||||
|
.I venti
|
||||||
|
server.
|
||||||
|
The utilities are:
|
||||||
|
.TP
|
||||||
|
.I checkarenas
|
||||||
|
Check the integrity, and optionally fix, Venti arenas.
|
||||||
|
.TP
|
||||||
|
.I checkindex
|
||||||
|
Check the integrity, and optionally fix, a Venti index.
|
||||||
|
.TP
|
||||||
|
.I buildindex
|
||||||
|
Rebuild a Venti index from scratch.
|
||||||
|
.TP
|
||||||
|
.I rdarena
|
||||||
|
Extract a Venti arena and write to standard output.
|
||||||
|
.PD
|
||||||
|
.PP
|
||||||
|
Options to
|
||||||
|
.I venti
|
||||||
|
are:
|
||||||
|
.TP
|
||||||
|
.BI -a " ventiaddress
|
||||||
|
The network address on which the server listens for incoming connections.
|
||||||
|
The default is
|
||||||
|
.LR tcp!*!venti .
|
||||||
|
.TP
|
||||||
|
.BI -B " blockcachesize
|
||||||
|
The size, in bytes, of memory allocated to caching raw disk blocks.
|
||||||
|
.TP
|
||||||
|
.BI -c " config
|
||||||
|
Specifies the
|
||||||
|
Venti
|
||||||
|
configuration file.
|
||||||
|
Defaults to
|
||||||
|
.LR venti.conf .
|
||||||
|
.TP
|
||||||
|
.BI -C " cachesize
|
||||||
|
The size, in bytes, of memory allocated to caching
|
||||||
|
Venti
|
||||||
|
blocks.
|
||||||
|
.TP
|
||||||
|
.BI -d
|
||||||
|
Produce various debugging information on standard error.
|
||||||
|
.TP
|
||||||
|
.BI -h " httpaddress
|
||||||
|
The network address of Venti's built-in
|
||||||
|
http
|
||||||
|
server.
|
||||||
|
The default is
|
||||||
|
.LR tcp!*!http .
|
||||||
|
.TP
|
||||||
|
.BI -I " icachesize
|
||||||
|
The size, in bytes, of memory allocated to caching the index mapping fingerprints
|
||||||
|
to locations in
|
||||||
|
.IR venti 's
|
||||||
|
data log.
|
||||||
|
.TP
|
||||||
|
.B -s
|
||||||
|
Do not run in the background.
|
||||||
|
Normally,
|
||||||
|
the foreground process will exit once the Venti server
|
||||||
|
is initialized and ready for connections.
|
||||||
|
.TP
|
||||||
|
.B -w
|
||||||
|
Enable write buffering. This option increase the performance of writes to
|
||||||
|
.I venti
|
||||||
|
at the cost of returning success to the client application before the
|
||||||
|
data has been written to disk.
|
||||||
|
The server implements a
|
||||||
|
.I sync
|
||||||
|
rpc that waits for completion of all the writes buffered at the time
|
||||||
|
the rpc was received.
|
||||||
|
Applications such as
|
||||||
|
.IR vac (1)
|
||||||
|
and the
|
||||||
|
.I sync
|
||||||
|
command described below
|
||||||
|
use this rpc to make sure that the data is correctly written to disk.
|
||||||
|
Use of this option is recommended.
|
||||||
|
.PD
|
||||||
|
.PP
|
||||||
|
The units for the various cache sizes above can be specified by appending a
|
||||||
|
.LR k ,
|
||||||
|
.LR m ,
|
||||||
|
or
|
||||||
|
.LR g
|
||||||
|
to indicate kilobytes, megabytes, or gigabytes respectively.
|
||||||
|
The command line options override options found in the
|
||||||
|
.IR venti.conf (6)
|
||||||
|
file.
|
||||||
|
.PP
|
||||||
|
.I Sync
|
||||||
|
connects to a running Venti server and executes a sync rpc
|
||||||
|
(described with the
|
||||||
|
.B -w
|
||||||
|
option above).
|
||||||
|
If sync exits successfully, it means that all writes buffered at the
|
||||||
|
time the command was issued are now on disk.
|
||||||
|
.SH SOURCE
|
||||||
|
.B /sys/src/cmd/venti
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.IR venti.conf (6),
|
||||||
|
.IR ventiaux (8),
|
||||||
|
.IR vac (1),
|
||||||
|
.IR vacfs (4).
|
||||||
|
.br
|
||||||
|
Sean Quinlan and Sean Dorward,
|
||||||
|
``Venti: a new approach to archival storage'',
|
||||||
|
.I "Usenix Conference on File and Storage Technologies" ,
|
||||||
|
2002.
|
||||||
504
man/man8/ventiaux.8
Normal file
504
man/man8/ventiaux.8
Normal file
|
|
@ -0,0 +1,504 @@
|
||||||
|
.TH VENTIAUX 8
|
||||||
|
.SH NAME
|
||||||
|
buildindex,
|
||||||
|
checkarenas,
|
||||||
|
checkindex,
|
||||||
|
conf,
|
||||||
|
copy,
|
||||||
|
fmtarenas,
|
||||||
|
fmtindex,
|
||||||
|
fmtisect,
|
||||||
|
rdarena,
|
||||||
|
rdarenablocks,
|
||||||
|
read,
|
||||||
|
wrarenablocks,
|
||||||
|
write \- Venti maintenance and debugging commands
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B venti/buildindex
|
||||||
|
[
|
||||||
|
.B -B
|
||||||
|
.I blockcachesize
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -Z
|
||||||
|
]
|
||||||
|
.I venti.config
|
||||||
|
.I tmp
|
||||||
|
.PP
|
||||||
|
.B venti/checkarenas
|
||||||
|
[
|
||||||
|
.B -afv
|
||||||
|
]
|
||||||
|
.I file
|
||||||
|
.PP
|
||||||
|
.B venti/checkindex
|
||||||
|
[
|
||||||
|
.B -f
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -B
|
||||||
|
.I blockcachesize
|
||||||
|
]
|
||||||
|
.I venti.config
|
||||||
|
.I tmp
|
||||||
|
.PP
|
||||||
|
.B venti/conf
|
||||||
|
[
|
||||||
|
.B -w
|
||||||
|
]
|
||||||
|
.I partition
|
||||||
|
[
|
||||||
|
.I configfile
|
||||||
|
]
|
||||||
|
.PP
|
||||||
|
.B venti/copy
|
||||||
|
[
|
||||||
|
.B -f
|
||||||
|
]
|
||||||
|
.I src
|
||||||
|
.I dst
|
||||||
|
.I score
|
||||||
|
[
|
||||||
|
.I type
|
||||||
|
]
|
||||||
|
.PP
|
||||||
|
.B venti/fmtarenas
|
||||||
|
[
|
||||||
|
.B -Z
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -a
|
||||||
|
.I arenasize
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -b
|
||||||
|
.I blocksize
|
||||||
|
]
|
||||||
|
.I name
|
||||||
|
.I file
|
||||||
|
.PP
|
||||||
|
.B venti/fmtindex
|
||||||
|
[
|
||||||
|
.B -a
|
||||||
|
]
|
||||||
|
.I venti.config
|
||||||
|
.PP
|
||||||
|
.B venti/fmtisect
|
||||||
|
[
|
||||||
|
.B -Z
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -b
|
||||||
|
.I blocksize
|
||||||
|
]
|
||||||
|
.I name
|
||||||
|
.I file
|
||||||
|
.PP
|
||||||
|
.B venti/rdarena
|
||||||
|
[
|
||||||
|
.B -v
|
||||||
|
]
|
||||||
|
.I arenapart
|
||||||
|
.I arenaname
|
||||||
|
.PP
|
||||||
|
.B venti/read
|
||||||
|
[
|
||||||
|
.B -h
|
||||||
|
.I host
|
||||||
|
]
|
||||||
|
.I score
|
||||||
|
[
|
||||||
|
.I type
|
||||||
|
]
|
||||||
|
.PP
|
||||||
|
.B venti/wrarena
|
||||||
|
[
|
||||||
|
.B -o
|
||||||
|
.I fileoffset
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -h
|
||||||
|
.I host
|
||||||
|
]
|
||||||
|
.I arenafile
|
||||||
|
[
|
||||||
|
.I clumpoffset
|
||||||
|
]
|
||||||
|
.PP
|
||||||
|
.B venti/write
|
||||||
|
[
|
||||||
|
.B -h
|
||||||
|
.I host
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -t
|
||||||
|
.I type
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B -z
|
||||||
|
]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
These commands aid in the setup, maintenance, and debugging of
|
||||||
|
Venti servers.
|
||||||
|
See
|
||||||
|
.IR venti (8)
|
||||||
|
and
|
||||||
|
.IR venti.conf (6)
|
||||||
|
for an overview of the data structures stored by Venti.
|
||||||
|
.PP
|
||||||
|
Note that the units for the various sizes in the following
|
||||||
|
commands can be specified by appending
|
||||||
|
.LR k ,
|
||||||
|
.LR m ,
|
||||||
|
or
|
||||||
|
.LR g
|
||||||
|
to indicate kilobytes, megabytes, or gigabytes respectively.
|
||||||
|
.PP
|
||||||
|
.I Buildindex
|
||||||
|
populates the index for the Venti system described in
|
||||||
|
.IR venti.config .
|
||||||
|
The index must have previously been formatted using
|
||||||
|
.IR fmtindex .
|
||||||
|
This command is typically used to build a new index for a Venti
|
||||||
|
system when the old index becomes too small, or to rebuild
|
||||||
|
an index after media failure.
|
||||||
|
Small errors in an index can usually be fixed with
|
||||||
|
.IR checkindex .
|
||||||
|
.PP
|
||||||
|
The
|
||||||
|
.I tmp
|
||||||
|
file, usually a disk partition, must be large enough to store a copy of the index.
|
||||||
|
This temporary space is used to perform a merge sort of index entries
|
||||||
|
generated by reading the arenas.
|
||||||
|
.PP
|
||||||
|
Options to
|
||||||
|
.I buildindex
|
||||||
|
are:
|
||||||
|
.TP
|
||||||
|
.BI -B " blockcachesize
|
||||||
|
The amount of memory, in bytes, to use for caching raw disk accesses while running
|
||||||
|
.IR buildindex .
|
||||||
|
(This is not a property of the created index.)
|
||||||
|
The default is 8k.
|
||||||
|
.TP
|
||||||
|
.B -Z
|
||||||
|
Do not zero the index.
|
||||||
|
This option should only be used when it is known that the index was already zeroed.
|
||||||
|
.PD
|
||||||
|
.PP
|
||||||
|
.I Checkarenas
|
||||||
|
examines the Venti arenas contained in the given
|
||||||
|
.IR file .
|
||||||
|
The program detects various error conditions, and optionally attempts
|
||||||
|
to fix any errors that are found.
|
||||||
|
.PP
|
||||||
|
Options to
|
||||||
|
.I checkarenas
|
||||||
|
are:
|
||||||
|
.TP
|
||||||
|
.B -a
|
||||||
|
For each arena, scan the entire data section.
|
||||||
|
If this option is omitted, only the end section of
|
||||||
|
the arena is examined.
|
||||||
|
.TP
|
||||||
|
.B -f
|
||||||
|
Attempt to fix any errors that are found.
|
||||||
|
.TP
|
||||||
|
.B -v
|
||||||
|
Increase the verbosity of output.
|
||||||
|
.PD
|
||||||
|
.PP
|
||||||
|
.I Checkindex
|
||||||
|
examines the Venti index described in
|
||||||
|
.IR venti.config .
|
||||||
|
The program detects various error conditions including:
|
||||||
|
blocks that are not indexed, index entries for blocks that do not exist,
|
||||||
|
and duplicate index entries.
|
||||||
|
If requested, an attempt can be made to fix errors that are found.
|
||||||
|
.PP
|
||||||
|
The
|
||||||
|
.I tmp
|
||||||
|
file, usually a disk partition, must be large enough to store a copy of the index.
|
||||||
|
This temporary space is used to perform a merge sort of index entries
|
||||||
|
generated by reading the arenas.
|
||||||
|
.PP
|
||||||
|
Options to
|
||||||
|
.I checkindex
|
||||||
|
are:
|
||||||
|
.TP
|
||||||
|
.BI -B " blockcachesize
|
||||||
|
The amount of memory, in bytes, to use for caching raw disk accesses while running
|
||||||
|
.IR checkindex .
|
||||||
|
The default is 8k.
|
||||||
|
.TP
|
||||||
|
.B -f
|
||||||
|
Attempt to fix any errors that are found.
|
||||||
|
.PD
|
||||||
|
.PP
|
||||||
|
.I Fmtarenas
|
||||||
|
formats the given
|
||||||
|
.IR file ,
|
||||||
|
typically a disk partition, into a number of
|
||||||
|
Venti
|
||||||
|
arenas.
|
||||||
|
The arenas are given names of the form
|
||||||
|
.IR name%d ,
|
||||||
|
where
|
||||||
|
.I %d
|
||||||
|
is replaced with a sequential number starting at 0.
|
||||||
|
.PP
|
||||||
|
Options to
|
||||||
|
.I fmtarenas
|
||||||
|
are:
|
||||||
|
.TP
|
||||||
|
.BI -a " arenasize
|
||||||
|
The arenas are of
|
||||||
|
.I arenasize
|
||||||
|
bytes. The default is 512 megabytes, which was selected to provide a balance
|
||||||
|
between the number of arenas and the ability to copy an arena to external
|
||||||
|
media such as recordable CDs and tapes.
|
||||||
|
.TP
|
||||||
|
.BI -b " blocksize
|
||||||
|
The size, in bytes, for read and write operations to the file.
|
||||||
|
The size is recorded in the file, and is used by applications that access the arenas.
|
||||||
|
The default is 8k.
|
||||||
|
.TP
|
||||||
|
.B -Z
|
||||||
|
Do not zero the data sections of the arenas.
|
||||||
|
Using this option reduces the formatting time
|
||||||
|
but should only be used when it is known that the file was already zeroed.
|
||||||
|
.PD
|
||||||
|
.I Fmtindex
|
||||||
|
takes the
|
||||||
|
.IR venti.conf (6)
|
||||||
|
file
|
||||||
|
.I venti.config
|
||||||
|
and initializes the index sections to form a usable index structure.
|
||||||
|
The arena files and index sections must have previously been formatted
|
||||||
|
using
|
||||||
|
.I fmtarenas
|
||||||
|
and
|
||||||
|
.I fmtisect
|
||||||
|
respectively.
|
||||||
|
.PP
|
||||||
|
The function of a Venti index is to map a SHA1 fingerprint to a location
|
||||||
|
in the data section of one of the arenas. The index is composed of
|
||||||
|
blocks, each of which contains the mapping for a fixed range of possible
|
||||||
|
fingerprint values.
|
||||||
|
.I Fmtindex
|
||||||
|
determines the mapping between SHA1 values and the blocks
|
||||||
|
of the collection of index sections. Once this mapping has been determined,
|
||||||
|
it cannot be changed without rebuilding the index.
|
||||||
|
The basic assumption in the current implementation is that the index
|
||||||
|
structure is sufficiently empty that individual blocks of the index will rarely
|
||||||
|
overflow. The total size of the index should be about 2% to 10% of
|
||||||
|
the total size of the arenas, but the exact depends both the index block size
|
||||||
|
and the compressed size of block stored to Venti.
|
||||||
|
.PP
|
||||||
|
.I Fmtindex
|
||||||
|
also computes a mapping between a linear address space and
|
||||||
|
the data section of the collection of arenas. The
|
||||||
|
.B -a
|
||||||
|
option can be used to add additional arenas to an index.
|
||||||
|
To use this feature,
|
||||||
|
add the new arenas to
|
||||||
|
.I venti.config
|
||||||
|
after the existing arenas and then run
|
||||||
|
.I fmtindex
|
||||||
|
.BR -a .
|
||||||
|
.PP
|
||||||
|
A copy of the above mappings is stored in the header for each of the index sections.
|
||||||
|
These copies enable
|
||||||
|
.I buildindex
|
||||||
|
to restore a single index section without rebuilding the entire index.
|
||||||
|
.PP
|
||||||
|
.I Fmtisect
|
||||||
|
formats the given
|
||||||
|
.IR file ,
|
||||||
|
typically a disk partition, as a Venti index section with the specified
|
||||||
|
.IR name .
|
||||||
|
One or more formatted index sections are combined into a Venti
|
||||||
|
index using
|
||||||
|
.IR fmtindex .
|
||||||
|
Each of the index sections within an index must have a unique name.
|
||||||
|
.PP
|
||||||
|
Options to
|
||||||
|
.I fmtisect
|
||||||
|
are:
|
||||||
|
.TP
|
||||||
|
.BI -b " blocksize
|
||||||
|
The size, in bytes, for read and write operations to the file.
|
||||||
|
All the index sections within a index must have the same block size.
|
||||||
|
The default is 8k.
|
||||||
|
.TP
|
||||||
|
.B -Z
|
||||||
|
Do not zero the index.
|
||||||
|
Using this option reduces the formatting time
|
||||||
|
but should only be used when it is known that the file was already zeroed.
|
||||||
|
.PD
|
||||||
|
.PP
|
||||||
|
.I Rdarena
|
||||||
|
extracts the named
|
||||||
|
.I arena
|
||||||
|
from the arena partition
|
||||||
|
.I arenapart
|
||||||
|
and writes this arena to standard output.
|
||||||
|
This command is typically used to back up an arena to external media.
|
||||||
|
The
|
||||||
|
.B -v
|
||||||
|
option generates more verbose output on standard error.
|
||||||
|
.PP
|
||||||
|
.I Wrarena
|
||||||
|
writes the blocks contained in the arena
|
||||||
|
.I arenafile
|
||||||
|
(typically, the output of
|
||||||
|
.IR rdarena )
|
||||||
|
to a Venti server.
|
||||||
|
It is typically used to reinitialize a Venti server from backups of the arenas.
|
||||||
|
For example,
|
||||||
|
.IP
|
||||||
|
.EX
|
||||||
|
venti/rdarena /dev/sdC0/arenas arena.0 >external.media
|
||||||
|
venti/wrarena -h venti2 external.media
|
||||||
|
.EE
|
||||||
|
.LP
|
||||||
|
writes the blocks contained in
|
||||||
|
.B arena.0
|
||||||
|
to the Venti server
|
||||||
|
.B venti2
|
||||||
|
(typically not the one using
|
||||||
|
.BR /dev/sdC0/arenas ).
|
||||||
|
.PP
|
||||||
|
The
|
||||||
|
.B -o
|
||||||
|
option specifies that the arena starts at byte
|
||||||
|
.I fileoffset
|
||||||
|
(default
|
||||||
|
.BR 0 )
|
||||||
|
in
|
||||||
|
.I arenafile .
|
||||||
|
This is useful for reading directly from
|
||||||
|
the Venti arena partition:
|
||||||
|
.IP
|
||||||
|
.EX
|
||||||
|
venti/wrarena -h venti2 -o 335872 /dev/sdC0/arenas
|
||||||
|
.EE
|
||||||
|
.LP
|
||||||
|
(In this example, 335872 is the offset shown in the Venti
|
||||||
|
server's index list (344064) minus one block (8192).
|
||||||
|
You will need to substitute your own arena offsets
|
||||||
|
and block size.)
|
||||||
|
.PP
|
||||||
|
Finally, the optional
|
||||||
|
.I offset
|
||||||
|
argument specifies that the writing should begin with the
|
||||||
|
clump starting at
|
||||||
|
.I offset
|
||||||
|
within the arena.
|
||||||
|
.I Wrarena
|
||||||
|
prints the offset it stopped at (because there were no more data blocks).
|
||||||
|
This could be used to incrementally back up a Venti server
|
||||||
|
to another Venti server:
|
||||||
|
.IP
|
||||||
|
.EX
|
||||||
|
last=`{cat last}
|
||||||
|
venti/wrarena -h venti2 -o 335872 /dev/sdC0/arenas $last >output
|
||||||
|
awk '/^end offset/ { print $3 }' offset >last
|
||||||
|
.EE
|
||||||
|
.LP
|
||||||
|
Of course, one would need to add wrapper code to keep track
|
||||||
|
of which arenas have been processed.
|
||||||
|
See
|
||||||
|
.B /sys/src/cmd/venti/backup.example
|
||||||
|
for a version that does this.
|
||||||
|
.PP
|
||||||
|
.I Read
|
||||||
|
and
|
||||||
|
.I write
|
||||||
|
read and write blocks from a running Venti server.
|
||||||
|
They are intended to ease debugging of the server.
|
||||||
|
The default
|
||||||
|
.I host
|
||||||
|
is the environment variable
|
||||||
|
.BR $venti ,
|
||||||
|
followed by the network metaname
|
||||||
|
.BR $venti .
|
||||||
|
The
|
||||||
|
.I type
|
||||||
|
is the decimal type of block to be read or written.
|
||||||
|
If no
|
||||||
|
.I type
|
||||||
|
is specified for
|
||||||
|
.I read ,
|
||||||
|
all types are tried, and a command-line is printed to
|
||||||
|
show the type that eventually worked.
|
||||||
|
If no
|
||||||
|
.I type
|
||||||
|
is specified for
|
||||||
|
.I write ,
|
||||||
|
.B VtDataType
|
||||||
|
(13)
|
||||||
|
is used.
|
||||||
|
.I Read
|
||||||
|
reads the block named by
|
||||||
|
.I score
|
||||||
|
(a SHA1 hash)
|
||||||
|
from the Venti server and writes it to standard output.
|
||||||
|
.I Write
|
||||||
|
reads a block from standard input and attempts to write
|
||||||
|
it to the Venti server.
|
||||||
|
If successful, it prints the score of the block on the server.
|
||||||
|
.PP
|
||||||
|
.I Copy
|
||||||
|
walks the entire tree of blocks rooted at
|
||||||
|
.I score ,
|
||||||
|
copying all the blocks visited during the walk from
|
||||||
|
the Venti server at network address
|
||||||
|
.I src
|
||||||
|
to the Venti server at network address
|
||||||
|
.I dst .
|
||||||
|
If
|
||||||
|
.I type
|
||||||
|
(a decimal block type for
|
||||||
|
.IR score )
|
||||||
|
is omitted, all types will be tried in sequence
|
||||||
|
until one is found that works.
|
||||||
|
The
|
||||||
|
.B -f
|
||||||
|
flag runs the copy in ``fast'' mode: if a block is already on
|
||||||
|
.IR dst ,
|
||||||
|
the walk does not descend below it, on the assumption that all its
|
||||||
|
children are also already on
|
||||||
|
.IR dst .
|
||||||
|
Without this flag, the copy often transfers many times more
|
||||||
|
data than necessary.
|
||||||
|
.PP
|
||||||
|
To make it easier to bootstrap servers, the configuration
|
||||||
|
file can be stored at the beginning of any Venti partitions using
|
||||||
|
.IR conf .
|
||||||
|
A partition so branded with a configuration file can
|
||||||
|
be used in place of a configuration file when invoking any
|
||||||
|
of the venti commands.
|
||||||
|
By default,
|
||||||
|
.I conf
|
||||||
|
prints the configuration stored in
|
||||||
|
.IR partition .
|
||||||
|
When invoked with the
|
||||||
|
.B -w
|
||||||
|
flag,
|
||||||
|
.I conf
|
||||||
|
reads a configuration file from
|
||||||
|
.I configfile
|
||||||
|
(or else standard input)
|
||||||
|
and stores it in
|
||||||
|
.IR partition .
|
||||||
|
.SH SOURCE
|
||||||
|
.B /sys/src/cmd/venti
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.IR venti (8),
|
||||||
|
.IR venti.conf (6)
|
||||||
|
.SH BUGS
|
||||||
|
.I Buildindex
|
||||||
|
should allow an individual index section to be rebuilt.
|
||||||
|
The merge sort could be performed in the space used to store the
|
||||||
|
index rather than requiring a temporary file.
|
||||||
2
sky/.cvsignore
Normal file
2
sky/.cvsignore
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*.scat
|
||||||
|
constelnames
|
||||||
|
|
@ -1308,7 +1308,7 @@ runproc(void *argvp)
|
||||||
name[e-t] = 0;
|
name[e-t] = 0;
|
||||||
e = utfrrune(name, '/');
|
e = utfrrune(name, '/');
|
||||||
if(e)
|
if(e)
|
||||||
strcpy(name, e+1);
|
memmove(name, e+1, strlen(e+1)+1); /* strcpy but overlaps */
|
||||||
strcat(name, " "); /* add blank here for ease in waittask */
|
strcat(name, " "); /* add blank here for ease in waittask */
|
||||||
c->name = bytetorune(name, &c->nname);
|
c->name = bytetorune(name, &c->nname);
|
||||||
free(name);
|
free(name);
|
||||||
|
|
|
||||||
|
|
@ -663,12 +663,12 @@ rowload(Row *row, char *file, int initing)
|
||||||
break;
|
break;
|
||||||
wincleartag(w);
|
wincleartag(w);
|
||||||
textinsert(&w->tag, w->tag.file->b.nc, r+n+1, nr-(n+1), TRUE);
|
textinsert(&w->tag, w->tag.file->b.nc, r+n+1, nr-(n+1), TRUE);
|
||||||
free(r);
|
|
||||||
if(ndumped >= 0){
|
if(ndumped >= 0){
|
||||||
/* simplest thing is to put it in a file and load that */
|
/* simplest thing is to put it in a file and load that */
|
||||||
sprint(buf, "/tmp/d%d.%.4sacme", getpid(), getuser());
|
sprint(buf, "/tmp/d%d.%.4sacme", getpid(), getuser());
|
||||||
fd = create(buf, OWRITE|ORCLOSE, 0600);
|
fd = create(buf, OWRITE|ORCLOSE, 0600);
|
||||||
if(fd < 0){
|
if(fd < 0){
|
||||||
|
free(r);
|
||||||
warning(nil, "can't create temp file: %r\n");
|
warning(nil, "can't create temp file: %r\n");
|
||||||
goto Rescue2;
|
goto Rescue2;
|
||||||
}
|
}
|
||||||
|
|
@ -679,6 +679,7 @@ rowload(Row *row, char *file, int initing)
|
||||||
if(rune == '\n')
|
if(rune == '\n')
|
||||||
line++;
|
line++;
|
||||||
if(rune == (Rune)Beof){
|
if(rune == (Rune)Beof){
|
||||||
|
free(r);
|
||||||
Bterm(bout);
|
Bterm(bout);
|
||||||
free(bout);
|
free(bout);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
@ -696,6 +697,7 @@ rowload(Row *row, char *file, int initing)
|
||||||
winsettag(w);
|
winsettag(w);
|
||||||
}else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-')
|
}else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-')
|
||||||
get(&w->body, nil, nil, FALSE, XXX, nil, 0);
|
get(&w->body, nil, nil, FALSE, XXX, nil, 0);
|
||||||
|
free(r);
|
||||||
if(fontr){
|
if(fontr){
|
||||||
fontx(&w->body, nil, nil, 0, 0, fontr, nfontr);
|
fontx(&w->body, nil, nil, 0, 0, fontr, nfontr);
|
||||||
free(fontr);
|
free(fontr);
|
||||||
|
|
|
||||||
|
|
@ -963,8 +963,11 @@ textshow(Text *t, uint q0, uint q1, int doselect)
|
||||||
int nl;
|
int nl;
|
||||||
uint q;
|
uint q;
|
||||||
|
|
||||||
if(t->what != Body)
|
if(t->what != Body){
|
||||||
|
if(doselect)
|
||||||
|
textsetselect(t, q0, q1);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if(t->w!=nil && t->fr.maxlines==0)
|
if(t->w!=nil && t->fr.maxlines==0)
|
||||||
colgrow(t->col, t->w, 1);
|
colgrow(t->col, t->w, 1);
|
||||||
if(doselect)
|
if(doselect)
|
||||||
|
|
|
||||||
167
src/lib9/rendez-futex.c
Normal file
167
src/lib9/rendez-futex.c
Normal file
|
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
NAME
|
||||||
|
rendezvous - user level process synchronization
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
ulong rendezvous(ulong tag, ulong value)
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The rendezvous system call allows two processes to synchro-
|
||||||
|
nize and exchange a value. In conjunction with the shared
|
||||||
|
memory system calls (see segattach(2) and fork(2)), it
|
||||||
|
enables parallel programs to control their scheduling.
|
||||||
|
|
||||||
|
Two processes wishing to synchronize call rendezvous with a
|
||||||
|
common tag, typically an address in memory they share. One
|
||||||
|
process will arrive at the rendezvous first; it suspends
|
||||||
|
execution until a second arrives. When a second process
|
||||||
|
meets the rendezvous the value arguments are exchanged
|
||||||
|
between the processes and returned as the result of the
|
||||||
|
respective rendezvous system calls. Both processes are
|
||||||
|
awakened when the rendezvous succeeds.
|
||||||
|
|
||||||
|
The set of tag values which two processes may use to
|
||||||
|
rendezvous-their tag space-is inherited when a process
|
||||||
|
forks, unless RFREND is set in the argument to rfork; see
|
||||||
|
fork(2).
|
||||||
|
|
||||||
|
If a rendezvous is interrupted the return value is ~0, so
|
||||||
|
that value should not be used in normal communication.
|
||||||
|
|
||||||
|
* This simulates rendezvous with shared memory, pause, and SIGUSR1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
|
typedef u32int u32;
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#define __user
|
||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <linux/futex.h>
|
||||||
|
#include <libc.h>
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
VOUSHASH = 257,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Vous Vous;
|
||||||
|
struct Vous
|
||||||
|
{
|
||||||
|
Vous *link;
|
||||||
|
Lock lk;
|
||||||
|
int pid;
|
||||||
|
ulong val;
|
||||||
|
ulong tag;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Vous vouspool[2048];
|
||||||
|
static int nvousused;
|
||||||
|
static Vous *vousfree;
|
||||||
|
static Vous *voushash[VOUSHASH];
|
||||||
|
static Lock vouslock;
|
||||||
|
|
||||||
|
static Vous*
|
||||||
|
getvous(void)
|
||||||
|
{
|
||||||
|
Vous *v;
|
||||||
|
|
||||||
|
if(vousfree){
|
||||||
|
v = vousfree;
|
||||||
|
vousfree = v->link;
|
||||||
|
}else if(nvousused < nelem(vouspool))
|
||||||
|
v = &vouspool[nvousused++];
|
||||||
|
else
|
||||||
|
abort();
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
putvous(Vous *v)
|
||||||
|
{
|
||||||
|
lock(&vouslock);
|
||||||
|
v->link = vousfree;
|
||||||
|
vousfree = v;
|
||||||
|
unlock(&vouslock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Vous*
|
||||||
|
findvous(ulong tag, ulong val, int pid)
|
||||||
|
{
|
||||||
|
int h;
|
||||||
|
Vous *v, **l;
|
||||||
|
|
||||||
|
lock(&vouslock);
|
||||||
|
h = tag%VOUSHASH;
|
||||||
|
for(l=&voushash[h], v=*l; v; l=&(*l)->link, v=*l){
|
||||||
|
if(v->tag == tag){
|
||||||
|
*l = v->link;
|
||||||
|
unlock(&vouslock);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v = getvous();
|
||||||
|
v->pid = pid;
|
||||||
|
v->link = voushash[h];
|
||||||
|
v->val = val;
|
||||||
|
v->tag = tag;
|
||||||
|
lock(&v->lk);
|
||||||
|
voushash[h] = v;
|
||||||
|
unlock(&vouslock);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DBG 0
|
||||||
|
ulong
|
||||||
|
rendezvous(ulong tag, ulong val)
|
||||||
|
{
|
||||||
|
int me, vpid;
|
||||||
|
ulong rval;
|
||||||
|
Vous *v;
|
||||||
|
|
||||||
|
me = getpid();
|
||||||
|
v = findvous(tag, val, me);
|
||||||
|
if(v->pid == me){
|
||||||
|
if(DBG)fprint(2, "pid is %d tag %lux, sleeping\n", me, tag);
|
||||||
|
/*
|
||||||
|
* No rendezvous partner was found; the next guy
|
||||||
|
* through will find v and wake us, so we must go
|
||||||
|
* to sleep.
|
||||||
|
*
|
||||||
|
* To go to sleep:
|
||||||
|
* 1. disable USR1 signals.
|
||||||
|
* 2. unlock v->lk (tells waker okay to signal us).
|
||||||
|
* 3. atomically suspend and enable USR1 signals.
|
||||||
|
*
|
||||||
|
* The call to ignusr1() could be done once at
|
||||||
|
* process creation instead of every time through rendezvous.
|
||||||
|
*/
|
||||||
|
v->val = val;
|
||||||
|
unlock(&v->lk);
|
||||||
|
while(sys_futex((u32int*)&v->tag, FUTEX_WAIT, tag, nil, nil) < 0 && errno==EINTR)
|
||||||
|
;
|
||||||
|
rval = v->val;
|
||||||
|
if(DBG)fprint(2, "pid is %d, awake\n", me);
|
||||||
|
putvous(v);
|
||||||
|
}else{
|
||||||
|
/*
|
||||||
|
* Found someone to meet. Wake him:
|
||||||
|
*
|
||||||
|
* A. lock v->lk (waits for him to get to his step 2)
|
||||||
|
* B. send a USR1
|
||||||
|
*
|
||||||
|
* He won't get the USR1 until he suspends, which
|
||||||
|
* means it must wake him up (it can't get delivered
|
||||||
|
* before he sleeps).
|
||||||
|
*/
|
||||||
|
vpid = v->pid;
|
||||||
|
lock(&v->lk);
|
||||||
|
rval = v->val;
|
||||||
|
v->val = val;
|
||||||
|
v->tag++;
|
||||||
|
unlock(&v->lk);
|
||||||
|
sys_futex((u32int*)&v->tag, FUTEX_WAKE, 1, nil, nil);
|
||||||
|
}
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +86,13 @@ _allocmemimage(Rectangle r, u32int chan)
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
md->ref = 1;
|
md->ref = 1;
|
||||||
md->base = poolalloc(imagmem, (2+nw)*sizeof(u32int));
|
/*
|
||||||
|
* The first two words are the md and the callerpc.
|
||||||
|
* Then nw words of data.
|
||||||
|
* The final word lets the drawing routines be a little
|
||||||
|
* sloppy about reading past the end of the block.
|
||||||
|
*/
|
||||||
|
md->base = poolalloc(imagmem, (2+nw+1)*sizeof(u32int));
|
||||||
if(md->base == nil){
|
if(md->base == nil){
|
||||||
free(md);
|
free(md);
|
||||||
return nil;
|
return nil;
|
||||||
|
|
|
||||||
|
|
@ -86,19 +86,27 @@ fsunmount(Fsys *fs)
|
||||||
void
|
void
|
||||||
_fsdecref(Fsys *fs)
|
_fsdecref(Fsys *fs)
|
||||||
{
|
{
|
||||||
Fid *f, *next;
|
Fid *f, **l, *next;
|
||||||
|
|
||||||
qlock(&fs->lk);
|
qlock(&fs->lk);
|
||||||
--fs->ref;
|
--fs->ref;
|
||||||
//fprint(2, "fsdecref %p to %d\n", fs, fs->ref);
|
//fprint(2, "fsdecref %p to %d\n", fs, fs->ref);
|
||||||
if(fs->ref == 0){
|
if(fs->ref == 0){
|
||||||
close(fs->fd);
|
close(fs->fd);
|
||||||
|
/* trim the list down to just the first in each chunk */
|
||||||
|
for(l=&fs->freefid; *l; ){
|
||||||
|
if((*l)->fid%Fidchunk == 0)
|
||||||
|
l = &(*l)->next;
|
||||||
|
else
|
||||||
|
*l = (*l)->next;
|
||||||
|
}
|
||||||
|
/* now free the list */
|
||||||
for(f=fs->freefid; f; f=next){
|
for(f=fs->freefid; f; f=next){
|
||||||
next = f->next;
|
next = f->next;
|
||||||
if(f->fid%Fidchunk == 0)
|
free(f);
|
||||||
free(f);
|
|
||||||
}
|
}
|
||||||
free(fs);
|
free(fs);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
qunlock(&fs->lk);
|
qunlock(&fs->lk);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,11 @@ nsmount(char *name, char *aname)
|
||||||
fd = dial(addr, 0, 0, 0);
|
fd = dial(addr, 0, 0, 0);
|
||||||
if(fd < 0){
|
if(fd < 0){
|
||||||
werrstr("dial %s: %r", addr);
|
werrstr("dial %s: %r", addr);
|
||||||
|
free(addr);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
free(addr);
|
||||||
|
|
||||||
fcntl(fd, F_SETFL, FD_CLOEXEC);
|
fcntl(fd, F_SETFL, FD_CLOEXEC);
|
||||||
|
|
||||||
fs = fsmount(fd, aname);
|
fs = fsmount(fd, aname);
|
||||||
|
|
|
||||||
|
|
@ -174,8 +174,8 @@ _threadfdwait(int fd, int rw, ulong pc)
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Channel c;
|
Channel c;
|
||||||
Alt *qentry[2];
|
|
||||||
ulong x;
|
ulong x;
|
||||||
|
Alt *qentry[2];
|
||||||
} s;
|
} s;
|
||||||
|
|
||||||
threadfdwaitsetup();
|
threadfdwaitsetup();
|
||||||
|
|
@ -214,11 +214,15 @@ threadsleep(int ms)
|
||||||
struct {
|
struct {
|
||||||
Channel c;
|
Channel c;
|
||||||
ulong x;
|
ulong x;
|
||||||
|
Alt *qentry[2];
|
||||||
} s;
|
} s;
|
||||||
|
|
||||||
threadfdwaitsetup();
|
threadfdwaitsetup();
|
||||||
chaninit(&s.c, sizeof(ulong), 1);
|
chaninit(&s.c, sizeof(ulong), 1);
|
||||||
|
s.c.qentry = (volatile Alt**)s.qentry;
|
||||||
|
s.c.nentry = 2;
|
||||||
|
memset(s.qentry, 0, sizeof s.qentry);
|
||||||
|
|
||||||
sleepchan[nsleep] = &s.c;
|
sleepchan[nsleep] = &s.c;
|
||||||
sleeptime[nsleep++] = p9nsec()/1000000+ms;
|
sleeptime[nsleep++] = p9nsec()/1000000+ms;
|
||||||
recvul(&s.c);
|
recvul(&s.c);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue